1/*
2 * Copyright (C) 2006 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.browser;
18
19import android.app.Activity;
20import android.app.KeyguardManager;
21import android.content.Context;
22import android.content.Intent;
23import android.content.res.Configuration;
24import android.os.Bundle;
25import android.os.PowerManager;
26import android.util.Log;
27import android.view.ActionMode;
28import android.view.ContextMenu;
29import android.view.ContextMenu.ContextMenuInfo;
30import android.view.KeyEvent;
31import android.view.Menu;
32import android.view.MenuItem;
33import android.view.MotionEvent;
34import android.view.View;
35import android.view.Window;
36
37import com.android.browser.stub.NullController;
38import com.google.common.annotations.VisibleForTesting;
39
40public class BrowserActivity extends Activity {
41
42    public static final String ACTION_SHOW_BOOKMARKS = "show_bookmarks";
43    public static final String ACTION_SHOW_BROWSER = "show_browser";
44    public static final String ACTION_RESTART = "--restart--";
45    private static final String EXTRA_STATE = "state";
46
47    private final static String LOGTAG = "browser";
48
49    private final static boolean LOGV_ENABLED = Browser.LOGV_ENABLED;
50
51    private ActivityController mController = NullController.INSTANCE;
52
53    @Override
54    public void onCreate(Bundle icicle) {
55        if (LOGV_ENABLED) {
56            Log.v(LOGTAG, this + " onStart, has state: "
57                    + (icicle == null ? "false" : "true"));
58        }
59        super.onCreate(icicle);
60
61        if (shouldIgnoreIntents()) {
62            finish();
63            return;
64        }
65
66        // If this was a web search request, pass it on to the default web
67        // search provider and finish this activity.
68        if (IntentHandler.handleWebSearchIntent(this, null, getIntent())) {
69            finish();
70            return;
71        }
72        mController = createController();
73
74        Intent intent = (icicle == null) ? getIntent() : null;
75        mController.start(intent);
76    }
77
78    public static boolean isTablet(Context context) {
79        return context.getResources().getBoolean(R.bool.isTablet);
80    }
81
82    private Controller createController() {
83        Controller controller = new Controller(this);
84        boolean xlarge = isTablet(this);
85        UI ui = null;
86        if (xlarge) {
87            ui = new XLargeUi(this, controller);
88        } else {
89            ui = new PhoneUi(this, controller);
90        }
91        controller.setUi(ui);
92        return controller;
93    }
94
95    @VisibleForTesting
96    Controller getController() {
97        return (Controller) mController;
98    }
99
100    @Override
101    protected void onNewIntent(Intent intent) {
102        if (shouldIgnoreIntents()) return;
103        if (ACTION_RESTART.equals(intent.getAction())) {
104            Bundle outState = new Bundle();
105            mController.onSaveInstanceState(outState);
106            finish();
107            getApplicationContext().startActivity(
108                    new Intent(getApplicationContext(), BrowserActivity.class)
109                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
110                    .putExtra(EXTRA_STATE, outState));
111            return;
112        }
113        mController.handleNewIntent(intent);
114    }
115
116    private KeyguardManager mKeyguardManager;
117    private PowerManager mPowerManager;
118    private boolean shouldIgnoreIntents() {
119        // Only process intents if the screen is on and the device is unlocked
120        // aka, if we will be user-visible
121        if (mKeyguardManager == null) {
122            mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
123        }
124        if (mPowerManager == null) {
125            mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
126        }
127        boolean ignore = !mPowerManager.isScreenOn();
128        ignore |= mKeyguardManager.inKeyguardRestrictedInputMode();
129        if (LOGV_ENABLED) {
130            Log.v(LOGTAG, "ignore intents: " + ignore);
131        }
132        return ignore;
133    }
134
135    @Override
136    protected void onResume() {
137        super.onResume();
138        if (LOGV_ENABLED) {
139            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
140        }
141        mController.onResume();
142    }
143
144    @Override
145    public boolean onMenuOpened(int featureId, Menu menu) {
146        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
147            mController.onMenuOpened(featureId, menu);
148        }
149        return true;
150    }
151
152    @Override
153    public void onOptionsMenuClosed(Menu menu) {
154        mController.onOptionsMenuClosed(menu);
155    }
156
157    @Override
158    public void onContextMenuClosed(Menu menu) {
159        super.onContextMenuClosed(menu);
160        mController.onContextMenuClosed(menu);
161    }
162
163    /**
164     *  onSaveInstanceState(Bundle map)
165     *  onSaveInstanceState is called right before onStop(). The map contains
166     *  the saved state.
167     */
168    @Override
169    protected void onSaveInstanceState(Bundle outState) {
170        if (LOGV_ENABLED) {
171            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
172        }
173        mController.onSaveInstanceState(outState);
174    }
175
176    @Override
177    protected void onPause() {
178        mController.onPause();
179        super.onPause();
180    }
181
182    @Override
183    protected void onDestroy() {
184        if (LOGV_ENABLED) {
185            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
186        }
187        super.onDestroy();
188        mController.onDestroy();
189        mController = NullController.INSTANCE;
190    }
191
192    @Override
193    public void onConfigurationChanged(Configuration newConfig) {
194        super.onConfigurationChanged(newConfig);
195        mController.onConfgurationChanged(newConfig);
196    }
197
198    @Override
199    public void onLowMemory() {
200        super.onLowMemory();
201        mController.onLowMemory();
202    }
203
204    @Override
205    public boolean onCreateOptionsMenu(Menu menu) {
206        super.onCreateOptionsMenu(menu);
207        return mController.onCreateOptionsMenu(menu);
208    }
209
210    @Override
211    public boolean onPrepareOptionsMenu(Menu menu) {
212        super.onPrepareOptionsMenu(menu);
213        return mController.onPrepareOptionsMenu(menu);
214    }
215
216    @Override
217    public boolean onOptionsItemSelected(MenuItem item) {
218        if (!mController.onOptionsItemSelected(item)) {
219            return super.onOptionsItemSelected(item);
220        }
221        return true;
222    }
223
224    @Override
225    public void onCreateContextMenu(ContextMenu menu, View v,
226            ContextMenuInfo menuInfo) {
227        mController.onCreateContextMenu(menu, v, menuInfo);
228    }
229
230    @Override
231    public boolean onContextItemSelected(MenuItem item) {
232        return mController.onContextItemSelected(item);
233    }
234
235    @Override
236    public boolean onKeyDown(int keyCode, KeyEvent event) {
237        return mController.onKeyDown(keyCode, event) ||
238            super.onKeyDown(keyCode, event);
239    }
240
241    @Override
242    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
243        return mController.onKeyLongPress(keyCode, event) ||
244            super.onKeyLongPress(keyCode, event);
245    }
246
247    @Override
248    public boolean onKeyUp(int keyCode, KeyEvent event) {
249        return mController.onKeyUp(keyCode, event) ||
250            super.onKeyUp(keyCode, event);
251    }
252
253    @Override
254    public void onActionModeStarted(ActionMode mode) {
255        super.onActionModeStarted(mode);
256        mController.onActionModeStarted(mode);
257    }
258
259    @Override
260    public void onActionModeFinished(ActionMode mode) {
261        super.onActionModeFinished(mode);
262        mController.onActionModeFinished(mode);
263    }
264
265    @Override
266    protected void onActivityResult(int requestCode, int resultCode,
267            Intent intent) {
268        mController.onActivityResult(requestCode, resultCode, intent);
269    }
270
271    @Override
272    public boolean onSearchRequested() {
273        return mController.onSearchRequested();
274    }
275
276    @Override
277    public boolean dispatchKeyEvent(KeyEvent event) {
278        return mController.dispatchKeyEvent(event)
279                || super.dispatchKeyEvent(event);
280    }
281
282    @Override
283    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
284        return mController.dispatchKeyShortcutEvent(event)
285                || super.dispatchKeyShortcutEvent(event);
286    }
287
288    @Override
289    public boolean dispatchTouchEvent(MotionEvent ev) {
290        return mController.dispatchTouchEvent(ev)
291                || super.dispatchTouchEvent(ev);
292    }
293
294    @Override
295    public boolean dispatchTrackballEvent(MotionEvent ev) {
296        return mController.dispatchTrackballEvent(ev)
297                || super.dispatchTrackballEvent(ev);
298    }
299
300    @Override
301    public boolean dispatchGenericMotionEvent(MotionEvent ev) {
302        return mController.dispatchGenericMotionEvent(ev) ||
303                super.dispatchGenericMotionEvent(ev);
304    }
305
306}
307