blob: 4fca79d19e8b255db5338275d74b5eb9836654a7 [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 }
352 resetTitleIconAndProgress(tab);
353 updateLockIconToLatest(tab);
354 tab.getTopWindow().requestFocus();
355 }
356
357 @Override
Michael Kolb1bf23132010-11-19 12:55:12 -0800358 public void updateTabs(List<Tab> tabs) {
359 if (mXLargeScreenSize) {
360 mTabBar.updateTabs(tabs);
361 }
362 }
363
364 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700365 public void removeTab(Tab tab) {
Michael Kolb77df4562010-11-19 14:49:34 -0800366 if (mActiveTab == tab) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700367 removeTabFromContentView(tab);
Michael Kolb77df4562010-11-19 14:49:34 -0800368 mActiveTab = null;
Michael Kolb8233fac2010-10-26 16:08:53 -0700369 }
370 if (mXLargeScreenSize) {
371 mTabBar.onRemoveTab(tab);
372 }
373 }
374
375 @Override
376 public void detachTab(Tab tab) {
377 removeTabFromContentView(tab);
378 }
379
380 @Override
381 public void attachTab(Tab tab) {
382 attachTabToContentView(tab);
383 }
384
385 private void attachTabToContentView(Tab tab) {
386 if (tab.getWebView() == null) {
387 return;
388 }
389 View container = tab.getViewContainer();
390 WebView mainView = tab.getWebView();
391 // Attach the WebView to the container and then attach the
392 // container to the content view.
393 FrameLayout wrapper =
394 (FrameLayout) container.findViewById(R.id.webview_wrapper);
395 ViewGroup parent = (ViewGroup) mainView.getParent();
396 if (parent != wrapper) {
397 if (parent != null) {
398 Log.w(LOGTAG, "mMainView already has a parent in"
399 + " attachTabToContentView!");
400 parent.removeView(mainView);
401 }
402 wrapper.addView(mainView);
403 } else {
404 Log.w(LOGTAG, "mMainView is already attached to wrapper in"
405 + " attachTabToContentView!");
406 }
407 parent = (ViewGroup) container.getParent();
408 if (parent != mContentView) {
409 if (parent != null) {
410 Log.w(LOGTAG, "mContainer already has a parent in"
411 + " attachTabToContentView!");
412 parent.removeView(container);
413 }
414 mContentView.addView(container, COVER_SCREEN_PARAMS);
415 } else {
416 Log.w(LOGTAG, "mContainer is already attached to content in"
417 + " attachTabToContentView!");
418 }
419 mUiController.attachSubWindow(tab);
420 }
421
422 private void removeTabFromContentView(Tab tab) {
423 // Remove the container that contains the main WebView.
424 WebView mainView = tab.getWebView();
425 View container = tab.getViewContainer();
426 if (mainView == null) {
427 return;
428 }
429 // Remove the container from the content and then remove the
430 // WebView from the container. This will trigger a focus change
431 // needed by WebView.
432 FrameLayout wrapper =
433 (FrameLayout) container.findViewById(R.id.webview_wrapper);
434 wrapper.removeView(mainView);
435 mContentView.removeView(container);
436 mUiController.endActionMode();
437 mUiController.removeSubWindow(tab);
438 ErrorConsoleView errorConsole = tab.getErrorConsole(false);
439 if (errorConsole != null) {
440 mErrorConsoleContainer.removeView(errorConsole);
441 }
442 mainView.setEmbeddedTitleBar(null);
443 }
444
Michael Kolba713ec82010-11-29 17:27:06 -0800445 @Override
446 public void onSetWebView(Tab tab, WebView webView) {
447 View container = tab.getViewContainer();
448 if (container == null) {
449 // The tab consists of a container view, which contains the main
450 // WebView, as well as any other UI elements associated with the tab.
451 container = mActivity.getLayoutInflater().inflate(R.layout.tab,
452 null);
453 tab.setViewContainer(container);
454 }
455 if (tab.getWebView() != webView) {
456 // Just remove the old one.
457 FrameLayout wrapper =
458 (FrameLayout) container.findViewById(R.id.webview_wrapper);
459 wrapper.removeView(tab.getWebView());
460 }
461 }
462
Michael Kolb8233fac2010-10-26 16:08:53 -0700463 /**
Michael Kolb1514bb72010-11-22 09:11:48 -0800464 * create a sub window container and webview for the tab
465 * Note: this methods operates through side-effects for now
466 * it sets both the subView and subViewContainer for the given tab
467 * @param tab tab to create the sub window for
468 * @param subView webview to be set as a subwindow for the tab
469 */
470 @Override
471 public void createSubWindow(Tab tab, WebView subView) {
472 View subViewContainer = mActivity.getLayoutInflater().inflate(
473 R.layout.browser_subwindow, null);
474 ViewGroup inner = (ViewGroup) subViewContainer
475 .findViewById(R.id.inner_container);
476 inner.addView(subView, new LayoutParams(LayoutParams.MATCH_PARENT,
477 LayoutParams.MATCH_PARENT));
478 final ImageButton cancel = (ImageButton) subViewContainer
479 .findViewById(R.id.subwindow_close);
480 final WebView cancelSubView = subView;
481 cancel.setOnClickListener(new OnClickListener() {
482 public void onClick(View v) {
483 cancelSubView.getWebChromeClient().onCloseWindow(cancelSubView);
484 }
485 });
486 tab.setSubWebView(subView);
487 tab.setSubViewContainer(subViewContainer);
488 }
489
490 /**
Michael Kolb8233fac2010-10-26 16:08:53 -0700491 * Remove the sub window from the content view.
492 */
493 @Override
494 public void removeSubWindow(View subviewContainer) {
495 mContentView.removeView(subviewContainer);
496 mUiController.endActionMode();
497 }
498
499 /**
500 * Attach the sub window to the content view.
501 */
502 @Override
503 public void attachSubWindow(View container) {
Michael Kolb1514bb72010-11-22 09:11:48 -0800504 if (container.getParent() != null) {
505 // already attached, remove first
506 ((ViewGroup) container.getParent()).removeView(container);
507 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700508 mContentView.addView(container, COVER_SCREEN_PARAMS);
509 }
510
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800511 int getTitleBarWidth() {
512 if (mTitleBar != null) {
513 return mTitleBar.getWidth();
514 }
515 return 0;
516 }
517
Michael Kolb8233fac2010-10-26 16:08:53 -0700518 void showFakeTitleBar() {
519 if (!isFakeTitleBarShowing() && mActiveTabsPage == null &&
520 !mActivityPaused) {
521 WebView mainView = mUiController.getCurrentWebView();
522 // if there is no current WebView, don't show the faked title bar;
523 if (mainView == null) {
524 return;
525 }
526 // Do not need to check for null, since the current tab will have
527 // at least a main WebView, or we would have returned above.
528 if (mUiController.isInCustomActionMode()) {
529 // Do not show the fake title bar, while a custom ActionMode
530 // (i.e. find or select) is showing.
531 return;
532 }
533 if (mXLargeScreenSize) {
534 mContentView.addView(mFakeTitleBar);
535 mTabBar.onShowTitleBar();
536 } else {
537 WindowManager manager = (WindowManager)
538 mActivity.getSystemService(Context.WINDOW_SERVICE);
539
540 // Add the title bar to the window manager so it can receive
541 // touches
542 // while the menu is up
543 WindowManager.LayoutParams params =
544 new WindowManager.LayoutParams(
545 ViewGroup.LayoutParams.MATCH_PARENT,
546 ViewGroup.LayoutParams.WRAP_CONTENT,
547 WindowManager.LayoutParams.TYPE_APPLICATION,
548 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
549 PixelFormat.TRANSLUCENT);
550 params.gravity = Gravity.TOP;
551 boolean atTop = mainView.getScrollY() == 0;
552 params.windowAnimations = atTop ? 0 : R.style.TitleBar;
553 manager.addView(mFakeTitleBar, params);
554 }
555 }
556 }
557
558 void hideFakeTitleBar() {
559 if (!isFakeTitleBarShowing()) return;
560 if (mXLargeScreenSize) {
561 mContentView.removeView(mFakeTitleBar);
562 mTabBar.onHideTitleBar();
563 } else {
564 WindowManager.LayoutParams params =
565 (WindowManager.LayoutParams) mFakeTitleBar.getLayoutParams();
566 WebView mainView = mUiController.getCurrentWebView();
567 // Although we decided whether or not to animate based on the
568 // current
569 // scroll position, the scroll position may have changed since the
570 // fake title bar was displayed. Make sure it has the appropriate
571 // animation/lack thereof before removing.
572 params.windowAnimations =
573 mainView != null && mainView.getScrollY() == 0 ?
574 0 : R.style.TitleBar;
575 WindowManager manager = (WindowManager) mActivity
576 .getSystemService(Context.WINDOW_SERVICE);
577 manager.updateViewLayout(mFakeTitleBar, params);
578 manager.removeView(mFakeTitleBar);
579 }
580 }
581
582 boolean isFakeTitleBarShowing() {
583 return (mFakeTitleBar.getParent() != null);
584 }
585
586 @Override
587 public void showComboView(boolean startWithHistory, Bundle extras) {
588 mComboView = new CombinedBookmarkHistoryView(mActivity,
589 mUiController,
590 startWithHistory ?
591 CombinedBookmarkHistoryView.FRAGMENT_ID_HISTORY
592 : CombinedBookmarkHistoryView.FRAGMENT_ID_BOOKMARKS,
593 extras);
594 mTitleBar.setVisibility(View.GONE);
595 hideFakeTitleBar();
Michael Kolb3a696282010-12-05 13:23:24 -0800596 dismissIME();
597 if (mActiveTab != null) {
598 WebView web = mActiveTab.getWebView();
599 mActiveTab.putInBackground();
600 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700601 mContentView.addView(mComboView, COVER_SCREEN_PARAMS);
602 }
603
604 /**
605 * dismiss the ComboPage
606 */
607 @Override
608 public void hideComboView() {
609 if (mComboView != null) {
610 mContentView.removeView(mComboView);
611 mTitleBar.setVisibility(View.VISIBLE);
612 mComboView = null;
613 }
Michael Kolb3a696282010-12-05 13:23:24 -0800614 if (mActiveTab != null) {
615 mActiveTab.putInForeground();
616 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700617 }
618
619 @Override
620 public void showCustomView(View view,
621 WebChromeClient.CustomViewCallback callback) {
622 // if a view already exists then immediately terminate the new one
623 if (mCustomView != null) {
624 callback.onCustomViewHidden();
625 return;
626 }
627
628 // Add the custom view to its container.
629 mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
630 mCustomView = view;
631 mCustomViewCallback = callback;
632 // Hide the content view.
633 mContentView.setVisibility(View.GONE);
634 // Finally show the custom view container.
635 setStatusBarVisibility(false);
636 mCustomViewContainer.setVisibility(View.VISIBLE);
637 mCustomViewContainer.bringToFront();
638 }
639
640 @Override
641 public void onHideCustomView() {
642 if (mCustomView == null)
643 return;
644
645 // Hide the custom view.
646 mCustomView.setVisibility(View.GONE);
647 // Remove the custom view from its container.
648 mCustomViewContainer.removeView(mCustomView);
649 mCustomView = null;
650 mCustomViewContainer.setVisibility(View.GONE);
651 mCustomViewCallback.onCustomViewHidden();
652 // Show the content view.
653 setStatusBarVisibility(true);
654 mContentView.setVisibility(View.VISIBLE);
655 }
656
657 @Override
658 public boolean isCustomViewShowing() {
659 return mCustomView != null;
660 }
661
662 @Override
663 public void showVoiceTitleBar(String title) {
664 mTitleBar.setInVoiceMode(true);
665 mTitleBar.setDisplayTitle(title);
666 mFakeTitleBar.setInVoiceMode(true);
667 mFakeTitleBar.setDisplayTitle(title);
668 }
669
670 @Override
671 public void revertVoiceTitleBar(Tab tab) {
672 mTitleBar.setInVoiceMode(false);
673 String url = tab.getCurrentUrl();
674 mTitleBar.setDisplayTitle(url);
675 mFakeTitleBar.setInVoiceMode(false);
676 mFakeTitleBar.setDisplayTitle(url);
677 }
678
Michael Kolb3a696282010-12-05 13:23:24 -0800679 private void dismissIME() {
680 if (mInputManager.isActive()) {
681 mInputManager.hideSoftInputFromWindow(mContentView.getWindowToken(),
682 0);
683 }
684 }
685
Michael Kolb8233fac2010-10-26 16:08:53 -0700686 // -------------------------------------------------------------------------
687
688 @Override
689 public void resetTitleAndRevertLockIcon(Tab tab) {
690 tab.revertLockIcon();
691 updateLockIconToLatest(tab);
692 resetTitleIconAndProgress(tab);
693 }
694
695 /**
696 * Resets the lock icon. This method is called when we start a new load and
697 * know the url to be loaded.
698 */
699 private void resetLockIcon(Tab tab, String url) {
700 // Save the lock-icon state (we revert to it if the load gets cancelled)
701 tab.resetLockIcon(url);
702 updateLockIconImage(Tab.LOCK_ICON_UNSECURE);
703 }
704
705 /**
706 * Update the lock icon to correspond to our latest state.
707 */
708 private void updateLockIconToLatest(Tab t) {
709 if (t != null) {
710 updateLockIconImage(t.getLockIconType());
711 }
712 }
713
714 /**
715 * Reset the title, favicon, and progress.
716 */
717 private void resetTitleIconAndProgress(Tab tab) {
718 WebView current = tab.getWebView();
719 if (current == null) {
720 return;
721 }
Michael Kolb41d3b942010-12-05 11:35:20 -0800722 resetTitleAndIcon(tab, current);
Michael Kolb8233fac2010-10-26 16:08:53 -0700723 int progress = current.getProgress();
724 current.getWebChromeClient().onProgressChanged(current, progress);
725 }
726
727 @Override
728 public void resetTitleAndIcon(Tab tab) {
729 WebView current = tab.getWebView();
730 if (current != null) {
Michael Kolb41d3b942010-12-05 11:35:20 -0800731 resetTitleAndIcon(tab, current);
Michael Kolb8233fac2010-10-26 16:08:53 -0700732 }
733 }
734
735 // Reset the title and the icon based on the given item.
Michael Kolb41d3b942010-12-05 11:35:20 -0800736 private void resetTitleAndIcon(Tab tab, WebView view) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700737 WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
Michael Kolb8233fac2010-10-26 16:08:53 -0700738 if (item != null) {
739 setUrlTitle(tab, item.getUrl(), item.getTitle());
740 setFavicon(tab, item.getFavicon());
741 } else {
John Reckef074262010-12-02 16:09:14 -0800742 setUrlTitle(tab, null, mActivity.getString(R.string.new_tab));
Michael Kolb8233fac2010-10-26 16:08:53 -0700743 setFavicon(tab, null);
744 }
745 }
746
747 /**
748 * Updates the lock-icon image in the title-bar.
749 */
750 private void updateLockIconImage(int lockIconType) {
751 Drawable d = null;
752 if (lockIconType == Tab.LOCK_ICON_SECURE) {
753 d = mSecLockIcon;
754 } else if (lockIconType == Tab.LOCK_ICON_MIXED) {
755 d = mMixLockIcon;
756 }
757 mTitleBar.setLock(d);
758 mFakeTitleBar.setLock(d);
759 }
760
761 // active tabs page
762
763 public void showActiveTabsPage() {
764 mActiveTabsPage = new ActiveTabsPage(mActivity, mUiController);
765 mTitleBar.setVisibility(View.GONE);
766 hideFakeTitleBar();
767 mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
768 mActiveTabsPage.requestFocus();
769 }
770
771 /**
772 * Remove the active tabs page.
Michael Kolb8233fac2010-10-26 16:08:53 -0700773 */
774 public void removeActiveTabsPage() {
775 mContentView.removeView(mActiveTabsPage);
776 mTitleBar.setVisibility(View.VISIBLE);
777 mActiveTabsPage = null;
778 }
779
780 // action mode callbacks
781
782 @Override
783 public void onActionModeStarted(ActionMode mode) {
784 // hide the fake title bar when CAB is shown
785 hideFakeTitleBar();
786 }
787
788 @Override
789 public void onActionModeFinished(boolean inLoad) {
790 if (inLoad) {
791 // the titlebar was removed when the CAB was shown
792 // if the page is loading, show it again
793 showFakeTitleBar();
794 }
795 }
796
797 // menu handling callbacks
798
799 @Override
800 public void onOptionsMenuOpened() {
801 mOptionsMenuOpen = true;
802 // options menu opened, show fake title bar
803 showFakeTitleBar();
804 }
805
806 @Override
807 public void onExtendedMenuOpened() {
808 // Switching the menu to expanded view, so hide the
809 // title bar.
810 mExtendedMenuOpen = true;
811 hideFakeTitleBar();
812 }
813
814 @Override
815 public void onOptionsMenuClosed(boolean inLoad) {
816 mOptionsMenuOpen = false;
817 if (!inLoad) {
818 hideFakeTitleBar();
819 }
820 }
821
822 @Override
823 public void onExtendedMenuClosed(boolean inLoad) {
824 mExtendedMenuOpen = false;
825 if (inLoad) {
826 showFakeTitleBar();
827 }
828 }
829
830 @Override
831 public void onContextMenuCreated(Menu menu) {
832 hideFakeTitleBar();
833 }
834
835 @Override
836 public void onContextMenuClosed(Menu menu, boolean inLoad) {
837 if (inLoad) {
838 showFakeTitleBar();
839 }
840 }
841
842 @Override
843 public void onScroll(boolean titleVisible) {
844 if (mTabBar != null) {
845 mTabBar.onScroll(titleVisible);
846 }
847 }
848
849 // error console
850
851 @Override
852 public void setShouldShowErrorConsole(Tab tab, boolean flag) {
853 ErrorConsoleView errorConsole = tab.getErrorConsole(true);
854 if (flag) {
855 // Setting the show state of the console will cause it's the layout
856 // to be inflated.
857 if (errorConsole.numberOfErrors() > 0) {
858 errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
859 } else {
860 errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
861 }
862 if (errorConsole.getParent() != null) {
863 mErrorConsoleContainer.removeView(errorConsole);
864 }
865 // Now we can add it to the main view.
866 mErrorConsoleContainer.addView(errorConsole,
867 new LinearLayout.LayoutParams(
868 ViewGroup.LayoutParams.MATCH_PARENT,
869 ViewGroup.LayoutParams.WRAP_CONTENT));
870 } else {
871 mErrorConsoleContainer.removeView(errorConsole);
872 }
873 }
874
875 private void setStatusBarVisibility(boolean visible) {
876 int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
877 mActivity.getWindow().setFlags(flag,
878 WindowManager.LayoutParams.FLAG_FULLSCREEN);
879 }
880
881 @Override
882 public void setUrlTitle(Tab tab, String url, String title) {
883 if (TextUtils.isEmpty(title)) {
John Reckef074262010-12-02 16:09:14 -0800884 title = url;
Michael Kolb8233fac2010-10-26 16:08:53 -0700885 }
886 if (tab.isInVoiceSearchMode()) return;
887 if (tab.inForeground()) {
888 mTitleBar.setDisplayTitle(url);
889 mFakeTitleBar.setDisplayTitle(url);
890 }
891 if (mXLargeScreenSize) {
892 mTabBar.onUrlAndTitle(tab, url, title);
893 }
894 }
895
896 // Set the favicon in the title bar.
897 @Override
898 public void setFavicon(Tab tab, Bitmap icon) {
899 mTitleBar.setFavicon(icon);
900 mFakeTitleBar.setFavicon(icon);
901 if (mXLargeScreenSize) {
902 mTabBar.onFavicon(tab, icon);
903 }
904 }
905 @Override
906 public boolean showsWeb() {
907 return mCustomView == null && mActiveTabsPage == null
908 && mComboView == null;
909 }
910
911 @Override
912 public void onPrepareOptionsMenu(Menu menu) {
913 if (!mXLargeScreenSize) {
914 final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
915 newtab.setEnabled(mUiController.getTabControl().canCreateNewTab());
916 }
917 }
918
919 // -------------------------------------------------------------------------
920 // Helper function for WebChromeClient
921 // -------------------------------------------------------------------------
922
923 @Override
924 public Bitmap getDefaultVideoPoster() {
925 if (mDefaultVideoPoster == null) {
926 mDefaultVideoPoster = BitmapFactory.decodeResource(
927 mActivity.getResources(), R.drawable.default_video_poster);
928 }
929 return mDefaultVideoPoster;
930 }
931
932 @Override
933 public View getVideoLoadingProgressView() {
934 if (mVideoProgressView == null) {
935 LayoutInflater inflater = LayoutInflater.from(mActivity);
936 mVideoProgressView = inflater.inflate(
937 R.layout.video_loading_progress, null);
938 }
939 return mVideoProgressView;
940 }
941
Michael Kolb843510f2010-12-09 10:51:49 -0800942 @Override
943 public void showMaxTabsWarning() {
944 Toast warning = Toast.makeText(mActivity,
945 mActivity.getString(R.string.max_tabs_warning),
946 Toast.LENGTH_SHORT);
947 warning.show();
948 }
949
Michael Kolb8233fac2010-10-26 16:08:53 -0700950}