1 /* 2 * Copyright (C) 2014 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.email.activity.setup; 18 19 import android.app.AlertDialog; 20 import android.app.Dialog; 21 import android.app.DialogFragment; 22 import android.app.Fragment; 23 import android.content.Context; 24 import android.content.DialogInterface; 25 import android.content.Intent; 26 import android.os.Bundle; 27 28 import com.android.email.R; 29 import com.android.email.setup.AuthenticatorSetupIntentHelper; 30 import com.android.emailcommon.provider.Account; 31 import com.android.mail.utils.LogUtils; 32 33 public class AccountServerSettingsActivity extends AccountSetupActivity implements 34 SecurityRequiredDialogFragment.Callback, CheckSettingsErrorDialogFragment.Callback, 35 AccountCheckSettingsFragment.Callback, AccountServerBaseFragment.Callback, 36 CheckSettingsProgressDialogFragment.Callback { 37 38 /** 39 * {@link com.android.emailcommon.provider.Account} 40 */ 41 private static final String EXTRA_ACCOUNT = "account"; 42 /** 43 * Incoming or Outgoing settings? 44 */ 45 private static final String EXTRA_WHICH_SETTINGS = "whichSettings"; 46 private static final String INCOMING_SETTINGS = "incoming"; 47 private static final String OUTGOING_SETTINGS = "outgoing"; 48 49 private AccountServerBaseFragment mAccountServerFragment; 50 51 public static Intent getIntentForIncoming(final Context context, final Account account) { 52 final Intent intent = new Intent(context, AccountServerSettingsActivity.class); 53 intent.putExtra(EXTRA_ACCOUNT, account); 54 intent.putExtra(EXTRA_WHICH_SETTINGS, INCOMING_SETTINGS); 55 return intent; 56 } 57 58 public static Intent getIntentForOutgoing(final Context context, final Account account) { 59 final Intent intent = new Intent(context, AccountServerSettingsActivity.class); 60 intent.putExtra(EXTRA_ACCOUNT, account); 61 intent.putExtra(EXTRA_WHICH_SETTINGS, OUTGOING_SETTINGS); 62 return intent; 63 } 64 65 @Override 66 public void onCreate(Bundle savedInstanceState) { 67 super.onCreate(savedInstanceState); 68 69 mSetupData.setFlowMode(AuthenticatorSetupIntentHelper.FLOW_MODE_EDIT); 70 71 setContentView(R.layout.account_server_settings); 72 setFinishOnTouchOutside(false); 73 74 if (savedInstanceState == null) { 75 final Account account = getIntent().getParcelableExtra(EXTRA_ACCOUNT); 76 if (account == null) { 77 throw new IllegalArgumentException("No account present in intent"); 78 } 79 mSetupData.setAccount(account); 80 final String whichSettings = getIntent().getStringExtra(EXTRA_WHICH_SETTINGS); 81 final AccountServerBaseFragment f; 82 if (OUTGOING_SETTINGS.equals(whichSettings)) { 83 f = AccountSetupOutgoingFragment.newInstance(true); 84 } else { 85 f = AccountSetupIncomingFragment.newInstance(true); 86 } 87 getFragmentManager().beginTransaction() 88 .add(R.id.account_server_settings_container, f) 89 .commit(); 90 } 91 } 92 93 @Override 94 public void onAttachFragment(Fragment fragment) { 95 super.onAttachFragment(fragment); 96 if (fragment instanceof AccountServerBaseFragment) { 97 mAccountServerFragment = (AccountServerBaseFragment) fragment; 98 } 99 } 100 101 public AccountServerBaseFragment getAccountServerFragment() { 102 return mAccountServerFragment; 103 } 104 105 private void forceBack() { 106 super.onBackPressed(); 107 } 108 109 /** 110 * Any time we exit via this pathway we put up the exit-save-changes dialog. 111 */ 112 @Override 113 public void onBackPressed() { 114 final AccountServerBaseFragment accountServerFragment = getAccountServerFragment(); 115 if (accountServerFragment != null) { 116 if (accountServerFragment.haveSettingsChanged()) { 117 UnsavedChangesDialogFragment dialogFragment = 118 UnsavedChangesDialogFragment.newInstanceForBack(); 119 dialogFragment.show(getFragmentManager(), UnsavedChangesDialogFragment.TAG); 120 return; // Prevent "back" from being handled 121 } 122 } 123 super.onBackPressed(); 124 } 125 126 @Override 127 public void onNextButton() {} 128 129 /** 130 * Save process is done, dismiss the fragment. 131 */ 132 @Override 133 public void onAccountServerSaveComplete() { 134 super.onBackPressed(); 135 } 136 137 @Override 138 public void onAccountServerUIComplete(int checkMode) { 139 final Fragment checkerDialog = CheckSettingsProgressDialogFragment.newInstance(checkMode); 140 final Fragment checkerFragment = AccountCheckSettingsFragment.newInstance(checkMode); 141 getFragmentManager().beginTransaction() 142 .add(checkerDialog, CheckSettingsProgressDialogFragment.TAG) 143 .add(checkerFragment, AccountCheckSettingsFragment.TAG) 144 .commit(); 145 } 146 147 @Override 148 public void onCheckSettingsProgressDialogCancel() { 149 dismissCheckSettingsFragment(); 150 } 151 152 /** 153 * After verifying a new server configuration as OK, we return here and continue. This kicks 154 * off the save process. 155 */ 156 @Override 157 public void onCheckSettingsComplete() { 158 dismissCheckSettingsFragment(); 159 final AccountServerBaseFragment f = getAccountServerFragment(); 160 if (f != null) { 161 f.saveSettings(); 162 } 163 } 164 165 @Override 166 public void onCheckSettingsSecurityRequired(String hostName) { 167 dismissCheckSettingsFragment(); 168 SecurityRequiredDialogFragment.newInstance(hostName) 169 .show(getFragmentManager(), SecurityRequiredDialogFragment.TAG); 170 } 171 172 @Override 173 public void onCheckSettingsError(int reason, String message) { 174 dismissCheckSettingsFragment(); 175 CheckSettingsErrorDialogFragment.newInstance(reason, message) 176 .show(getFragmentManager(), CheckSettingsErrorDialogFragment.TAG); 177 } 178 179 @Override 180 public void onCheckSettingsAutoDiscoverComplete(int result) { 181 throw new IllegalStateException(); 182 } 183 184 private void dismissCheckSettingsFragment() { 185 final Fragment f = 186 getFragmentManager().findFragmentByTag(AccountCheckSettingsFragment.TAG); 187 final Fragment d = 188 getFragmentManager().findFragmentByTag(CheckSettingsProgressDialogFragment.TAG); 189 getFragmentManager().beginTransaction() 190 .remove(f) 191 .remove(d) 192 .commit(); 193 } 194 195 @Override 196 public void onSecurityRequiredDialogResult(boolean ok) { 197 if (ok) { 198 final AccountServerBaseFragment f = getAccountServerFragment(); 199 if (f != null) { 200 f.saveSettings(); 201 } 202 } 203 // else just stay here 204 } 205 206 @Override 207 public void onCheckSettingsErrorDialogEditSettings() { 208 // Just stay here 209 } 210 211 @Override 212 public void onCheckSettingsErrorDialogEditCertificate() { 213 final AccountServerBaseFragment f = getAccountServerFragment(); 214 if (f instanceof AccountSetupIncomingFragment) { 215 AccountSetupIncomingFragment asif = (AccountSetupIncomingFragment) f; 216 asif.onCertificateRequested(); 217 } else { 218 LogUtils.wtf(LogUtils.TAG, "Tried to change cert on non-incoming screen?"); 219 } 220 } 221 222 /** 223 * Dialog fragment to show "exit with unsaved changes?" dialog 224 */ 225 public static class UnsavedChangesDialogFragment extends DialogFragment { 226 final static String TAG = "UnsavedChangesDialogFragment"; 227 228 /** 229 * Creates a save changes dialog when the user navigates "back". 230 * {@link #onBackPressed()} defines in which case this may be triggered. 231 */ 232 public static UnsavedChangesDialogFragment newInstanceForBack() { 233 return new UnsavedChangesDialogFragment(); 234 } 235 236 // Force usage of newInstance() 237 public UnsavedChangesDialogFragment() {} 238 239 @Override 240 public Dialog onCreateDialog(Bundle savedInstanceState) { 241 final AccountServerSettingsActivity activity = 242 (AccountServerSettingsActivity) getActivity(); 243 244 return new AlertDialog.Builder(activity) 245 .setIconAttribute(android.R.attr.alertDialogIcon) 246 .setTitle(android.R.string.dialog_alert_title) 247 .setMessage(R.string.account_settings_exit_server_settings) 248 .setPositiveButton( 249 android.R.string.ok, 250 new DialogInterface.OnClickListener() { 251 @Override 252 public void onClick(DialogInterface dialog, int which) { 253 activity.forceBack(); 254 dismiss(); 255 } 256 }) 257 .setNegativeButton( 258 activity.getString(android.R.string.cancel), null) 259 .create(); 260 } 261 } 262 } 263