1/*******************************************************************************
2 *      Copyright (C) 2012 Google Inc.
3 *      Licensed to The Android Open Source Project.
4 *
5 *      Licensed under the Apache License, Version 2.0 (the "License");
6 *      you may not use this file except in compliance with the License.
7 *      You may obtain a copy of the License at
8 *
9 *           http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *      Unless required by applicable law or agreed to in writing, software
12 *      distributed under the License is distributed on an "AS IS" BASIS,
13 *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *      See the License for the specific language governing permissions and
15 *      limitations under the License.
16 *******************************************************************************/
17
18package com.android.mail.ui;
19
20import android.app.Dialog;
21import android.content.Intent;
22import android.content.res.Configuration;
23import android.os.Bundle;
24import android.support.annotation.LayoutRes;
25import android.view.KeyEvent;
26import android.view.Menu;
27import android.view.MenuItem;
28import android.view.MotionEvent;
29import android.view.View;
30
31import com.android.mail.browse.ConversationCursor.ConversationListener;
32import com.android.mail.browse.ConversationListFooterView;
33import com.android.mail.providers.Folder;
34import com.android.mail.ui.ViewMode.ModeChangeListener;
35
36/**
37 * An Activity controller knows how to combine views and listeners into a functioning activity.
38 * ActivityControllers are delegates that implement methods by calling underlying views to modify,
39 * or respond to user action.
40 *
41 * There are two ways of adding methods to this interface:
42 * <ul>
43 *     <li>When the methods pertain to a single logical grouping: consider adding a new
44 *     interface and putting all the methods in that interface. As an example,
45 *     look at {@link AccountController}. The controller implements this,
46 *     and returns itself in
47 *     {@link com.android.mail.ui.ControllableActivity#getAccountController()}. This allows
48 *     for account-specific methods to be added without creating new methods in this interface
49 *     .</li>
50 *     <li>Methods that relate to an activity can be added directly. As an example,
51 *     look at {@link #onActivityResult(int, int, android.content.Intent)} which is identical to
52 *     its declaration in {@link android.app.Activity}.</li>
53 *     <li>Everything else. As an example, look at {@link #isDrawerEnabled()}. Try to avoid
54 *     this path because an implementation has to provided in many classes:
55 *     {@link MailActivity}, {@link FolderSelectionActivity}, and the controllers.</li>
56 * </ul>
57 */
58public interface ActivityController extends LayoutListener,
59        ModeChangeListener, ConversationListCallbacks,
60        ConversationSetObserver, ConversationListener, FolderSelector,
61        UndoListener, ConversationUpdater, ErrorListener, FolderController, AccountController,
62        ConversationPositionTracker.Callbacks, ConversationListFooterView.FooterViewClickListener,
63        RecentFolderController, FragmentLauncher, KeyboardNavigationController {
64
65    // As far as possible, the methods here that correspond to Activity lifecycle have the same name
66    // as their counterpart in the Activity lifecycle.
67
68
69    /**
70     * @see android.app.Activity#onActivityResult
71     * @param requestCode
72     * @param resultCode
73     * @param data
74     */
75    void onActivityResult(int requestCode, int resultCode, Intent data);
76
77    /**
78     * Called by the Mail activity when the back button is pressed. Returning true consumes the
79     * event and disallows the calling method from trying to handle the back button any other way.
80     *
81     * @see android.app.Activity#onBackPressed()
82     * @return true if the back press was handled and the event was consumed. Return false if the
83     * event was not consumed.
84     */
85    boolean onBackPressed();
86
87    /**
88     * Called when the root activity calls onCreate. Any initialization needs to
89     * be done here. Subclasses need to call their parents' onCreate method, since it performs
90     * valuable initialization common to all subclasses.
91     *
92     * This was called initialize in Gmail.
93     *
94     * @see android.app.Activity#onCreate
95     * @param savedState
96     */
97    void onCreate(Bundle savedState);
98
99    /**
100     * @see android.app.Activity#onPostCreate
101     */
102    void onPostCreate(Bundle savedState);
103
104    /**
105     * @see android.app.Activity#onConfigurationChanged
106     */
107    void onConfigurationChanged(Configuration newConfig);
108
109    /**
110     * @see android.app.Activity#onStart
111     */
112    void onStart();
113
114    /**
115     * Called when the the root activity calls onRestart
116     * @see android.app.Activity#onRestart
117     */
118    void onRestart();
119
120    /**
121     * @see android.app.Activity#onCreateDialog(int, Bundle)
122     * @param id
123     * @param bundle
124     * @return
125     */
126    Dialog onCreateDialog(int id, Bundle bundle);
127
128    /**
129     * @see android.app.Activity#onCreateOptionsMenu(Menu)
130     * @param menu
131     * @return
132     */
133    boolean onCreateOptionsMenu(Menu menu);
134
135    /**
136     * @see android.app.Activity#onKeyDown(int, KeyEvent)
137     * @param keyCode
138     * @param event
139     * @return
140     */
141    boolean onKeyDown(int keyCode, KeyEvent event);
142
143    /**
144     * Called by Mail activity when menu items are selected
145     * @see android.app.Activity#onOptionsItemSelected(MenuItem)
146     * @param item
147     * @return
148     */
149    boolean onOptionsItemSelected(MenuItem item);
150
151    /**
152     * Called by the Mail activity on Activity pause.
153     * @see android.app.Activity#onPause
154     */
155    void onPause();
156
157    /**
158     * @see android.app.Activity#onDestroy
159     */
160    void onDestroy();
161
162    /**
163     * @see android.app.Activity#onPrepareDialog
164     * @param id
165     * @param dialog
166     * @param bundle
167     */
168    void onPrepareDialog(int id, Dialog dialog, Bundle bundle);
169
170    /**
171     * Called by the Mail activity when menu items need to be prepared.
172     * @see android.app.Activity#onPrepareOptionsMenu(Menu)
173     * @param menu
174     * @return
175     */
176    void onPrepareOptionsMenu(Menu menu);
177
178    /**
179     * Called by the Mail activity on Activity resume.
180     * @see android.app.Activity#onResume
181     */
182    void onResume();
183
184    /**
185     * @see android.app.Activity#onRestoreInstanceState
186     */
187    void onRestoreInstanceState(Bundle savedInstanceState);
188
189    /**
190     * @see android.app.Activity#onSaveInstanceState
191     * @param outState
192     */
193    void onSaveInstanceState(Bundle outState);
194
195    /**
196     * Begin a search with the given query string.
197     */
198    void executeSearch(String query);
199
200    /**
201     * Called by the Mail activity on Activity stop.
202     * @see android.app.Activity#onStop
203     */
204    void onStop();
205
206    /**
207     * Called by the Mail activity when window focus changes.
208     * @see android.app.Activity#onWindowFocusChanged(boolean)
209     * @param hasFocus
210     */
211    void onWindowFocusChanged(boolean hasFocus);
212
213    /**
214     * Handle a touch event.
215     */
216    void onTouchEvent(MotionEvent event);
217
218    /**
219     * Returns whether the first conversation in the conversation list should be
220     * automatically selected and shown.
221     */
222    boolean shouldShowFirstConversation();
223
224    /**
225     * Get the selected set of conversations. Guaranteed to return non-null, this should return
226     * an empty set if no conversation is currently selected.
227     * @return
228     */
229    public ConversationCheckedSet getCheckedSet();
230
231    /**
232     * Start search mode if the account being view supports the search capability.
233     */
234    void startSearch();
235
236    /**
237     * Return the folder currently being viewed by the activity.
238     */
239    public Folder getHierarchyFolder();
240
241    /**
242     * Handles the animation end of the animated adapter.
243     */
244    void onAnimationEnd(AnimatedAdapter animatedAdapter);
245
246    /**
247     * Called when Accessibility is enabled or disabled.
248     */
249    void onAccessibilityStateChanged();
250
251    /**
252     * Called to determine if the drawer is enabled for this controller/activity instance.
253     * Note: the value returned should not change for this controller instance.
254     */
255    boolean isDrawerEnabled();
256
257    /**
258     * Called to determine if menu items in the action bar should be hidden.
259     * Currently this is used for when the drawer is open to hide certain
260     * items that are not applicable while the drawer is open.
261     */
262    boolean shouldHideMenuItems();
263
264    DrawerController getDrawerController();
265
266    /**
267     * Called to determine the layout resource to use for the activity's content view.
268     * @return Resource ID
269     */
270    @LayoutRes int getContentViewResource();
271
272    View.OnClickListener getNavigationViewClickListener();
273
274    /**
275     * If the search bar should always be visible on top of the screen (e.g. search result list).
276     * @param viewMode the new view mode. This is passed as a parameter because we don't know
277     *   which onViewModeChanged callback gets called first, so the view modes might differ.
278     */
279    boolean shouldShowSearchBarByDefault(int viewMode);
280
281    /**
282     * If we should show the search menu item.
283     */
284    boolean shouldShowSearchMenuItem();
285
286    /**
287     * Attach layout listener so our custom toolbar can listen to thread list layout events.
288     */
289    void addConversationListLayoutListener(TwoPaneLayout.ConversationListLayoutListener listener);
290}
291