blob: b7c5a82ab9faa279130277707154cc19123b4141 [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
511 void showFakeTitleBar() {
512 if (!isFakeTitleBarShowing() && mActiveTabsPage == null &&
513 !mActivityPaused) {
514 WebView mainView = mUiController.getCurrentWebView();
515 // if there is no current WebView, don't show the faked title bar;
516 if (mainView == null) {
517 return;
518 }
519 // Do not need to check for null, since the current tab will have
520 // at least a main WebView, or we would have returned above.
521 if (mUiController.isInCustomActionMode()) {
522 // Do not show the fake title bar, while a custom ActionMode
523 // (i.e. find or select) is showing.
524 return;
525 }
526 if (mXLargeScreenSize) {
527 mContentView.addView(mFakeTitleBar);
528 mTabBar.onShowTitleBar();
529 } else {
530 WindowManager manager = (WindowManager)
531 mActivity.getSystemService(Context.WINDOW_SERVICE);
532
533 // Add the title bar to the window manager so it can receive
534 // touches
535 // while the menu is up
536 WindowManager.LayoutParams params =
537 new WindowManager.LayoutParams(
538 ViewGroup.LayoutParams.MATCH_PARENT,
539 ViewGroup.LayoutParams.WRAP_CONTENT,
540 WindowManager.LayoutParams.TYPE_APPLICATION,
541 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
542 PixelFormat.TRANSLUCENT);
543 params.gravity = Gravity.TOP;
544 boolean atTop = mainView.getScrollY() == 0;
545 params.windowAnimations = atTop ? 0 : R.style.TitleBar;
546 manager.addView(mFakeTitleBar, params);
547 }
548 }
549 }
550
551 void hideFakeTitleBar() {
552 if (!isFakeTitleBarShowing()) return;
553 if (mXLargeScreenSize) {
554 mContentView.removeView(mFakeTitleBar);
555 mTabBar.onHideTitleBar();
556 } else {
557 WindowManager.LayoutParams params =
558 (WindowManager.LayoutParams) mFakeTitleBar.getLayoutParams();
559 WebView mainView = mUiController.getCurrentWebView();
560 // Although we decided whether or not to animate based on the
561 // current
562 // scroll position, the scroll position may have changed since the
563 // fake title bar was displayed. Make sure it has the appropriate
564 // animation/lack thereof before removing.
565 params.windowAnimations =
566 mainView != null && mainView.getScrollY() == 0 ?
567 0 : R.style.TitleBar;
568 WindowManager manager = (WindowManager) mActivity
569 .getSystemService(Context.WINDOW_SERVICE);
570 manager.updateViewLayout(mFakeTitleBar, params);
571 manager.removeView(mFakeTitleBar);
572 }
573 }
574
575 boolean isFakeTitleBarShowing() {
576 return (mFakeTitleBar.getParent() != null);
577 }
578
579 @Override
580 public void showComboView(boolean startWithHistory, Bundle extras) {
581 mComboView = new CombinedBookmarkHistoryView(mActivity,
582 mUiController,
583 startWithHistory ?
584 CombinedBookmarkHistoryView.FRAGMENT_ID_HISTORY
585 : CombinedBookmarkHistoryView.FRAGMENT_ID_BOOKMARKS,
586 extras);
587 mTitleBar.setVisibility(View.GONE);
588 hideFakeTitleBar();
Michael Kolb3a696282010-12-05 13:23:24 -0800589 dismissIME();
590 if (mActiveTab != null) {
591 WebView web = mActiveTab.getWebView();
592 mActiveTab.putInBackground();
593 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700594 mContentView.addView(mComboView, COVER_SCREEN_PARAMS);
595 }
596
597 /**
598 * dismiss the ComboPage
599 */
600 @Override
601 public void hideComboView() {
602 if (mComboView != null) {
603 mContentView.removeView(mComboView);
604 mTitleBar.setVisibility(View.VISIBLE);
605 mComboView = null;
606 }
Michael Kolb3a696282010-12-05 13:23:24 -0800607 if (mActiveTab != null) {
608 mActiveTab.putInForeground();
609 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700610 }
611
612 @Override
613 public void showCustomView(View view,
614 WebChromeClient.CustomViewCallback callback) {
615 // if a view already exists then immediately terminate the new one
616 if (mCustomView != null) {
617 callback.onCustomViewHidden();
618 return;
619 }
620
621 // Add the custom view to its container.
622 mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
623 mCustomView = view;
624 mCustomViewCallback = callback;
625 // Hide the content view.
626 mContentView.setVisibility(View.GONE);
627 // Finally show the custom view container.
628 setStatusBarVisibility(false);
629 mCustomViewContainer.setVisibility(View.VISIBLE);
630 mCustomViewContainer.bringToFront();
631 }
632
633 @Override
634 public void onHideCustomView() {
635 if (mCustomView == null)
636 return;
637
638 // Hide the custom view.
639 mCustomView.setVisibility(View.GONE);
640 // Remove the custom view from its container.
641 mCustomViewContainer.removeView(mCustomView);
642 mCustomView = null;
643 mCustomViewContainer.setVisibility(View.GONE);
644 mCustomViewCallback.onCustomViewHidden();
645 // Show the content view.
646 setStatusBarVisibility(true);
647 mContentView.setVisibility(View.VISIBLE);
648 }
649
650 @Override
651 public boolean isCustomViewShowing() {
652 return mCustomView != null;
653 }
654
655 @Override
656 public void showVoiceTitleBar(String title) {
657 mTitleBar.setInVoiceMode(true);
658 mTitleBar.setDisplayTitle(title);
659 mFakeTitleBar.setInVoiceMode(true);
660 mFakeTitleBar.setDisplayTitle(title);
661 }
662
663 @Override
664 public void revertVoiceTitleBar(Tab tab) {
665 mTitleBar.setInVoiceMode(false);
666 String url = tab.getCurrentUrl();
667 mTitleBar.setDisplayTitle(url);
668 mFakeTitleBar.setInVoiceMode(false);
669 mFakeTitleBar.setDisplayTitle(url);
670 }
671
Michael Kolb3a696282010-12-05 13:23:24 -0800672 private void dismissIME() {
673 if (mInputManager.isActive()) {
674 mInputManager.hideSoftInputFromWindow(mContentView.getWindowToken(),
675 0);
676 }
677 }
678
Michael Kolb8233fac2010-10-26 16:08:53 -0700679 // -------------------------------------------------------------------------
680
681 @Override
682 public void resetTitleAndRevertLockIcon(Tab tab) {
683 tab.revertLockIcon();
684 updateLockIconToLatest(tab);
685 resetTitleIconAndProgress(tab);
686 }
687
688 /**
689 * Resets the lock icon. This method is called when we start a new load and
690 * know the url to be loaded.
691 */
692 private void resetLockIcon(Tab tab, String url) {
693 // Save the lock-icon state (we revert to it if the load gets cancelled)
694 tab.resetLockIcon(url);
695 updateLockIconImage(Tab.LOCK_ICON_UNSECURE);
696 }
697
698 /**
699 * Update the lock icon to correspond to our latest state.
700 */
701 private void updateLockIconToLatest(Tab t) {
702 if (t != null) {
703 updateLockIconImage(t.getLockIconType());
704 }
705 }
706
707 /**
708 * Reset the title, favicon, and progress.
709 */
710 private void resetTitleIconAndProgress(Tab tab) {
711 WebView current = tab.getWebView();
712 if (current == null) {
713 return;
714 }
Michael Kolb41d3b942010-12-05 11:35:20 -0800715 resetTitleAndIcon(tab, current);
Michael Kolb8233fac2010-10-26 16:08:53 -0700716 int progress = current.getProgress();
717 current.getWebChromeClient().onProgressChanged(current, progress);
718 }
719
720 @Override
721 public void resetTitleAndIcon(Tab tab) {
722 WebView current = tab.getWebView();
723 if (current != null) {
Michael Kolb41d3b942010-12-05 11:35:20 -0800724 resetTitleAndIcon(tab, current);
Michael Kolb8233fac2010-10-26 16:08:53 -0700725 }
726 }
727
728 // Reset the title and the icon based on the given item.
Michael Kolb41d3b942010-12-05 11:35:20 -0800729 private void resetTitleAndIcon(Tab tab, WebView view) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700730 WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
Michael Kolb8233fac2010-10-26 16:08:53 -0700731 if (item != null) {
732 setUrlTitle(tab, item.getUrl(), item.getTitle());
733 setFavicon(tab, item.getFavicon());
734 } else {
John Reckef074262010-12-02 16:09:14 -0800735 setUrlTitle(tab, null, mActivity.getString(R.string.new_tab));
Michael Kolb8233fac2010-10-26 16:08:53 -0700736 setFavicon(tab, null);
737 }
738 }
739
740 /**
741 * Updates the lock-icon image in the title-bar.
742 */
743 private void updateLockIconImage(int lockIconType) {
744 Drawable d = null;
745 if (lockIconType == Tab.LOCK_ICON_SECURE) {
746 d = mSecLockIcon;
747 } else if (lockIconType == Tab.LOCK_ICON_MIXED) {
748 d = mMixLockIcon;
749 }
750 mTitleBar.setLock(d);
751 mFakeTitleBar.setLock(d);
752 }
753
754 // active tabs page
755
756 public void showActiveTabsPage() {
757 mActiveTabsPage = new ActiveTabsPage(mActivity, mUiController);
758 mTitleBar.setVisibility(View.GONE);
759 hideFakeTitleBar();
760 mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
761 mActiveTabsPage.requestFocus();
762 }
763
764 /**
765 * Remove the active tabs page.
Michael Kolb8233fac2010-10-26 16:08:53 -0700766 */
767 public void removeActiveTabsPage() {
768 mContentView.removeView(mActiveTabsPage);
769 mTitleBar.setVisibility(View.VISIBLE);
770 mActiveTabsPage = null;
771 }
772
773 // action mode callbacks
774
775 @Override
776 public void onActionModeStarted(ActionMode mode) {
777 // hide the fake title bar when CAB is shown
778 hideFakeTitleBar();
779 }
780
781 @Override
782 public void onActionModeFinished(boolean inLoad) {
783 if (inLoad) {
784 // the titlebar was removed when the CAB was shown
785 // if the page is loading, show it again
786 showFakeTitleBar();
787 }
788 }
789
790 // menu handling callbacks
791
792 @Override
793 public void onOptionsMenuOpened() {
794 mOptionsMenuOpen = true;
795 // options menu opened, show fake title bar
796 showFakeTitleBar();
797 }
798
799 @Override
800 public void onExtendedMenuOpened() {
801 // Switching the menu to expanded view, so hide the
802 // title bar.
803 mExtendedMenuOpen = true;
804 hideFakeTitleBar();
805 }
806
807 @Override
808 public void onOptionsMenuClosed(boolean inLoad) {
809 mOptionsMenuOpen = false;
810 if (!inLoad) {
811 hideFakeTitleBar();
812 }
813 }
814
815 @Override
816 public void onExtendedMenuClosed(boolean inLoad) {
817 mExtendedMenuOpen = false;
818 if (inLoad) {
819 showFakeTitleBar();
820 }
821 }
822
823 @Override
824 public void onContextMenuCreated(Menu menu) {
825 hideFakeTitleBar();
826 }
827
828 @Override
829 public void onContextMenuClosed(Menu menu, boolean inLoad) {
830 if (inLoad) {
831 showFakeTitleBar();
832 }
833 }
834
835 @Override
836 public void onScroll(boolean titleVisible) {
837 if (mTabBar != null) {
838 mTabBar.onScroll(titleVisible);
839 }
840 }
841
842 // error console
843
844 @Override
845 public void setShouldShowErrorConsole(Tab tab, boolean flag) {
846 ErrorConsoleView errorConsole = tab.getErrorConsole(true);
847 if (flag) {
848 // Setting the show state of the console will cause it's the layout
849 // to be inflated.
850 if (errorConsole.numberOfErrors() > 0) {
851 errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
852 } else {
853 errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
854 }
855 if (errorConsole.getParent() != null) {
856 mErrorConsoleContainer.removeView(errorConsole);
857 }
858 // Now we can add it to the main view.
859 mErrorConsoleContainer.addView(errorConsole,
860 new LinearLayout.LayoutParams(
861 ViewGroup.LayoutParams.MATCH_PARENT,
862 ViewGroup.LayoutParams.WRAP_CONTENT));
863 } else {
864 mErrorConsoleContainer.removeView(errorConsole);
865 }
866 }
867
868 private void setStatusBarVisibility(boolean visible) {
869 int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
870 mActivity.getWindow().setFlags(flag,
871 WindowManager.LayoutParams.FLAG_FULLSCREEN);
872 }
873
874 @Override
875 public void setUrlTitle(Tab tab, String url, String title) {
876 if (TextUtils.isEmpty(title)) {
John Reckef074262010-12-02 16:09:14 -0800877 title = url;
Michael Kolb8233fac2010-10-26 16:08:53 -0700878 }
879 if (tab.isInVoiceSearchMode()) return;
880 if (tab.inForeground()) {
881 mTitleBar.setDisplayTitle(url);
882 mFakeTitleBar.setDisplayTitle(url);
883 }
884 if (mXLargeScreenSize) {
885 mTabBar.onUrlAndTitle(tab, url, title);
886 }
887 }
888
889 // Set the favicon in the title bar.
890 @Override
891 public void setFavicon(Tab tab, Bitmap icon) {
892 mTitleBar.setFavicon(icon);
893 mFakeTitleBar.setFavicon(icon);
894 if (mXLargeScreenSize) {
895 mTabBar.onFavicon(tab, icon);
896 }
897 }
898 @Override
899 public boolean showsWeb() {
900 return mCustomView == null && mActiveTabsPage == null
901 && mComboView == null;
902 }
903
904 @Override
905 public void onPrepareOptionsMenu(Menu menu) {
906 if (!mXLargeScreenSize) {
907 final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
908 newtab.setEnabled(mUiController.getTabControl().canCreateNewTab());
909 }
910 }
911
912 // -------------------------------------------------------------------------
913 // Helper function for WebChromeClient
914 // -------------------------------------------------------------------------
915
916 @Override
917 public Bitmap getDefaultVideoPoster() {
918 if (mDefaultVideoPoster == null) {
919 mDefaultVideoPoster = BitmapFactory.decodeResource(
920 mActivity.getResources(), R.drawable.default_video_poster);
921 }
922 return mDefaultVideoPoster;
923 }
924
925 @Override
926 public View getVideoLoadingProgressView() {
927 if (mVideoProgressView == null) {
928 LayoutInflater inflater = LayoutInflater.from(mActivity);
929 mVideoProgressView = inflater.inflate(
930 R.layout.video_loading_progress, null);
931 }
932 return mVideoProgressView;
933 }
934
Michael Kolb843510f2010-12-09 10:51:49 -0800935 @Override
936 public void showMaxTabsWarning() {
937 Toast warning = Toast.makeText(mActivity,
938 mActivity.getString(R.string.max_tabs_warning),
939 Toast.LENGTH_SHORT);
940 warning.show();
941 }
942
Michael Kolb8233fac2010-10-26 16:08:53 -0700943}