Home | History | Annotate | Download | only in setup
      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 {
     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