blob: 85695504d757024faac93d73e6dc34d338457165 [file] [log] [blame]
The Android Open Source Project0c908882009-03-03 19:32:16 -08001/*
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
Bijan Amirzada41242f22014-03-21 12:12:18 -070017package com.android.browser;
The Android Open Source Project0c908882009-03-03 19:32:16 -080018
The Android Open Source Project0c908882009-03-03 19:32:16 -080019import android.app.Activity;
John Reck7878f222012-04-18 16:23:14 -070020import android.app.KeyguardManager;
John Reck9d27ff52011-02-11 17:47:54 -080021import android.content.Context;
The Android Open Source Project0c908882009-03-03 19:32:16 -080022import android.content.Intent;
The Android Open Source Project0c908882009-03-03 19:32:16 -080023import android.content.res.Configuration;
The Android Open Source Project0c908882009-03-03 19:32:16 -080024import android.os.Bundle;
qqzhou8c5b0a32013-07-22 15:31:03 +080025import android.os.Handler;
John Reck7878f222012-04-18 16:23:14 -070026import android.os.PowerManager;
The Android Open Source Project0c908882009-03-03 19:32:16 -080027import android.util.Log;
Leon Scroggins III8e4fbf12010-08-17 16:58:15 -040028import android.view.ActionMode;
The Android Open Source Project0c908882009-03-03 19:32:16 -080029import android.view.ContextMenu;
Michael Kolba2b2ba82010-08-04 17:54:03 -070030import android.view.ContextMenu.ContextMenuInfo;
The Android Open Source Project0c908882009-03-03 19:32:16 -080031import android.view.KeyEvent;
The Android Open Source Project0c908882009-03-03 19:32:16 -080032import android.view.Menu;
The Android Open Source Project0c908882009-03-03 19:32:16 -080033import android.view.MenuItem;
Michael Kolbc3af0672011-08-09 10:24:41 -070034import android.view.MotionEvent;
The Android Open Source Project0c908882009-03-03 19:32:16 -080035import android.view.View;
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -070036import android.view.ViewGroup;
37import android.view.ViewTreeObserver;
The Android Open Source Project0c908882009-03-03 19:32:16 -080038import android.view.Window;
The Android Open Source Project0c908882009-03-03 19:32:16 -080039
John Reckd3e4d5b2011-07-13 15:48:43 -070040import com.google.common.annotations.VisibleForTesting;
Bijan Amirzada41242f22014-03-21 12:12:18 -070041import com.android.browser.R;
Bijan Amirzada41242f22014-03-21 12:12:18 -070042import com.android.browser.search.DefaultSearchEngine;
43import com.android.browser.search.SearchEngine;
44import com.android.browser.stub.NullController;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080045
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080046import org.codeaurora.swe.WebView;
John Reckd3e4d5b2011-07-13 15:48:43 -070047
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -070048public class BrowserActivity extends Activity implements ViewTreeObserver.OnPreDrawListener {
The Android Open Source Project0c908882009-03-03 19:32:16 -080049
John Reck439c9a52010-12-14 10:04:39 -080050 public static final String ACTION_SHOW_BOOKMARKS = "show_bookmarks";
51 public static final String ACTION_SHOW_BROWSER = "show_browser";
John Reck63bb6872010-12-01 19:29:32 -080052 public static final String ACTION_RESTART = "--restart--";
53 private static final String EXTRA_STATE = "state";
John Reck38b39652012-06-05 09:22:59 -070054 public static final String EXTRA_DISABLE_URL_OVERRIDE = "disable_url_override";
John Reck63bb6872010-12-01 19:29:32 -080055
Michael Kolb8233fac2010-10-26 16:08:53 -070056 private final static String LOGTAG = "browser";
The Android Open Source Project0c908882009-03-03 19:32:16 -080057
John Reck6c2e2f32011-08-22 13:41:23 -070058 private final static boolean LOGV_ENABLED = Browser.LOGV_ENABLED;
Dave Bort31a6d1c2009-04-13 15:56:49 -070059
John Reck9c35b9c2012-05-30 10:08:50 -070060 private ActivityController mController = NullController.INSTANCE;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080061
qqzhou8c5b0a32013-07-22 15:31:03 +080062 private Handler mHandler = new Handler();
Jeff Davidson43610292010-07-16 16:03:58 -070063
kaiyizbb2db872013-08-01 22:24:07 -040064 private UiController mUiController;
65 private Handler mHandlerEx = new Handler();
66 private Runnable runnable = new Runnable() {
67 @Override
68 public void run() {
69 if (mUiController != null) {
70 WebView current = mUiController.getCurrentWebView();
71 if (current != null) {
72 current.postInvalidate();
73 }
74 }
75 }
76 };
77
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -070078 private Bundle mSavedInstanceState;
79 private EngineInitializer mEngineInitializer;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080080
Grace Kloba22ac16e2009-10-07 18:00:23 -070081 @Override
82 public void onCreate(Bundle icicle) {
Dave Bort31a6d1c2009-04-13 15:56:49 -070083 if (LOGV_ENABLED) {
John Reck6c2e2f32011-08-22 13:41:23 -070084 Log.v(LOGTAG, this + " onStart, has state: "
85 + (icicle == null ? "false" : "true"));
The Android Open Source Project0c908882009-03-03 19:32:16 -080086 }
87 super.onCreate(icicle);
Derek Sollenbergerffa561e2010-11-16 14:19:01 -050088
John Reck7878f222012-04-18 16:23:14 -070089 if (shouldIgnoreIntents()) {
90 finish();
91 return;
92 }
93
John Reckf57c0292011-07-21 18:15:39 -070094 // If this was a web search request, pass it on to the default web
95 // search provider and finish this activity.
Bijan Amirzada41242f22014-03-21 12:12:18 -070096 /*
kaiyiza2368f12013-09-02 10:43:31 +080097 SearchEngine searchEngine = BrowserSettings.getInstance().getSearchEngine();
98 boolean result = IntentHandler.handleWebSearchIntent(this, null, getIntent());
99 if (result && (searchEngine instanceof DefaultSearchEngine)) {
John Reckf57c0292011-07-21 18:15:39 -0700100 finish();
101 return;
102 }
Bijan Amirzada41242f22014-03-21 12:12:18 -0700103 */
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700104
105 mEngineInitializer = EngineInitializer.getInstance();
106 mEngineInitializer.onActivityCreate(BrowserActivity.this);
107
108 Thread.setDefaultUncaughtExceptionHandler(new CrashLogExceptionHandler(this));
109
110 mSavedInstanceState = icicle;
111 // Create the initial UI views
John Reck9c35b9c2012-05-30 10:08:50 -0700112 mController = createController();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800113
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700114 // Workaround for the black screen flicker on SurfaceView creation
115 ViewGroup topLayout = (ViewGroup) findViewById(R.id.main_content);
116 topLayout.requestTransparentRegion(topLayout);
117
118 // Add pre-draw listener to start the controller after engine initialization.
119 final ViewTreeObserver observer = getWindow().getDecorView().getViewTreeObserver();
120 observer.addOnPreDrawListener(this);
121
122 mEngineInitializer.initializeResourceExtractor(this);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800123 }
124
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700125 @Override
126 public boolean onPreDraw()
127 {
128 final ViewTreeObserver observer = getWindow().getDecorView().getViewTreeObserver();
129 observer.removeOnPreDrawListener(this);
130 mEngineInitializer.onPreDraw();
131 return true;
132 }
133
134
John Recka5176f32011-05-17 12:35:37 -0700135 public static boolean isTablet(Context context) {
136 return context.getResources().getBoolean(R.bool.isTablet);
John Reck9d27ff52011-02-11 17:47:54 -0800137 }
138
John Reck9c35b9c2012-05-30 10:08:50 -0700139 private Controller createController() {
140 Controller controller = new Controller(this);
141 boolean xlarge = isTablet(this);
142 UI ui = null;
143 if (xlarge) {
kaiyizbb2db872013-08-01 22:24:07 -0400144 XLargeUi tablet = new XLargeUi(this, controller);
145 ui = tablet;
146 mUiController = tablet.getUiController();
John Reck9c35b9c2012-05-30 10:08:50 -0700147 } else {
kaiyizbb2db872013-08-01 22:24:07 -0400148 PhoneUi phone = new PhoneUi(this, controller);
149 ui = phone;
150 mUiController = phone.getUiController();
John Reck9c35b9c2012-05-30 10:08:50 -0700151 }
152 controller.setUi(ui);
153 return controller;
154 }
155
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700156 public void onEngineInitializationComplete() {
157 Intent intent = (mSavedInstanceState == null) ? getIntent() : null;
158 mController.start(intent);
159 }
160
John Reck41554852010-12-01 12:53:37 -0800161 @VisibleForTesting
Tarun Nainani436b8732014-06-10 13:58:41 -0700162 //public to facilitate testing
163 public Controller getController() {
John Reck9c35b9c2012-05-30 10:08:50 -0700164 return (Controller) mController;
Michael Kolba2b2ba82010-08-04 17:54:03 -0700165 }
166
The Android Open Source Project0c908882009-03-03 19:32:16 -0800167 @Override
168 protected void onNewIntent(Intent intent) {
John Reck7878f222012-04-18 16:23:14 -0700169 if (shouldIgnoreIntents()) return;
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700170 mEngineInitializer.onNewIntent(intent);
171 // Note: Do not add any more application logic in this method.
172 // Move any additional app logic into handleOnNewIntent().
173 }
174
175 protected void handleOnNewIntent(Intent intent) {
John Reck63bb6872010-12-01 19:29:32 -0800176 if (ACTION_RESTART.equals(intent.getAction())) {
177 Bundle outState = new Bundle();
John Reck1cf4b792011-07-26 10:22:22 -0700178 mController.onSaveInstanceState(outState);
John Reck63bb6872010-12-01 19:29:32 -0800179 finish();
180 getApplicationContext().startActivity(
181 new Intent(getApplicationContext(), BrowserActivity.class)
182 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
183 .putExtra(EXTRA_STATE, outState));
184 return;
185 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700186 mController.handleNewIntent(intent);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800187 }
188
John Reck7878f222012-04-18 16:23:14 -0700189 private KeyguardManager mKeyguardManager;
190 private PowerManager mPowerManager;
191 private boolean shouldIgnoreIntents() {
192 // Only process intents if the screen is on and the device is unlocked
193 // aka, if we will be user-visible
194 if (mKeyguardManager == null) {
195 mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
196 }
197 if (mPowerManager == null) {
198 mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
199 }
200 boolean ignore = !mPowerManager.isScreenOn();
201 ignore |= mKeyguardManager.inKeyguardRestrictedInputMode();
202 if (LOGV_ENABLED) {
203 Log.v(LOGTAG, "ignore intents: " + ignore);
204 }
205 return ignore;
206 }
207
Grace Kloba22ac16e2009-10-07 18:00:23 -0700208 @Override
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700209 protected void onStart() {
210 super.onStart();
211 mEngineInitializer.onActivityStart();
212 }
213
214 @Override
Grace Kloba22ac16e2009-10-07 18:00:23 -0700215 protected void onResume() {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800216 super.onResume();
Dave Bort31a6d1c2009-04-13 15:56:49 -0700217 if (LOGV_ENABLED) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800218 Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
219 }
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700220 mEngineInitializer.onActivityResume();
221 // Note: Do not add any more application logic in this method.
222 // Move any additional app logic into handleOnResume().
223 }
Tarun Nainanief749cb2014-05-19 18:16:53 -0700224
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700225 protected void handleOnResume() {
226 mController.onResume();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800227 }
228
Leon Scrogginsa81a7642009-08-31 17:05:41 -0400229 @Override
230 public boolean onMenuOpened(int featureId, Menu menu) {
Leon Scroggins3bbb6ca2009-09-09 12:51:10 -0400231 if (Window.FEATURE_OPTIONS_PANEL == featureId) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700232 mController.onMenuOpened(featureId, menu);
Leon Scroggins3bbb6ca2009-09-09 12:51:10 -0400233 }
Leon Scrogginsa81a7642009-08-31 17:05:41 -0400234 return true;
235 }
236
Leon Scroggins3bbb6ca2009-09-09 12:51:10 -0400237 @Override
238 public void onOptionsMenuClosed(Menu menu) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700239 mController.onOptionsMenuClosed(menu);
Leon Scrogginsc6fa1102009-09-21 10:40:01 -0400240 }
241
Leon Scrogginsb2b19f52009-10-09 16:10:00 -0400242 @Override
243 public void onContextMenuClosed(Menu menu) {
244 super.onContextMenuClosed(menu);
Michael Kolb8233fac2010-10-26 16:08:53 -0700245 mController.onContextMenuClosed(menu);
Leon Scrogginsb2b19f52009-10-09 16:10:00 -0400246 }
247
Leon Scrogginsc6fa1102009-09-21 10:40:01 -0400248 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800249 * onSaveInstanceState(Bundle map)
250 * onSaveInstanceState is called right before onStop(). The map contains
251 * the saved state.
252 */
Grace Kloba22ac16e2009-10-07 18:00:23 -0700253 @Override
254 protected void onSaveInstanceState(Bundle outState) {
Dave Bort31a6d1c2009-04-13 15:56:49 -0700255 if (LOGV_ENABLED) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800256 Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
257 }
John Reck9c35b9c2012-05-30 10:08:50 -0700258 mController.onSaveInstanceState(outState);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800259 }
260
Grace Kloba22ac16e2009-10-07 18:00:23 -0700261 @Override
262 protected void onPause() {
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700263 mEngineInitializer.onActivityPause();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800264 super.onPause();
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700265 // Note: Do not add any more application logic in this method.
266 // Move any additional app logic into handleOnPause().
267 }
268
269 protected void handleOnPause() {
270 mController.onPause();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800271 }
272
Grace Kloba22ac16e2009-10-07 18:00:23 -0700273 @Override
274 protected void onDestroy() {
Dave Bort31a6d1c2009-04-13 15:56:49 -0700275 if (LOGV_ENABLED) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800276 Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
277 }
278 super.onDestroy();
Enrico Rosd6efa972014-12-02 19:49:59 -0800279 // mEngineInitializer can be null if onCreate is not called before onDestroy
280 // it happens when starting the activity with an intent while the screen is locked.
281 if (mEngineInitializer != null)
282 mEngineInitializer.onActivityDestroy();
John Reck9c35b9c2012-05-30 10:08:50 -0700283 mController.onDestroy();
284 mController = NullController.INSTANCE;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800285 }
286
287 @Override
288 public void onConfigurationChanged(Configuration newConfig) {
289 super.onConfigurationChanged(newConfig);
John Reck9c35b9c2012-05-30 10:08:50 -0700290 mController.onConfgurationChanged(newConfig);
kaiyizbb2db872013-08-01 22:24:07 -0400291
292 //For avoiding bug CR520353 temporarily, delay 300ms to refresh WebView.
293 mHandlerEx.postDelayed(runnable, 300);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800294 }
295
Grace Kloba22ac16e2009-10-07 18:00:23 -0700296 @Override
297 public void onLowMemory() {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800298 super.onLowMemory();
Michael Kolb8233fac2010-10-26 16:08:53 -0700299 mController.onLowMemory();
Grace Kloba22ac16e2009-10-07 18:00:23 -0700300 }
301
The Android Open Source Project0c908882009-03-03 19:32:16 -0800302 @Override
Pankaj Garg49b79252014-11-07 17:33:41 -0800303 public void invalidateOptionsMenu() {
304 super.invalidateOptionsMenu();
305 mController.invalidateOptionsMenu();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800306 }
307
308 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700309 public boolean onPrepareOptionsMenu(Menu menu) {
310 super.onPrepareOptionsMenu(menu);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800311 return false;
Cary Clark01cfcdd2010-06-04 16:36:45 -0400312 }
313
The Android Open Source Project0c908882009-03-03 19:32:16 -0800314 @Override
315 public boolean onOptionsItemSelected(MenuItem item) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700316 if (!mController.onOptionsItemSelected(item)) {
317 return super.onOptionsItemSelected(item);
Michael Kolb370a4f32010-10-06 10:45:32 -0700318 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800319 return true;
320 }
321
322 @Override
323 public void onCreateContextMenu(ContextMenu menu, View v,
324 ContextMenuInfo menuInfo) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700325 mController.onCreateContextMenu(menu, v, menuInfo);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800326 }
327
Michael Kolb8233fac2010-10-26 16:08:53 -0700328 @Override
329 public boolean onContextItemSelected(MenuItem item) {
330 return mController.onContextItemSelected(item);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700331 }
332
Grace Kloba5942df02009-09-18 11:48:29 -0700333 @Override
334 public boolean onKeyDown(int keyCode, KeyEvent event) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700335 return mController.onKeyDown(keyCode, event) ||
336 super.onKeyDown(keyCode, event);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800337 }
338
Grace Kloba5942df02009-09-18 11:48:29 -0700339 @Override
John Recke6bf4ab2011-02-24 15:48:05 -0800340 public boolean onKeyLongPress(int keyCode, KeyEvent event) {
341 return mController.onKeyLongPress(keyCode, event) ||
342 super.onKeyLongPress(keyCode, event);
343 }
344
345 @Override
Grace Kloba5942df02009-09-18 11:48:29 -0700346 public boolean onKeyUp(int keyCode, KeyEvent event) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700347 return mController.onKeyUp(keyCode, event) ||
348 super.onKeyUp(keyCode, event);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800349 }
350
Michael Kolbe421c242010-10-04 19:29:01 -0700351 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700352 public void onActionModeStarted(ActionMode mode) {
353 super.onActionModeStarted(mode);
354 mController.onActionModeStarted(mode);
Michael Kolbe421c242010-10-04 19:29:01 -0700355 }
356
Michael Kolbe421c242010-10-04 19:29:01 -0700357 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700358 public void onActionModeFinished(ActionMode mode) {
359 super.onActionModeFinished(mode);
360 mController.onActionModeFinished(mode);
Michael Kolbe421c242010-10-04 19:29:01 -0700361 }
362
The Android Open Source Project0c908882009-03-03 19:32:16 -0800363 @Override
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700364 protected void onActivityResult (int requestCode, int resultCode,
365 Intent intent) {
366 mEngineInitializer.onActivityResult(requestCode, resultCode, intent);
367 }
368
369 protected void handleOnActivityResult (int requestCode, int resultCode, Intent intent) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700370 mController.onActivityResult(requestCode, resultCode, intent);
Andrei Popescu163ab742009-10-20 17:58:23 +0100371 }
372
Michael Kolbfbc579a2011-07-07 15:59:33 -0700373 @Override
374 public boolean onSearchRequested() {
375 return mController.onSearchRequested();
376 }
377
Michael Kolbc3af0672011-08-09 10:24:41 -0700378 @Override
379 public boolean dispatchKeyEvent(KeyEvent event) {
380 return mController.dispatchKeyEvent(event)
381 || super.dispatchKeyEvent(event);
382 }
383
384 @Override
385 public boolean dispatchKeyShortcutEvent(KeyEvent event) {
386 return mController.dispatchKeyShortcutEvent(event)
387 || super.dispatchKeyShortcutEvent(event);
388 }
389
390 @Override
391 public boolean dispatchTouchEvent(MotionEvent ev) {
392 return mController.dispatchTouchEvent(ev)
393 || super.dispatchTouchEvent(ev);
394 }
395
396 @Override
397 public boolean dispatchTrackballEvent(MotionEvent ev) {
398 return mController.dispatchTrackballEvent(ev)
399 || super.dispatchTrackballEvent(ev);
400 }
401
402 @Override
403 public boolean dispatchGenericMotionEvent(MotionEvent ev) {
404 return mController.dispatchGenericMotionEvent(ev) ||
405 super.dispatchGenericMotionEvent(ev);
406 }
407
The Android Open Source Project0c908882009-03-03 19:32:16 -0800408}