• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.email.activity.setup;
2 
3 import android.app.Fragment;
4 import android.content.Context;
5 import android.os.Bundle;
6 import android.os.Parcel;
7 import android.os.Parcelable;
8 
9 import com.android.email.service.EmailServiceUtils;
10 import com.android.emailcommon.provider.Account;
11 import com.android.emailcommon.provider.HostAuth;
12 import com.android.emailcommon.provider.Policy;
13 
14 /**
15  * Headless fragment to hold setup data for the account setup or settings flows
16  */
17 public 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 {
getSetupData()69         public SetupDataFragment getSetupData();
70     }
71 
SetupDataFragment()72     public SetupDataFragment() {
73         mPolicy = null;
74         setAccount(new Account());
75         mEmail = null;
76         mCredentialResults = null;
77     }
78 
79     @Override
onSaveInstanceState(Bundle outState)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
onCreate(Bundle savedInstanceState)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
getFlowMode()111     public int getFlowMode() {
112         return mFlowMode;
113     }
114 
setFlowMode(int flowMode)115     public void setFlowMode(int flowMode) {
116         mFlowMode = flowMode;
117     }
118 
getAccount()119     public Account getAccount() {
120         return mAccount;
121     }
122 
setAccount(Account account)123     public void setAccount(Account account) {
124         mAccount = account;
125         mAccount.setTemporary(true);
126     }
127 
getEmail()128     public String getEmail() {
129         return mEmail;
130     }
131 
setEmail(String email)132     public void setEmail(String email) {
133         mEmail = email;
134         mAccount.mEmailAddress = email;
135         mIncomingCredLoaded = false;
136         mOutgoingCredLoaded = false;
137     }
138 
getCredentialResults()139     public Bundle getCredentialResults() {
140         return mCredentialResults;
141     }
142 
setCredentialResults(Bundle credentialResults)143     public void setCredentialResults(Bundle credentialResults) {
144         mCredentialResults = credentialResults;
145         mIncomingCredLoaded = false;
146         mOutgoingCredLoaded = false;
147     }
148 
isIncomingCredLoaded()149     public boolean isIncomingCredLoaded() {
150         return mIncomingCredLoaded;
151     }
152 
setIncomingCredLoaded(boolean incomingCredLoaded)153     public void setIncomingCredLoaded(boolean incomingCredLoaded) {
154         mIncomingCredLoaded = incomingCredLoaded;
155     }
156 
isOutgoingCredLoaded()157     public boolean isOutgoingCredLoaded() {
158         return mOutgoingCredLoaded;
159     }
160 
setOutgoingCredLoaded(boolean outgoingCredLoaded)161     public void setOutgoingCredLoaded(boolean outgoingCredLoaded) {
162         mOutgoingCredLoaded = outgoingCredLoaded;
163     }
164 
getPolicy()165     public synchronized Policy getPolicy() {
166         return mPolicy;
167     }
168 
setPolicy(Policy policy)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      */
getIncomingServiceInfo(Context context)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      */
getIncomingProtocol()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      */
getIncomingProtocol(Context context)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 
setIncomingProtocol(final Context context, final String protocol)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 
getClientCert(Context context)218     public String getClientCert(Context context) {
219         final HostAuth recvAuth = mAccount.getOrCreateHostAuthRecv(context);
220         return recvAuth.mClientCertAlias;
221     }
222 
getAmProtocol()223     public String getAmProtocol() {
224         return mAmProtocol;
225     }
226 
setAmProtocol(String amProtocol)227     public void setAmProtocol(String amProtocol) {
228         mAmProtocol = amProtocol;
229     }
230 
231     // Parcelable methods
232     @Override
describeContents()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
writeToParcel(Parcel dest, int flags)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 
SetupDataFragment(Parcel in)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
toString()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