SetupDataFragment.java revision 06415a635f5f01d8e1620b29f44d68dc4dfdf435
1package com.android.email.activity.setup; 2 3import android.app.Fragment; 4import android.content.Context; 5import android.os.Bundle; 6import android.os.Parcel; 7import android.os.Parcelable; 8 9import com.android.email.service.EmailServiceUtils; 10import com.android.emailcommon.provider.Account; 11import com.android.emailcommon.provider.HostAuth; 12import com.android.emailcommon.provider.Policy; 13 14/** 15 * Headless fragment to hold setup data for the account setup or settings flows 16 */ 17public class SetupDataFragment extends Fragment implements Parcelable { 18 // The "extra" name for the Bundle saved with SetupData 19 public static final String EXTRA_SETUP_DATA = "com.android.email.setupdata"; 20 21 // NORMAL is the standard entry from the Email app; EAS and POP_IMAP are used when entering via 22 // Settings -> Accounts 23 public static final int FLOW_MODE_UNSPECIFIED = -1; 24 public static final int FLOW_MODE_NORMAL = 0; 25 public static final int FLOW_MODE_ACCOUNT_MANAGER = 1; 26 public static final int FLOW_MODE_EDIT = 3; 27 public static final int FLOW_MODE_FORCE_CREATE = 4; 28 // The following two modes are used to "pop the stack" and return from the setup flow. We 29 // either return to the caller (if we're in an account type flow) or go to the message list 30 // TODO: figure out if we still care about these 31 public static final int FLOW_MODE_RETURN_TO_CALLER = 5; 32 public static final int FLOW_MODE_RETURN_TO_MESSAGE_LIST = 6; 33 public static final int FLOW_MODE_RETURN_NO_ACCOUNTS_RESULT = 7; 34 public static final int FLOW_MODE_NO_ACCOUNTS = 8; 35 36 // Mode bits for AccountSetupCheckSettings, indicating the type of check requested 37 public static final int CHECK_INCOMING = 1; 38 public static final int CHECK_OUTGOING = 2; 39 public static final int CHECK_AUTODISCOVER = 4; 40 41 private static final String SAVESTATE_FLOWMODE = "SetupDataFragment.flowMode"; 42 private static final String SAVESTATE_ACCOUNT = "SetupDataFragment.account"; 43 private static final String SAVESTATE_EMAIL = "SetupDataFragment.email"; 44 private static final String SAVESTATE_CREDENTIAL = "SetupDataFragment.credential"; 45 private static final String SAVESTATE_INCOMING_LOADED = "SetupDataFragment.incomingLoaded"; 46 private static final String SAVESTATE_OUTGOING_LOADED = "SetupDataFragment.outgoingLoaded"; 47 private static final String SAVESTATE_POLICY = "SetupDataFragment.policy"; 48 private static final String SAVESTATE_INCOMING_PROTOCOL = "SetupDataFragment.incomingProtocol"; 49 private static final String SAVESTATE_AM_PROTOCOL = "SetupDataFragment.amProtocol"; 50 51 // All access will be through getters/setters 52 private int mFlowMode = FLOW_MODE_NORMAL; 53 private Account mAccount; 54 private String mEmail; 55 private Bundle mCredentialResults; 56 // These are used to track whether we've preloaded the login credentials into incoming/outgoing 57 // settings. Set them to 'true' by default, and false when we change the credentials or email 58 private boolean mIncomingCredLoaded = true; 59 private boolean mOutgoingCredLoaded = true; 60 // This is accessed off-thread in AccountCheckSettingsFragment 61 private volatile Policy mPolicy; 62 // Cache incoming protocol and service info here 63 private EmailServiceUtils.EmailServiceInfo mIncomingServiceInfo; 64 private String mIncomingProtocol; 65 // Protocol the user chose in the account manager "Add an account" screen 66 private String mAmProtocol; 67 68 public interface SetupDataContainer { 69 public SetupDataFragment getSetupData(); 70 } 71 72 public SetupDataFragment() { 73 mPolicy = null; 74 setAccount(new Account()); 75 mEmail = null; 76 mCredentialResults = null; 77 } 78 79 @Override 80 public void onSaveInstanceState(Bundle outState) { 81 super.onSaveInstanceState(outState); 82 outState.putInt(SAVESTATE_FLOWMODE, mFlowMode); 83 outState.putParcelable(SAVESTATE_ACCOUNT, mAccount); 84 outState.putString(SAVESTATE_EMAIL, mEmail); 85 outState.putParcelable(SAVESTATE_CREDENTIAL, mCredentialResults); 86 outState.putBoolean(SAVESTATE_INCOMING_LOADED, mIncomingCredLoaded); 87 outState.putBoolean(SAVESTATE_OUTGOING_LOADED, mOutgoingCredLoaded); 88 outState.putParcelable(SAVESTATE_POLICY, mPolicy); 89 outState.putString(SAVESTATE_INCOMING_PROTOCOL, mIncomingProtocol); 90 outState.putString(SAVESTATE_AM_PROTOCOL, mAmProtocol); 91 } 92 93 @Override 94 public void onCreate(Bundle savedInstanceState) { 95 super.onCreate(savedInstanceState); 96 if (savedInstanceState != null) { 97 mFlowMode = savedInstanceState.getInt(SAVESTATE_FLOWMODE); 98 setAccount((Account) savedInstanceState.getParcelable(SAVESTATE_ACCOUNT)); 99 mEmail = savedInstanceState.getString(SAVESTATE_EMAIL); 100 mCredentialResults = savedInstanceState.getParcelable(SAVESTATE_CREDENTIAL); 101 mIncomingCredLoaded = savedInstanceState.getBoolean(SAVESTATE_INCOMING_LOADED); 102 mOutgoingCredLoaded = savedInstanceState.getBoolean(SAVESTATE_OUTGOING_LOADED); 103 mPolicy = savedInstanceState.getParcelable(SAVESTATE_POLICY); 104 mIncomingProtocol = savedInstanceState.getString(SAVESTATE_INCOMING_PROTOCOL); 105 mAmProtocol = savedInstanceState.getString(SAVESTATE_AM_PROTOCOL); 106 } 107 setRetainInstance(true); 108 } 109 110 // Getters and setters 111 public int getFlowMode() { 112 return mFlowMode; 113 } 114 115 public void setFlowMode(int flowMode) { 116 mFlowMode = flowMode; 117 } 118 119 public Account getAccount() { 120 return mAccount; 121 } 122 123 public void setAccount(Account account) { 124 mAccount = account; 125 mAccount.setTemporary(true); 126 } 127 128 public String getEmail() { 129 return mEmail; 130 } 131 132 public void setEmail(String email) { 133 mEmail = email; 134 mAccount.mEmailAddress = email; 135 mIncomingCredLoaded = false; 136 mOutgoingCredLoaded = false; 137 } 138 139 public Bundle getCredentialResults() { 140 return mCredentialResults; 141 } 142 143 public void setCredentialResults(Bundle credentialResults) { 144 mCredentialResults = credentialResults; 145 mIncomingCredLoaded = false; 146 mOutgoingCredLoaded = false; 147 } 148 149 public boolean isIncomingCredLoaded() { 150 return mIncomingCredLoaded; 151 } 152 153 public void setIncomingCredLoaded(boolean incomingCredLoaded) { 154 mIncomingCredLoaded = incomingCredLoaded; 155 } 156 157 public boolean isOutgoingCredLoaded() { 158 return mOutgoingCredLoaded; 159 } 160 161 public void setOutgoingCredLoaded(boolean outgoingCredLoaded) { 162 mOutgoingCredLoaded = outgoingCredLoaded; 163 } 164 165 public synchronized Policy getPolicy() { 166 return mPolicy; 167 } 168 169 public synchronized void setPolicy(Policy policy) { 170 mPolicy = policy; 171 } 172 173 /** 174 * Retrieve the service info for the incoming protocol 175 * @param context For resolving the service info, and possibly loading the {@link HostAuth} 176 * @return service info object 177 */ 178 public EmailServiceUtils.EmailServiceInfo getIncomingServiceInfo(Context context) { 179 if (mIncomingServiceInfo == null) { 180 mIncomingServiceInfo = EmailServiceUtils.getServiceInfo(context, 181 getIncomingProtocol(context)); 182 } 183 return mIncomingServiceInfo; 184 } 185 186 /** 187 * Retrieve the protocol as previously set in setIncomingProtocol, but don't attempt to look at 188 * {@link #mAccount#hostAuthRecv } 189 * @return Protocol string 190 */ 191 public String getIncomingProtocol() { 192 return mIncomingProtocol; 193 } 194 195 /** 196 * Retrieve the protocol as previously set in setIncomingProtocol, or from 197 * {@link #mAccount#hostAuthRecv}. Try not to call this on the main thread if it's unlikely that 198 * the hostauth isn't already loaded. 199 * @param context context to possibly load the {@link HostAuth} from the provider 200 * @return Protocol string 201 */ 202 public String getIncomingProtocol(Context context) { 203 if (mIncomingProtocol != null) { 204 return mIncomingProtocol; 205 } 206 207 final HostAuth recvAuth = mAccount.getOrCreateHostAuthRecv(context); 208 return recvAuth.mProtocol; 209 } 210 211 public void setIncomingProtocol(final Context context, final String protocol) { 212 final HostAuth recvAuth = mAccount.getOrCreateHostAuthRecv(context); 213 recvAuth.setConnection(protocol, recvAuth.mAddress, recvAuth.mPort, recvAuth.mFlags); 214 mIncomingProtocol = protocol; 215 mIncomingServiceInfo = null; 216 } 217 218 public String getClientCert(Context context) { 219 final HostAuth recvAuth = mAccount.getOrCreateHostAuthRecv(context); 220 return recvAuth.mClientCertAlias; 221 } 222 223 public String getAmProtocol() { 224 return mAmProtocol; 225 } 226 227 public void setAmProtocol(String amProtocol) { 228 mAmProtocol = amProtocol; 229 } 230 231 // Parcelable methods 232 @Override 233 public int describeContents() { 234 return 0; 235 } 236 237 public static final Parcelable.Creator<SetupDataFragment> CREATOR = 238 new Parcelable.Creator<SetupDataFragment>() { 239 @Override 240 public SetupDataFragment createFromParcel(Parcel in) { 241 return new SetupDataFragment(in); 242 } 243 244 @Override 245 public SetupDataFragment[] newArray(int size) { 246 return new SetupDataFragment[size]; 247 } 248 }; 249 250 @Override 251 public void writeToParcel(Parcel dest, int flags) { 252 dest.writeInt(mFlowMode); 253 dest.writeParcelable(mAccount, 0); 254 dest.writeString(mEmail); 255 dest.writeParcelable(mCredentialResults, 0); 256 dest.writeBooleanArray(new boolean[] {mIncomingCredLoaded, mOutgoingCredLoaded}); 257 dest.writeParcelable(mPolicy, 0); 258 } 259 260 public SetupDataFragment(Parcel in) { 261 final ClassLoader loader = getClass().getClassLoader(); 262 mFlowMode = in.readInt(); 263 setAccount((Account) in.readParcelable(loader)); 264 mEmail = in.readString(); 265 mCredentialResults = in.readParcelable(loader); 266 final boolean[] credsLoaded = in.createBooleanArray(); 267 mIncomingCredLoaded = credsLoaded[0]; 268 mOutgoingCredLoaded = credsLoaded[1]; 269 mPolicy = in.readParcelable(loader); 270 } 271 272 @Override 273 public String toString() { 274 final StringBuilder sb = new StringBuilder("SetupData"); 275 sb.append(":acct="); 276 sb.append(mAccount == null ? "none" :mAccount.mId); 277 if (mEmail != null) { 278 sb.append(":user="); 279 sb.append(mEmail); 280 } 281 if (mCredentialResults != null) { 282 sb.append(":cred="); 283 sb.append(mCredentialResults.toString()); 284 } 285 sb.append(":policy="); 286 sb.append(mPolicy == null ? "none" : "exists"); 287 return sb.toString(); 288 } 289 290} 291