11a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler/* 21a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Copyright (C) 2010 The Android Open Source Project 31a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * 41a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Licensed under the Apache License, Version 2.0 (the "License"); 51a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * you may not use this file except in compliance with the License. 61a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * You may obtain a copy of the License at 71a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * 81a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * http://www.apache.org/licenses/LICENSE-2.0 91a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * 101a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Unless required by applicable law or agreed to in writing, software 111a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * distributed under the License is distributed on an "AS IS" BASIS, 121a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * See the License for the specific language governing permissions and 141a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * limitations under the License. 151a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 161a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 171a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerpackage com.android.email.activity.setup; 181a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 191a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.app.Activity; 201a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.app.Fragment; 211a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.content.Context; 228d22e85e459df3d94968389852859dacaf2baafeAndy Stadlerimport android.os.AsyncTask; 231a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.os.Bundle; 243432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komaloimport android.view.KeyEvent; 25112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadlerimport android.view.View; 26112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadlerimport android.view.View.OnClickListener; 27206109cf44e27e90e4a5208daa289704aa451198Todd Kennedyimport android.view.View.OnFocusChangeListener; 283432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komaloimport android.view.inputmethod.EditorInfo; 29206109cf44e27e90e4a5208daa289704aa451198Todd Kennedyimport android.view.inputmethod.InputMethodManager; 30112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadlerimport android.widget.Button; 31206109cf44e27e90e4a5208daa289704aa451198Todd Kennedyimport android.widget.TextView; 323432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komaloimport android.widget.TextView.OnEditorActionListener; 333432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo 343432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komaloimport com.android.email.R; 353432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komaloimport com.android.email.activity.UiUtilities; 363432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komaloimport com.android.emailcommon.provider.Account; 373432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komaloimport com.android.emailcommon.provider.HostAuth; 381a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 391a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler/** 401a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Common base class for server settings fragments, so they can be more easily manipulated by 411a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * AccountSettingsXL. Provides the following common functionality: 421a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * 431a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Activity-provided callbacks 441a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Activity callback during onAttach 451a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Present "Next" button and respond to its clicks 461a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 47fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadlerpublic abstract class AccountServerBaseFragment extends Fragment 48112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler implements AccountCheckSettingsFragment.Callbacks, OnClickListener { 49112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler 50ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo private static final String BUNDLE_KEY_SETTINGS = "AccountServerBaseFragment.settings"; 51ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo private static final String BUNDLE_KEY_ACTIVITY_TITLE = "AccountServerBaseFragment.title"; 521a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 5326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler protected Activity mContext; 541a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler protected Callback mCallback = EmptyCallback.INSTANCE; 55206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy /** 56206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy * Whether or not we are in "settings mode". We re-use the same screens for both the initial 57206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy * account creation as well as subsequent account modification. If <code>mSettingsMode</code> 58206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy * if <code>false</code>, we are in account creation mode. Otherwise, we are in account 59206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy * modification mode. 60206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy */ 61112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler protected boolean mSettingsMode; 62fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy /*package*/ HostAuth mLoadedSendAuth; 63fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy /*package*/ HostAuth mLoadedRecvAuth; 64c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy 6526cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler protected SetupData mSetupData; 6626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler 67112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler // This is null in the setup wizard screens, and non-null in AccountSettings mode 682fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki private Button mProceedButton; 698d22e85e459df3d94968389852859dacaf2baafeAndy Stadler // This is used to debounce multiple clicks on the proceed button (which does async work) 7064c7a437ac94bc0a1025804507b59d453caecd2bTodd Kennedy private boolean mProceedButtonPressed; 71040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy /*package*/ String mBaseScheme = "protocol"; 721a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 731a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler /** 741a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Callback interface that owning activities must provide 751a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 761a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler public interface Callback { 771a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler /** 781a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Called each time the user-entered input transitions between valid and invalid 791a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * @param enable true to enable proceed/next button, false to disable 801a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 811a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler public void onEnableProceedButtons(boolean enable); 82fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler 831a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler /** 84fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler * Called when user clicks "next". Starts account checker. 851a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * @param checkMode values from {@link SetupData} 86fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler * @param target the fragment that requested the check 871a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 88fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler public void onProceedNext(int checkMode, AccountServerBaseFragment target); 89fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler 90fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler /** 912731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler * Called when account checker completes. Fragments are responsible for saving 92fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler * own edited data; This is primarily for the activity to do post-check navigation. 932731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler * @param result check settings result code - success is CHECK_SETTINGS_OK 9426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler * @param setupData possibly modified SetupData 95fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler */ 9626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler public void onCheckSettingsComplete(int result, SetupData setupData); 971a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 981a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 991a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler private static class EmptyCallback implements Callback { 1001a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler public static final Callback INSTANCE = new EmptyCallback(); 1011a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler @Override public void onEnableProceedButtons(boolean enable) { } 102fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler @Override public void onProceedNext(int checkMode, AccountServerBaseFragment target) { } 10326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler @Override public void onCheckSettingsComplete(int result, SetupData setupData) { } 1041a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 1051a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 1061a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler /** 10726cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler * Creates and returns a bundle of arguments in the format we expect 10826cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler * 10926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler * @param settingsMode True if we're in settings, false if we're in account creation 11026cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler * @return Arg bundle 1111a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 11226cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler public static Bundle getArgs(Boolean settingsMode) { 11326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler final Bundle setupModeArgs = new Bundle(1); 11426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler setupModeArgs.putBoolean(BUNDLE_KEY_SETTINGS, settingsMode); 11526cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler return setupModeArgs; 1161a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 1171a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 11826cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler public AccountServerBaseFragment() {} 119c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy 1201a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler /** 121112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler * At onCreate time, read the fragment arguments 1221a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 1231a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler @Override 1241a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler public void onCreate(Bundle savedInstanceState) { 1251a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler super.onCreate(savedInstanceState); 1261a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 127112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler // Get arguments, which modally switch us into "settings" mode (different appearance) 128112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler mSettingsMode = false; 12926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler if (savedInstanceState != null) { 13026cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler mSettingsMode = savedInstanceState.getBoolean(BUNDLE_KEY_SETTINGS); 13126cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler } else if (getArguments() != null) { 132112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler mSettingsMode = getArguments().getBoolean(BUNDLE_KEY_SETTINGS); 133112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler } 134f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank setHasOptionsMenu(true); 1351a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 1361a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 137112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler /** 138112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler * Called from onCreateView, to do settings mode configuration 139112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler */ 140112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler protected void onCreateViewSettingsMode(View view) { 141112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler if (mSettingsMode) { 1422fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki UiUtilities.getView(view, R.id.cancel).setOnClickListener(this); 143219c3b5b8474bc0b95a9dcab21067ff603fccb15Tony Mantler mProceedButton = UiUtilities.getView(view, R.id.done); 144112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler mProceedButton.setOnClickListener(this); 145112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler mProceedButton.setEnabled(false); 146e6c6587b04a589eeb04006f75759c09ea10811e0Andy Stadler } 1471a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 1481a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 1491a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler @Override 150ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo public void onActivityCreated(Bundle savedInstanceState) { 151ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo // startPreferencePanel launches this fragment with the right title initially, but 152ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo // if the device is rotate we must set the title ourselves 15326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler mContext = getActivity(); 154ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo if (mSettingsMode && savedInstanceState != null) { 15526cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler mContext.setTitle(savedInstanceState.getString(BUNDLE_KEY_ACTIVITY_TITLE)); 156ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo } 15726cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler SetupData.SetupDataContainer container = (SetupData.SetupDataContainer) mContext; 15826cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler mSetupData = container.getSetupData(); 15926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler 160ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo super.onActivityCreated(savedInstanceState); 161ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo } 162ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo 163ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo @Override 164ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo public void onSaveInstanceState(Bundle outState) { 165ae594dc0ca4748a97ee8ae05c5f5c828121934e8Jorge Lugo outState.putString(BUNDLE_KEY_ACTIVITY_TITLE, (String) getActivity().getTitle()); 16626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler outState.putBoolean(BUNDLE_KEY_SETTINGS, mSettingsMode); 1671a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 1681a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 169206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy @Override 1706fc2585327025d4e1ef7a488a7a075284c71773dBen Komalo public void onDetach() { 1716fc2585327025d4e1ef7a488a7a075284c71773dBen Komalo super.onDetach(); 1726fc2585327025d4e1ef7a488a7a075284c71773dBen Komalo 1736fc2585327025d4e1ef7a488a7a075284c71773dBen Komalo // Ensure that we don't have any callbacks at this point. 1746fc2585327025d4e1ef7a488a7a075284c71773dBen Komalo mCallback = EmptyCallback.INSTANCE; 1756fc2585327025d4e1ef7a488a7a075284c71773dBen Komalo } 1766fc2585327025d4e1ef7a488a7a075284c71773dBen Komalo 1776fc2585327025d4e1ef7a488a7a075284c71773dBen Komalo @Override 178206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy public void onPause() { 179206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy // Hide the soft keyboard if we lose focus 18026cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler final InputMethodManager imm = 181206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy (InputMethodManager)mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 182206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy imm.hideSoftInputFromWindow(getView().getWindowToken(), 0); 183206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy super.onPause(); 184206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy } 185206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy 1861a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler /** 187112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler * Implements OnClickListener 1881a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 1891a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler @Override 190112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler public void onClick(View v) { 191112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler switch (v.getId()) { 192112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler case R.id.cancel: 193112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler getActivity().onBackPressed(); 194112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler break; 195112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler case R.id.done: 1968d22e85e459df3d94968389852859dacaf2baafeAndy Stadler // Simple debounce - just ignore while checks are underway 1978d22e85e459df3d94968389852859dacaf2baafeAndy Stadler if (mProceedButtonPressed) { 1988d22e85e459df3d94968389852859dacaf2baafeAndy Stadler return; 1998d22e85e459df3d94968389852859dacaf2baafeAndy Stadler } 2008d22e85e459df3d94968389852859dacaf2baafeAndy Stadler mProceedButtonPressed = true; 2011a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler onNext(); 202112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler break; 2031a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 2041a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 2051a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 2061a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler /** 2071a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Activity provides callbacks here. 2081a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 2091a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler public void setCallback(Callback callback) { 2101a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler mCallback = (callback == null) ? EmptyCallback.INSTANCE : callback; 2111a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler mContext = getActivity(); 2121a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 2131a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 2141a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler /** 2151a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Enable/disable the "next" button 2161a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 2171a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler public void enableNextButton(boolean enable) { 218112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler // If we are in settings "mode" we may be showing our own next button, and we'll 219112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler // enable it directly, here 220112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler if (mProceedButton != null) { 221112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler mProceedButton.setEnabled(enable); 2221a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 22364c7a437ac94bc0a1025804507b59d453caecd2bTodd Kennedy clearButtonBounce(); 2241a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 225112ed496f817ebeab6b1ee1d5117259ef80342b2Andy Stadler // TODO: This supports the phone UX activities and will be removed 2261a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler mCallback.onEnableProceedButtons(enable); 2271a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler } 2281a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 2291a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler /** 230206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy * Make the given text view uneditable. If the text view is ever focused, the specified 231206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy * error message will be displayed. 232206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy */ 233206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy protected void makeTextViewUneditable(final TextView view, final String errorMessage) { 234206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy // We're editing an existing account; don't allow modification of the user name 235206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy if (mSettingsMode) { 236206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy view.setKeyListener(null); 237206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy view.setFocusable(true); 238206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy view.setOnFocusChangeListener(new OnFocusChangeListener() { 239206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy @Override 240206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy public void onFocusChange(View v, boolean hasFocus) { 241206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy if (hasFocus) { 242206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy // Framework will not auto-hide IME; do it ourselves 243206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy InputMethodManager imm = (InputMethodManager)mContext. 244206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy getSystemService(Context.INPUT_METHOD_SERVICE); 245206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy imm.hideSoftInputFromWindow(getView().getWindowToken(), 0); 246206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy view.setError(errorMessage); 247206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy } else { 248206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy view.setError(null); 249206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy } 250206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy } 251206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy }); 252206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy view.setOnClickListener(new OnClickListener() { 253206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy @Override 254206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy public void onClick(View v) { 255206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy if (view.getError() == null) { 256206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy view.setError(errorMessage); 257206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy } else { 258206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy view.setError(null); 259206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy } 260206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy } 261206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy }); 262206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy } 263206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy } 264206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy 265206109cf44e27e90e4a5208daa289704aa451198Todd Kennedy /** 2663432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo * A keyboard listener which dismisses the keyboard when "DONE" is pressed, but doesn't muck 2673432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo * around with focus. This is useful in settings screens, as we don't want focus to change 2683432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo * since some fields throw up errors when they're focused to give the user more info. 2693432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo */ 2703432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo protected final OnEditorActionListener mDismissImeOnDoneListener = 2713432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo new OnEditorActionListener() { 2723432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo @Override 2733432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 2743432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo if (actionId == EditorInfo.IME_ACTION_DONE) { 2753432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo // Dismiss soft keyboard but don't modify focus. 2763432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo final Context context = getActivity(); 2773432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo if (context == null) { 2783432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo return false; 2793432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo } 28026cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler final InputMethodManager imm = (InputMethodManager) context.getSystemService( 2813432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo Context.INPUT_METHOD_SERVICE); 2823432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo if (imm != null && imm.isActive()) { 2833432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo imm.hideSoftInputFromWindow(getView().getWindowToken(), 0); 2843432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo } 2853432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo return true; 2863432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo } 2873432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo return false; 2883432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo } 2893432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo }; 2903432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo 2913432bdb757c4195fb4726c8b401f2261e78d75a7Ben Komalo /** 29264c7a437ac94bc0a1025804507b59d453caecd2bTodd Kennedy * Clears the "next" button de-bounce flags and allows the "next" button to activate. 29364c7a437ac94bc0a1025804507b59d453caecd2bTodd Kennedy */ 294463584d23f747cfbbd9856b39390269342363b41Tony Mantler protected void clearButtonBounce() { 29564c7a437ac94bc0a1025804507b59d453caecd2bTodd Kennedy mProceedButtonPressed = false; 29664c7a437ac94bc0a1025804507b59d453caecd2bTodd Kennedy } 29764c7a437ac94bc0a1025804507b59d453caecd2bTodd Kennedy 2988d22e85e459df3d94968389852859dacaf2baafeAndy Stadler /** 299fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler * Implements AccountCheckSettingsFragment.Callbacks 300fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler * 3016e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler * Handle OK or error result from check settings. Save settings (async), and then 3026e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler * exit to previous fragment. 30355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler */ 304fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler @Override 30526cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler public void onCheckSettingsComplete(final int settingsResult, SetupData setupData) { 30626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler mSetupData = setupData; 3076e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler new AsyncTask<Void, Void, Void>() { 3086e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler @Override 3096e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler protected Void doInBackground(Void... params) { 3106e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler if (settingsResult == AccountCheckSettingsFragment.CHECK_SETTINGS_OK) { 31126cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler if (mSetupData.getFlowMode() == SetupData.FLOW_MODE_EDIT) { 3126e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler saveSettingsAfterEdit(); 3136e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler } else { 3146e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler saveSettingsAfterSetup(); 3156e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler } 3166e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler } 3176e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler return null; 3182731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler } 3196e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler 3206e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler @Override 3216e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler protected void onPostExecute(Void result) { 3226e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler // Signal to owning activity that a settings check completed 32326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler mCallback.onCheckSettingsComplete(settingsResult, mSetupData); 3246e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler } 325bc2eaadde987044027b57d241e635de014bdb8baMakoto Onuki }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 3262731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler } 3272731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler 3282731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler /** 3292731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler * Implements AccountCheckSettingsFragment.Callbacks 3302731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler * This is overridden only by AccountSetupExchange 3312731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler */ 3322731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler @Override 33326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler public void onAutoDiscoverComplete(int result, SetupData setupData) { 3342731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler throw new IllegalStateException(); 33555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler } 33655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler 33755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler /** 338c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy * Returns whether or not any settings have changed. 339c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy */ 340c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy public boolean haveSettingsChanged() { 34126cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler final Account account = mSetupData.getAccount(); 342c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy 34326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler final HostAuth sendAuth = account.getOrCreateHostAuthSend(mContext); 34426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler final boolean sendChanged = (mLoadedSendAuth != null && !mLoadedSendAuth.equals(sendAuth)); 345fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy 34626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler final HostAuth recvAuth = account.getOrCreateHostAuthRecv(mContext); 34726cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler final boolean recvChanged = (mLoadedRecvAuth != null && !mLoadedRecvAuth.equals(recvAuth)); 348c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy 349fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy return sendChanged || recvChanged; 350c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy } 351c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy 352c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy /** 3531a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Save settings after "OK" result from checker. Concrete classes must implement. 3546e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler * This is called from a worker thread and is allowed to perform DB operations. 3551a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 3561a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler public abstract void saveSettingsAfterEdit(); 3571a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler 3581a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler /** 359fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler * Save settings after "OK" result from checker. Concrete classes must implement. 3606e71978ec38add2edf3ac5f3dd1f9abeea9c1ab6Andy Stadler * This is called from a worker thread and is allowed to perform DB operations. 361fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler */ 362fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler public abstract void saveSettingsAfterSetup(); 363fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler 364fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler /** 3651a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler * Respond to a click of the "Next" button. Concrete classes must implement. 3661a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler */ 3671a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler public abstract void onNext(); 3681a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler} 369