AccountServerBaseFragment.java revision 112ed496f817ebeab6b1ee1d5117259ef80342b2
1/*
2 * Copyright (C) 2010 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
17package com.android.email.activity.setup;
18
19import com.android.email.R;
20import com.android.email.provider.EmailContent.HostAuth;
21
22import android.app.Activity;
23import android.app.Fragment;
24import android.content.Context;
25import android.os.Bundle;
26import android.view.View;
27import android.view.View.OnClickListener;
28import android.widget.Button;
29
30/**
31 * Common base class for server settings fragments, so they can be more easily manipulated by
32 * AccountSettingsXL.  Provides the following common functionality:
33 *
34 * Activity-provided callbacks
35 * Activity callback during onAttach
36 * Present "Next" button and respond to its clicks
37 */
38public abstract class AccountServerBaseFragment extends Fragment
39        implements AccountCheckSettingsFragment.Callbacks, OnClickListener {
40
41    private final static String BUNDLE_KEY_SETTINGS = "AccountServerBaseFragment.settings";
42
43    protected Context mContext;
44    protected Callback mCallback = EmptyCallback.INSTANCE;
45    protected boolean mSettingsMode;
46    // This is null in the setup wizard screens, and non-null in AccountSettings mode
47    public Button mProceedButton;
48
49    /**
50     * Callback interface that owning activities must provide
51     */
52    public interface Callback {
53        /**
54         * Called each time the user-entered input transitions between valid and invalid
55         * @param enable true to enable proceed/next button, false to disable
56         */
57        public void onEnableProceedButtons(boolean enable);
58
59        /**
60         * Called when user clicks "next".  Starts account checker.
61         * @param checkMode values from {@link SetupData}
62         * @param target the fragment that requested the check
63         */
64        public void onProceedNext(int checkMode, AccountServerBaseFragment target);
65
66        /**
67         * Called when account checker completes.  Fragments are responsible for saving
68         * own edited data;  This is primarily for the activity to do post-check navigation.
69         * @param result check settings result code - success is CHECK_SETTINGS_OK
70         * @param setupMode signals if we were editing or creating
71         */
72        public void onCheckSettingsComplete(int result, int setupMode);
73    }
74
75    private static class EmptyCallback implements Callback {
76        public static final Callback INSTANCE = new EmptyCallback();
77        @Override public void onEnableProceedButtons(boolean enable) { }
78        @Override public void onProceedNext(int checkMode, AccountServerBaseFragment target) { }
79        @Override public void onCheckSettingsComplete(int result, int setupMode) { }
80    }
81
82    /**
83     * At constructor time, set the fragment arguments
84     */
85    protected void setSetupArguments(boolean settingsMode) {
86        Bundle b = new Bundle();
87        b.putBoolean(BUNDLE_KEY_SETTINGS, true);
88        setArguments(b);
89    }
90
91    /**
92     * At onCreate time, read the fragment arguments
93     */
94    @Override
95    public void onCreate(Bundle savedInstanceState) {
96        super.onCreate(savedInstanceState);
97
98        // Get arguments, which modally switch us into "settings" mode (different appearance)
99        mSettingsMode = false;
100        if (getArguments() != null) {
101            mSettingsMode = getArguments().getBoolean(BUNDLE_KEY_SETTINGS);
102        }
103    }
104
105    /**
106     * Called from onCreateView, to do settings mode configuration
107     */
108    protected void onCreateViewSettingsMode(View view) {
109        if (mSettingsMode) {
110            view.findViewById(R.id.cancel).setOnClickListener(this);
111            mProceedButton = (Button) view.findViewById(R.id.done);
112            mProceedButton.setOnClickListener(this);
113            mProceedButton.setEnabled(false);
114        }
115    }
116
117    /**
118     * Called when a fragment is first attached to its activity.
119     * {@link #onCreate(Bundle)} will be called after this.
120     */
121    @Override
122    public void onAttach(Activity activity) {
123        super.onAttach(activity);
124        mContext = activity;
125
126        // Notify the activity that we're here.
127        if (activity instanceof AccountSettingsXL) {
128            ((AccountSettingsXL)activity).onAttach(this);
129        }
130    }
131
132    /**
133     * Implements OnClickListener
134     */
135    @Override
136    public void onClick(View v) {
137        switch (v.getId()) {
138            case R.id.cancel:
139                getActivity().onBackPressed();
140                break;
141            case R.id.done:
142                onNext();
143                break;
144        }
145    }
146
147    /**
148     * Activity provides callbacks here.
149     */
150    public void setCallback(Callback callback) {
151        mCallback = (callback == null) ? EmptyCallback.INSTANCE : callback;
152        mContext = getActivity();
153    }
154
155    /**
156     * Enable/disable the "next" button
157     */
158    public void enableNextButton(boolean enable) {
159        // If we are in settings "mode" we may be showing our own next button, and we'll
160        // enable it directly, here
161        if (mProceedButton != null) {
162            mProceedButton.setEnabled(enable);
163        }
164
165        // TODO: This supports the phone UX activities and will be removed
166        mCallback.onEnableProceedButtons(enable);
167    }
168
169    /**
170     * Implements AccountCheckSettingsFragment.Callbacks
171     *
172     * Handle OK or error result from check settings.  Save settings, and exit to previous fragment.
173     */
174    @Override
175    public void onCheckSettingsComplete(int result) {
176        if (result == AccountCheckSettingsFragment.CHECK_SETTINGS_OK) {
177            if (SetupData.getFlowMode() == SetupData.FLOW_MODE_EDIT) {
178                saveSettingsAfterEdit();
179            } else {
180                saveSettingsAfterSetup();
181            }
182        }
183        // Signal to owning activity that a settings check completed
184        mCallback.onCheckSettingsComplete(result, SetupData.getFlowMode());
185    }
186
187    /**
188     * Implements AccountCheckSettingsFragment.Callbacks
189     * This is overridden only by AccountSetupExchange
190     */
191    @Override
192    public void onAutoDiscoverComplete(int result, HostAuth hostAuth) {
193        throw new IllegalStateException();
194    }
195
196    /**
197     * Save settings after "OK" result from checker.  Concrete classes must implement.
198     */
199    public abstract void saveSettingsAfterEdit();
200
201    /**
202     * Save settings after "OK" result from checker.  Concrete classes must implement.
203     */
204    public abstract void saveSettingsAfterSetup();
205
206    /**
207     * Respond to a click of the "Next" button.  Concrete classes must implement.
208     */
209    public abstract void onNext();
210}
211