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