blob: b39cb433958f84675660ce22c9be32c800934669 [file] [log] [blame]
Michael Kolb8233fac2010-10-26 16:08:53 -07001/*
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.browser;
18
19import android.app.ActionBar;
20import android.app.Activity;
21import android.content.Context;
22import android.content.res.Configuration;
23import android.content.res.Resources;
24import android.graphics.Bitmap;
25import android.graphics.BitmapFactory;
26import android.graphics.PixelFormat;
27import android.graphics.drawable.Drawable;
28import android.os.Bundle;
29import android.text.TextUtils;
30import android.util.Log;
31import android.view.ActionMode;
32import android.view.Gravity;
33import android.view.LayoutInflater;
34import android.view.Menu;
35import android.view.MenuItem;
36import android.view.View;
Michael Kolb1514bb72010-11-22 09:11:48 -080037import android.view.View.OnClickListener;
Michael Kolb8233fac2010-10-26 16:08:53 -070038import android.view.ViewGroup;
Michael Kolb1514bb72010-11-22 09:11:48 -080039import android.view.ViewGroup.LayoutParams;
Michael Kolb8233fac2010-10-26 16:08:53 -070040import android.view.WindowManager;
Michael Kolb3a696282010-12-05 13:23:24 -080041import android.view.inputmethod.InputMethodManager;
Michael Kolb8233fac2010-10-26 16:08:53 -070042import android.webkit.WebChromeClient;
43import android.webkit.WebHistoryItem;
44import android.webkit.WebView;
45import android.widget.FrameLayout;
Michael Kolb1514bb72010-11-22 09:11:48 -080046import android.widget.ImageButton;
Michael Kolb8233fac2010-10-26 16:08:53 -070047import android.widget.LinearLayout;
48import android.widget.Toast;
49
Michael Kolb1bf23132010-11-19 12:55:12 -080050import java.util.List;
51
Michael Kolb8233fac2010-10-26 16:08:53 -070052/**
53 * UI interface definitions
54 */
55public class BaseUi implements UI, WebViewFactory {
56
57 private static final String LOGTAG = "BaseUi";
58
59 private static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
60 new FrameLayout.LayoutParams(
61 ViewGroup.LayoutParams.MATCH_PARENT,
62 ViewGroup.LayoutParams.MATCH_PARENT);
63
64 private static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
65 new FrameLayout.LayoutParams(
66 ViewGroup.LayoutParams.MATCH_PARENT,
67 ViewGroup.LayoutParams.MATCH_PARENT,
68 Gravity.CENTER);
69
70 Activity mActivity;
71 UiController mUiController;
72 TabControl mTabControl;
Michael Kolb77df4562010-11-19 14:49:34 -080073 private Tab mActiveTab;
Michael Kolb3a696282010-12-05 13:23:24 -080074 private InputMethodManager mInputManager;
Michael Kolb8233fac2010-10-26 16:08:53 -070075
76 private Drawable mSecLockIcon;
77 private Drawable mMixLockIcon;
78
79 private boolean mXLargeScreenSize;
80 private FrameLayout mBrowserFrameLayout;
81 private FrameLayout mContentView;
82 private FrameLayout mCustomViewContainer;
83 private TitleBarBase mTitleBar;
84 private TitleBarBase mFakeTitleBar;
85 private TabBar mTabBar;
86
87 private View mCustomView;
88 private WebChromeClient.CustomViewCallback mCustomViewCallback;
89
90 private CombinedBookmarkHistoryView mComboView;
91
92 private LinearLayout mErrorConsoleContainer = null;
93
94 private Toast mStopToast;
95 private ActiveTabsPage mActiveTabsPage;
96
97 // the default <video> poster
98 private Bitmap mDefaultVideoPoster;
99 // the video progress view
100 private View mVideoProgressView;
101
102 boolean mExtendedMenuOpen;
103 boolean mOptionsMenuOpen;
104
105 private boolean mActivityPaused;
106
107 public BaseUi(Activity browser, UiController controller) {
108 mActivity = browser;
109 mUiController = controller;
110 mTabControl = controller.getTabControl();
111 Resources res = mActivity.getResources();
Michael Kolb3a696282010-12-05 13:23:24 -0800112 mInputManager = (InputMethodManager)
113 browser.getSystemService(Activity.INPUT_METHOD_SERVICE);
Michael Kolb8233fac2010-10-26 16:08:53 -0700114 mSecLockIcon = res.getDrawable(R.drawable.ic_secure);
115 mMixLockIcon = res.getDrawable(R.drawable.ic_partial_secure);
116
117
118 mXLargeScreenSize = (res.getConfiguration().screenLayout
119 & Configuration.SCREENLAYOUT_SIZE_MASK)
120 == Configuration.SCREENLAYOUT_SIZE_XLARGE;
121
122 FrameLayout frameLayout = (FrameLayout) mActivity.getWindow()
123 .getDecorView().findViewById(android.R.id.content);
124 mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(mActivity)
125 .inflate(R.layout.custom_screen, null);
126 mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
127 R.id.main_content);
128 mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
129 .findViewById(R.id.error_console);
130 mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
131 .findViewById(R.id.fullscreen_custom_content);
132 frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
133
134 if (mXLargeScreenSize) {
135 mTitleBar = new TitleBarXLarge(mActivity, mUiController);
136 mTitleBar.setProgress(100);
137 mFakeTitleBar = new TitleBarXLarge(mActivity, mUiController);
138 ActionBar actionBar = mActivity.getActionBar();
139 mTabBar = new TabBar(mActivity, mUiController, this);
140 actionBar.setCustomNavigationMode(mTabBar);
141 } else {
142 mTitleBar = new TitleBar(mActivity, mUiController);
143 // mTitleBar will be always be shown in the fully loaded mode on
144 // phone
145 mTitleBar.setProgress(100);
146 mFakeTitleBar = new TitleBar(mActivity, mUiController);
147 }
148 }
149
150 // webview factory
151
152 @Override
153 public WebView createWebView(boolean privateBrowsing) {
154 // Create a new WebView
155 ScrollWebView w = new ScrollWebView(mActivity, null,
156 android.R.attr.webViewStyle, privateBrowsing);
157 w.setScrollbarFadingEnabled(true);
158 w.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
159 w.setMapTrackballToArrowKeys(false); // use trackball directly
160 // Enable the built-in zoom
161 w.getSettings().setBuiltInZoomControls(true);
162 if (mXLargeScreenSize) {
163 w.setScrollListener(mTabBar);
164 w.getSettings().setDisplayZoomControls(false);
165 }
166
167 // Add this WebView to the settings observer list and update the
168 // settings
169 final BrowserSettings s = BrowserSettings.getInstance();
170 s.addObserver(w.getSettings()).update(s, null);
171 return w;
172 }
173
Michael Kolb1514bb72010-11-22 09:11:48 -0800174 @Override
175 public WebView createSubWebView(boolean privateBrowsing) {
176 ScrollWebView web = (ScrollWebView) createWebView(privateBrowsing);
177 if (mXLargeScreenSize) {
178 // no scroll listener for subview
179 web.setScrollListener(null);
180 }
181 return web;
182 }
183
Michael Kolb8233fac2010-10-26 16:08:53 -0700184 void stopWebViewScrolling() {
185 ScrollWebView web = (ScrollWebView) mUiController.getCurrentWebView();
186 if (web != null) {
187 web.stopScroll();
188 }
189 }
190
191 private void cancelStopToast() {
192 if (mStopToast != null) {
193 mStopToast.cancel();
194 mStopToast = null;
195 }
196 }
197
198 // lifecycle
199
200 public void onPause() {
201 // FIXME: This removes the active tabs page and resets the menu to
202 // MAIN_MENU. A better solution might be to do this work in onNewIntent
203 // but then we would need to save it in onSaveInstanceState and restore
204 // it in onCreate/onRestoreInstanceState
205 if (mActiveTabsPage != null) {
206 mUiController.removeActiveTabsPage(true);
207 }
Michael Kolb7a5cf472010-11-30 13:23:53 -0800208 if (isCustomViewShowing()) {
209 onHideCustomView();
210 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700211 cancelStopToast();
212 mActivityPaused = true;
213 }
214
215 public void onResume() {
216 mActivityPaused = false;
217 }
218
219 public void onDestroy() {
220 hideFakeTitleBar();
221 }
222
223 public void onConfigurationChanged(Configuration config) {
224 }
225
226 // key handling
227
228 @Override
229 public boolean onBackKey() {
230 if (mActiveTabsPage != null) {
231 // if tab page is showing, hide it
232 mUiController.removeActiveTabsPage(true);
233 return true;
234 }
235 if (mComboView != null) {
236 if (!mComboView.onBackPressed()) {
237 mUiController.removeComboView();
238 }
239 return true;
240 }
241 if (mCustomView != null) {
242 mUiController.hideCustomView();
243 return true;
244 }
245 return false;
246 }
247
248 // WebView callbacks
249
250 @Override
251 public void onPageStarted(Tab tab, String url, Bitmap favicon) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700252 if (tab.inForeground()) {
253 resetLockIcon(tab, url);
254 setUrlTitle(tab, url, null);
255 setFavicon(tab, favicon);
256 }
John Reckef074262010-12-02 16:09:14 -0800257 if (mXLargeScreenSize) {
258 mTabBar.onPageStarted(tab, url, favicon);
259 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700260 }
261
262 @Override
Leon Scroggins4cd97792010-12-03 15:31:56 -0500263 public void bookmarkedStatusHasChanged(Tab tab) {
264 if (tab.inForeground() && mXLargeScreenSize) {
265 boolean isBookmark = tab.isBookmarkedSite();
266 ((TitleBarXLarge) mTitleBar).setCurrentUrlIsBookmark(isBookmark);
267 ((TitleBarXLarge) mFakeTitleBar).setCurrentUrlIsBookmark(isBookmark);
268 }
269 }
270
271 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700272 public void onPageFinished(Tab tab, String url) {
273 if (mXLargeScreenSize) {
274 mTabBar.onPageFinished(tab);
275 }
276 if (tab.inForeground()) {
277 // Reset the title and icon in case we stopped a provisional load.
278 resetTitleAndIcon(tab);
279 // Update the lock icon image only once we are done loading
280 updateLockIconToLatest(tab);
281 }
282 }
283
284 @Override
285 public void onPageStopped(Tab tab) {
286 cancelStopToast();
287 if (tab.inForeground()) {
288 mStopToast = Toast
289 .makeText(mActivity, R.string.stopping, Toast.LENGTH_SHORT);
290 mStopToast.show();
291 }
292 }
293
294 @Override
295 public void onProgressChanged(Tab tab, int progress) {
296 if (mXLargeScreenSize) {
297 mTabBar.onProgress(tab, progress);
298 }
299 if (tab.inForeground()) {
300 mFakeTitleBar.setProgress(progress);
301 if (progress == 100) {
302 if (!mOptionsMenuOpen || !mExtendedMenuOpen) {
303 hideFakeTitleBar();
304 }
305 } else {
306 if (!mOptionsMenuOpen || mExtendedMenuOpen) {
307 showFakeTitleBar();
308 }
309 }
310 }
311 }
312
313 @Override
Michael Kolb1bf23132010-11-19 12:55:12 -0800314 public boolean needsRestoreAllTabs() {
315 return mXLargeScreenSize;
316 }
317
318 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700319 public void addTab(Tab tab) {
320 if (mXLargeScreenSize) {
321 mTabBar.onNewTab(tab);
322 }
323 }
324
325 @Override
326 public void setActiveTab(Tab tab) {
Michael Kolb77df4562010-11-19 14:49:34 -0800327 if ((tab != mActiveTab) && (mActiveTab != null)) {
328 removeTabFromContentView(mActiveTab);
Michael Kolb8233fac2010-10-26 16:08:53 -0700329 }
Michael Kolb77df4562010-11-19 14:49:34 -0800330 mActiveTab = tab;
Michael Kolb8233fac2010-10-26 16:08:53 -0700331 attachTabToContentView(tab);
332 setShouldShowErrorConsole(tab, mUiController.shouldShowErrorConsole());
333
334 WebView view = tab.getWebView();
Michael Kolb77df4562010-11-19 14:49:34 -0800335 // TabControl.setCurrentTab has been called before this,
336 // so the tab is guaranteed to have a webview
337 if (view == null) {
338 Log.e(LOGTAG, "active tab with no webview detected");
339 return;
340 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700341 view.setEmbeddedTitleBar(mTitleBar);
342 if (tab.isInVoiceSearchMode()) {
343 showVoiceTitleBar(tab.getVoiceDisplayTitle());
344 } else {
345 revertVoiceTitleBar(tab);
346 }
347
348 if (mXLargeScreenSize) {
349 // Request focus on the top window.
350 mTabBar.onSetActiveTab(tab);
351 }
Leon Scroggins4cd97792010-12-03 15:31:56 -0500352 bookmarkedStatusHasChanged(tab);
Michael Kolb8233fac2010-10-26 16:08:53 -0700353 resetTitleIconAndProgress(tab);
354 updateLockIconToLatest(tab);
355 tab.getTopWindow().requestFocus();
356 }
357
358 @Override
Michael Kolb1bf23132010-11-19 12:55:12 -0800359 public void updateTabs(List<Tab> tabs) {
360 if (mXLargeScreenSize) {
361 mTabBar.updateTabs(tabs);
362 }
363 }
364
365 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700366 public void removeTab(Tab tab) {
Michael Kolb77df4562010-11-19 14:49:34 -0800367 if (mActiveTab == tab) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700368 removeTabFromContentView(tab);
Michael Kolb77df4562010-11-19 14:49:34 -0800369 mActiveTab = null;
Michael Kolb8233fac2010-10-26 16:08:53 -0700370 }
371 if (mXLargeScreenSize) {
372 mTabBar.onRemoveTab(tab);
373 }
374 }
375
376 @Override
377 public void detachTab(Tab tab) {
378 removeTabFromContentView(tab);
379 }
380
381 @Override
382 public void attachTab(Tab tab) {
383 attachTabToContentView(tab);
384 }
385
386 private void attachTabToContentView(Tab tab) {
387 if (tab.getWebView() == null) {
388 return;
389 }
390 View container = tab.getViewContainer();
391 WebView mainView = tab.getWebView();
392 // Attach the WebView to the container and then attach the
393 // container to the content view.
394 FrameLayout wrapper =
395 (FrameLayout) container.findViewById(R.id.webview_wrapper);
396 ViewGroup parent = (ViewGroup) mainView.getParent();
397 if (parent != wrapper) {
398 if (parent != null) {
399 Log.w(LOGTAG, "mMainView already has a parent in"
400 + " attachTabToContentView!");
401 parent.removeView(mainView);
402 }
403 wrapper.addView(mainView);
404 } else {
405 Log.w(LOGTAG, "mMainView is already attached to wrapper in"
406 + " attachTabToContentView!");
407 }
408 parent = (ViewGroup) container.getParent();
409 if (parent != mContentView) {
410 if (parent != null) {
411 Log.w(LOGTAG, "mContainer already has a parent in"
412 + " attachTabToContentView!");
413 parent.removeView(container);
414 }
415 mContentView.addView(container, COVER_SCREEN_PARAMS);
416 } else {
417 Log.w(LOGTAG, "mContainer is already attached to content in"
418 + " attachTabToContentView!");
419 }
420 mUiController.attachSubWindow(tab);
421 }
422
423 private void removeTabFromContentView(Tab tab) {
424 // Remove the container that contains the main WebView.
425 WebView mainView = tab.getWebView();
426 View container = tab.getViewContainer();
427 if (mainView == null) {
428 return;
429 }
430 // Remove the container from the content and then remove the
431 // WebView from the container. This will trigger a focus change
432 // needed by WebView.
433 FrameLayout wrapper =
434 (FrameLayout) container.findViewById(R.id.webview_wrapper);
435 wrapper.removeView(mainView);
436 mContentView.removeView(container);
437 mUiController.endActionMode();
438 mUiController.removeSubWindow(tab);
439 ErrorConsoleView errorConsole = tab.getErrorConsole(false);
440 if (errorConsole != null) {
441 mErrorConsoleContainer.removeView(errorConsole);
442 }
443 mainView.setEmbeddedTitleBar(null);
444 }
445
Michael Kolba713ec82010-11-29 17:27:06 -0800446 @Override
447 public void onSetWebView(Tab tab, WebView webView) {
448 View container = tab.getViewContainer();
449 if (container == null) {
450 // The tab consists of a container view, which contains the main
451 // WebView, as well as any other UI elements associated with the tab.
452 container = mActivity.getLayoutInflater().inflate(R.layout.tab,
453 null);
454 tab.setViewContainer(container);
455 }
456 if (tab.getWebView() != webView) {
457 // Just remove the old one.
458 FrameLayout wrapper =
459 (FrameLayout) container.findViewById(R.id.webview_wrapper);
460 wrapper.removeView(tab.getWebView());
461 }
462 }
463
Michael Kolb8233fac2010-10-26 16:08:53 -0700464 /**
Michael Kolb1514bb72010-11-22 09:11:48 -0800465 * create a sub window container and webview for the tab
466 * Note: this methods operates through side-effects for now
467 * it sets both the subView and subViewContainer for the given tab
468 * @param tab tab to create the sub window for
469 * @param subView webview to be set as a subwindow for the tab
470 */
471 @Override
472 public void createSubWindow(Tab tab, WebView subView) {
473 View subViewContainer = mActivity.getLayoutInflater().inflate(
474 R.layout.browser_subwindow, null);
475 ViewGroup inner = (ViewGroup) subViewContainer
476 .findViewById(R.id.inner_container);
477 inner.addView(subView, new LayoutParams(LayoutParams.MATCH_PARENT,
478 LayoutParams.MATCH_PARENT));
479 final ImageButton cancel = (ImageButton) subViewContainer
480 .findViewById(R.id.subwindow_close);
481 final WebView cancelSubView = subView;
482 cancel.setOnClickListener(new OnClickListener() {
483 public void onClick(View v) {
484 cancelSubView.getWebChromeClient().onCloseWindow(cancelSubView);
485 }
486 });
487 tab.setSubWebView(subView);
488 tab.setSubViewContainer(subViewContainer);
489 }
490
491 /**
Michael Kolb8233fac2010-10-26 16:08:53 -0700492 * Remove the sub window from the content view.
493 */
494 @Override
495 public void removeSubWindow(View subviewContainer) {
496 mContentView.removeView(subviewContainer);
497 mUiController.endActionMode();
498 }
499
500 /**
501 * Attach the sub window to the content view.
502 */
503 @Override
504 public void attachSubWindow(View container) {
Michael Kolb1514bb72010-11-22 09:11:48 -0800505 if (container.getParent() != null) {
506 // already attached, remove first
507 ((ViewGroup) container.getParent()).removeView(container);
508 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700509 mContentView.addView(container, COVER_SCREEN_PARAMS);
510 }
511
512 void showFakeTitleBar() {
513 if (!isFakeTitleBarShowing() && mActiveTabsPage == null &&
514 !mActivityPaused) {
515 WebView mainView = mUiController.getCurrentWebView();
516 // if there is no current WebView, don't show the faked title bar;
517 if (mainView == null) {
518 return;
519 }
520 // Do not need to check for null, since the current tab will have
521 // at least a main WebView, or we would have returned above.
522 if (mUiController.isInCustomActionMode()) {
523 // Do not show the fake title bar, while a custom ActionMode
524 // (i.e. find or select) is showing.
525 return;
526 }
527 if (mXLargeScreenSize) {
528 mContentView.addView(mFakeTitleBar);
529 mTabBar.onShowTitleBar();
530 } else {
531 WindowManager manager = (WindowManager)
532 mActivity.getSystemService(Context.WINDOW_SERVICE);
533
534 // Add the title bar to the window manager so it can receive
535 // touches
536 // while the menu is up
537 WindowManager.LayoutParams params =
538 new WindowManager.LayoutParams(
539 ViewGroup.LayoutParams.MATCH_PARENT,
540 ViewGroup.LayoutParams.WRAP_CONTENT,
541 WindowManager.LayoutParams.TYPE_APPLICATION,
542 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
543 PixelFormat.TRANSLUCENT);
544 params.gravity = Gravity.TOP;
545 boolean atTop = mainView.getScrollY() == 0;
546 params.windowAnimations = atTop ? 0 : R.style.TitleBar;
547 manager.addView(mFakeTitleBar, params);
548 }
549 }
550 }
551
552 void hideFakeTitleBar() {
553 if (!isFakeTitleBarShowing()) return;
554 if (mXLargeScreenSize) {
555 mContentView.removeView(mFakeTitleBar);
556 mTabBar.onHideTitleBar();
557 } else {
558 WindowManager.LayoutParams params =
559 (WindowManager.LayoutParams) mFakeTitleBar.getLayoutParams();
560 WebView mainView = mUiController.getCurrentWebView();
561 // Although we decided whether or not to animate based on the
562 // current
563 // scroll position, the scroll position may have changed since the
564 // fake title bar was displayed. Make sure it has the appropriate
565 // animation/lack thereof before removing.
566 params.windowAnimations =
567 mainView != null && mainView.getScrollY() == 0 ?
568 0 : R.style.TitleBar;
569 WindowManager manager = (WindowManager) mActivity
570 .getSystemService(Context.WINDOW_SERVICE);
571 manager.updateViewLayout(mFakeTitleBar, params);
572 manager.removeView(mFakeTitleBar);
573 }
574 }
575
576 boolean isFakeTitleBarShowing() {
577 return (mFakeTitleBar.getParent() != null);
578 }
579
580 @Override
581 public void showComboView(boolean startWithHistory, Bundle extras) {
582 mComboView = new CombinedBookmarkHistoryView(mActivity,
583 mUiController,
584 startWithHistory ?
585 CombinedBookmarkHistoryView.FRAGMENT_ID_HISTORY
586 : CombinedBookmarkHistoryView.FRAGMENT_ID_BOOKMARKS,
587 extras);
588 mTitleBar.setVisibility(View.GONE);
589 hideFakeTitleBar();
Michael Kolb3a696282010-12-05 13:23:24 -0800590 dismissIME();
591 if (mActiveTab != null) {
592 WebView web = mActiveTab.getWebView();
593 mActiveTab.putInBackground();
594 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700595 mContentView.addView(mComboView, COVER_SCREEN_PARAMS);
596 }
597
598 /**
599 * dismiss the ComboPage
600 */
601 @Override
602 public void hideComboView() {
603 if (mComboView != null) {
604 mContentView.removeView(mComboView);
605 mTitleBar.setVisibility(View.VISIBLE);
606 mComboView = null;
607 }
Michael Kolb3a696282010-12-05 13:23:24 -0800608 if (mActiveTab != null) {
609 mActiveTab.putInForeground();
610 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700611 }
612
613 @Override
614 public void showCustomView(View view,
615 WebChromeClient.CustomViewCallback callback) {
616 // if a view already exists then immediately terminate the new one
617 if (mCustomView != null) {
618 callback.onCustomViewHidden();
619 return;
620 }
621
622 // Add the custom view to its container.
623 mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
624 mCustomView = view;
625 mCustomViewCallback = callback;
626 // Hide the content view.
627 mContentView.setVisibility(View.GONE);
628 // Finally show the custom view container.
629 setStatusBarVisibility(false);
630 mCustomViewContainer.setVisibility(View.VISIBLE);
631 mCustomViewContainer.bringToFront();
632 }
633
634 @Override
635 public void onHideCustomView() {
636 if (mCustomView == null)
637 return;
638
639 // Hide the custom view.
640 mCustomView.setVisibility(View.GONE);
641 // Remove the custom view from its container.
642 mCustomViewContainer.removeView(mCustomView);
643 mCustomView = null;
644 mCustomViewContainer.setVisibility(View.GONE);
645 mCustomViewCallback.onCustomViewHidden();
646 // Show the content view.
647 setStatusBarVisibility(true);
648 mContentView.setVisibility(View.VISIBLE);
649 }
650
651 @Override
652 public boolean isCustomViewShowing() {
653 return mCustomView != null;
654 }
655
656 @Override
657 public void showVoiceTitleBar(String title) {
658 mTitleBar.setInVoiceMode(true);
659 mTitleBar.setDisplayTitle(title);
660 mFakeTitleBar.setInVoiceMode(true);
661 mFakeTitleBar.setDisplayTitle(title);
662 }
663
664 @Override
665 public void revertVoiceTitleBar(Tab tab) {
666 mTitleBar.setInVoiceMode(false);
667 String url = tab.getCurrentUrl();
668 mTitleBar.setDisplayTitle(url);
669 mFakeTitleBar.setInVoiceMode(false);
670 mFakeTitleBar.setDisplayTitle(url);
671 }
672
Michael Kolb3a696282010-12-05 13:23:24 -0800673 private void dismissIME() {
674 if (mInputManager.isActive()) {
675 mInputManager.hideSoftInputFromWindow(mContentView.getWindowToken(),
676 0);
677 }
678 }
679
Michael Kolb8233fac2010-10-26 16:08:53 -0700680 // -------------------------------------------------------------------------
681
682 @Override
683 public void resetTitleAndRevertLockIcon(Tab tab) {
684 tab.revertLockIcon();
685 updateLockIconToLatest(tab);
686 resetTitleIconAndProgress(tab);
687 }
688
689 /**
690 * Resets the lock icon. This method is called when we start a new load and
691 * know the url to be loaded.
692 */
693 private void resetLockIcon(Tab tab, String url) {
694 // Save the lock-icon state (we revert to it if the load gets cancelled)
695 tab.resetLockIcon(url);
696 updateLockIconImage(Tab.LOCK_ICON_UNSECURE);
697 }
698
699 /**
700 * Update the lock icon to correspond to our latest state.
701 */
702 private void updateLockIconToLatest(Tab t) {
703 if (t != null) {
704 updateLockIconImage(t.getLockIconType());
705 }
706 }
707
708 /**
709 * Reset the title, favicon, and progress.
710 */
711 private void resetTitleIconAndProgress(Tab tab) {
712 WebView current = tab.getWebView();
713 if (current == null) {
714 return;
715 }
Michael Kolb41d3b942010-12-05 11:35:20 -0800716 resetTitleAndIcon(tab, current);
Michael Kolb8233fac2010-10-26 16:08:53 -0700717 int progress = current.getProgress();
718 current.getWebChromeClient().onProgressChanged(current, progress);
719 }
720
721 @Override
722 public void resetTitleAndIcon(Tab tab) {
723 WebView current = tab.getWebView();
724 if (current != null) {
Michael Kolb41d3b942010-12-05 11:35:20 -0800725 resetTitleAndIcon(tab, current);
Michael Kolb8233fac2010-10-26 16:08:53 -0700726 }
727 }
728
729 // Reset the title and the icon based on the given item.
Michael Kolb41d3b942010-12-05 11:35:20 -0800730 private void resetTitleAndIcon(Tab tab, WebView view) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700731 WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
Michael Kolb8233fac2010-10-26 16:08:53 -0700732 if (item != null) {
733 setUrlTitle(tab, item.getUrl(), item.getTitle());
734 setFavicon(tab, item.getFavicon());
735 } else {
John Reckef074262010-12-02 16:09:14 -0800736 setUrlTitle(tab, null, mActivity.getString(R.string.new_tab));
Michael Kolb8233fac2010-10-26 16:08:53 -0700737 setFavicon(tab, null);
738 }
739 }
740
741 /**
742 * Updates the lock-icon image in the title-bar.
743 */
744 private void updateLockIconImage(int lockIconType) {
745 Drawable d = null;
746 if (lockIconType == Tab.LOCK_ICON_SECURE) {
747 d = mSecLockIcon;
748 } else if (lockIconType == Tab.LOCK_ICON_MIXED) {
749 d = mMixLockIcon;
750 }
751 mTitleBar.setLock(d);
752 mFakeTitleBar.setLock(d);
753 }
754
755 // active tabs page
756
757 public void showActiveTabsPage() {
758 mActiveTabsPage = new ActiveTabsPage(mActivity, mUiController);
759 mTitleBar.setVisibility(View.GONE);
760 hideFakeTitleBar();
761 mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
762 mActiveTabsPage.requestFocus();
763 }
764
765 /**
766 * Remove the active tabs page.
Michael Kolb8233fac2010-10-26 16:08:53 -0700767 */
768 public void removeActiveTabsPage() {
769 mContentView.removeView(mActiveTabsPage);
770 mTitleBar.setVisibility(View.VISIBLE);
771 mActiveTabsPage = null;
772 }
773
774 // action mode callbacks
775
776 @Override
777 public void onActionModeStarted(ActionMode mode) {
778 // hide the fake title bar when CAB is shown
779 hideFakeTitleBar();
780 }
781
782 @Override
783 public void onActionModeFinished(boolean inLoad) {
784 if (inLoad) {
785 // the titlebar was removed when the CAB was shown
786 // if the page is loading, show it again
787 showFakeTitleBar();
788 }
789 }
790
791 // menu handling callbacks
792
793 @Override
794 public void onOptionsMenuOpened() {
795 mOptionsMenuOpen = true;
796 // options menu opened, show fake title bar
797 showFakeTitleBar();
798 }
799
800 @Override
801 public void onExtendedMenuOpened() {
802 // Switching the menu to expanded view, so hide the
803 // title bar.
804 mExtendedMenuOpen = true;
805 hideFakeTitleBar();
806 }
807
808 @Override
809 public void onOptionsMenuClosed(boolean inLoad) {
810 mOptionsMenuOpen = false;
811 if (!inLoad) {
812 hideFakeTitleBar();
813 }
814 }
815
816 @Override
817 public void onExtendedMenuClosed(boolean inLoad) {
818 mExtendedMenuOpen = false;
819 if (inLoad) {
820 showFakeTitleBar();
821 }
822 }
823
824 @Override
825 public void onContextMenuCreated(Menu menu) {
826 hideFakeTitleBar();
827 }
828
829 @Override
830 public void onContextMenuClosed(Menu menu, boolean inLoad) {
831 if (inLoad) {
832 showFakeTitleBar();
833 }
834 }
835
836 @Override
837 public void onScroll(boolean titleVisible) {
838 if (mTabBar != null) {
839 mTabBar.onScroll(titleVisible);
840 }
841 }
842
843 // error console
844
845 @Override
846 public void setShouldShowErrorConsole(Tab tab, boolean flag) {
847 ErrorConsoleView errorConsole = tab.getErrorConsole(true);
848 if (flag) {
849 // Setting the show state of the console will cause it's the layout
850 // to be inflated.
851 if (errorConsole.numberOfErrors() > 0) {
852 errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
853 } else {
854 errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
855 }
856 if (errorConsole.getParent() != null) {
857 mErrorConsoleContainer.removeView(errorConsole);
858 }
859 // Now we can add it to the main view.
860 mErrorConsoleContainer.addView(errorConsole,
861 new LinearLayout.LayoutParams(
862 ViewGroup.LayoutParams.MATCH_PARENT,
863 ViewGroup.LayoutParams.WRAP_CONTENT));
864 } else {
865 mErrorConsoleContainer.removeView(errorConsole);
866 }
867 }
868
869 private void setStatusBarVisibility(boolean visible) {
870 int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
871 mActivity.getWindow().setFlags(flag,
872 WindowManager.LayoutParams.FLAG_FULLSCREEN);
873 }
874
875 @Override
876 public void setUrlTitle(Tab tab, String url, String title) {
877 if (TextUtils.isEmpty(title)) {
John Reckef074262010-12-02 16:09:14 -0800878 title = url;
Michael Kolb8233fac2010-10-26 16:08:53 -0700879 }
880 if (tab.isInVoiceSearchMode()) return;
881 if (tab.inForeground()) {
882 mTitleBar.setDisplayTitle(url);
883 mFakeTitleBar.setDisplayTitle(url);
884 }
885 if (mXLargeScreenSize) {
886 mTabBar.onUrlAndTitle(tab, url, title);
887 }
888 }
889
890 // Set the favicon in the title bar.
891 @Override
892 public void setFavicon(Tab tab, Bitmap icon) {
893 mTitleBar.setFavicon(icon);
894 mFakeTitleBar.setFavicon(icon);
895 if (mXLargeScreenSize) {
896 mTabBar.onFavicon(tab, icon);
897 }
898 }
899 @Override
900 public boolean showsWeb() {
901 return mCustomView == null && mActiveTabsPage == null
902 && mComboView == null;
903 }
904
905 @Override
906 public void onPrepareOptionsMenu(Menu menu) {
907 if (!mXLargeScreenSize) {
908 final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
909 newtab.setEnabled(mUiController.getTabControl().canCreateNewTab());
910 }
911 }
912
913 // -------------------------------------------------------------------------
914 // Helper function for WebChromeClient
915 // -------------------------------------------------------------------------
916
917 @Override
918 public Bitmap getDefaultVideoPoster() {
919 if (mDefaultVideoPoster == null) {
920 mDefaultVideoPoster = BitmapFactory.decodeResource(
921 mActivity.getResources(), R.drawable.default_video_poster);
922 }
923 return mDefaultVideoPoster;
924 }
925
926 @Override
927 public View getVideoLoadingProgressView() {
928 if (mVideoProgressView == null) {
929 LayoutInflater inflater = LayoutInflater.from(mActivity);
930 mVideoProgressView = inflater.inflate(
931 R.layout.video_loading_progress, null);
932 }
933 return mVideoProgressView;
934 }
935
936}