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