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