blob: 2b3a9e5faf0a1bfd565ed8cc04013e62dfd29081 [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 }
204 cancelStopToast();
205 mActivityPaused = true;
206 }
207
208 public void onResume() {
209 mActivityPaused = false;
210 }
211
212 public void onDestroy() {
213 hideFakeTitleBar();
214 }
215
216 public void onConfigurationChanged(Configuration config) {
217 }
218
219 // key handling
220
221 @Override
222 public boolean onBackKey() {
223 if (mActiveTabsPage != null) {
224 // if tab page is showing, hide it
225 mUiController.removeActiveTabsPage(true);
226 return true;
227 }
228 if (mComboView != null) {
229 if (!mComboView.onBackPressed()) {
230 mUiController.removeComboView();
231 }
232 return true;
233 }
234 if (mCustomView != null) {
235 mUiController.hideCustomView();
236 return true;
237 }
238 return false;
239 }
240
241 // WebView callbacks
242
243 @Override
244 public void onPageStarted(Tab tab, String url, Bitmap favicon) {
245 if (mXLargeScreenSize) {
246 mTabBar.onPageStarted(tab, url, favicon);
247 }
248 if (tab.inForeground()) {
249 resetLockIcon(tab, url);
250 setUrlTitle(tab, url, null);
251 setFavicon(tab, favicon);
252 }
253
254 }
255
256 @Override
257 public void onPageFinished(Tab tab, String url) {
258 if (mXLargeScreenSize) {
259 mTabBar.onPageFinished(tab);
260 }
261 if (tab.inForeground()) {
262 // Reset the title and icon in case we stopped a provisional load.
263 resetTitleAndIcon(tab);
264 // Update the lock icon image only once we are done loading
265 updateLockIconToLatest(tab);
266 }
267 }
268
269 @Override
270 public void onPageStopped(Tab tab) {
271 cancelStopToast();
272 if (tab.inForeground()) {
273 mStopToast = Toast
274 .makeText(mActivity, R.string.stopping, Toast.LENGTH_SHORT);
275 mStopToast.show();
276 }
277 }
278
279 @Override
280 public void onProgressChanged(Tab tab, int progress) {
281 if (mXLargeScreenSize) {
282 mTabBar.onProgress(tab, progress);
283 }
284 if (tab.inForeground()) {
285 mFakeTitleBar.setProgress(progress);
286 if (progress == 100) {
287 if (!mOptionsMenuOpen || !mExtendedMenuOpen) {
288 hideFakeTitleBar();
289 }
290 } else {
291 if (!mOptionsMenuOpen || mExtendedMenuOpen) {
292 showFakeTitleBar();
293 }
294 }
295 }
296 }
297
298 @Override
Michael Kolb1bf23132010-11-19 12:55:12 -0800299 public boolean needsRestoreAllTabs() {
300 return mXLargeScreenSize;
301 }
302
303 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700304 public void addTab(Tab tab) {
305 if (mXLargeScreenSize) {
306 mTabBar.onNewTab(tab);
307 }
308 }
309
310 @Override
311 public void setActiveTab(Tab tab) {
Michael Kolb77df4562010-11-19 14:49:34 -0800312 if ((tab != mActiveTab) && (mActiveTab != null)) {
313 removeTabFromContentView(mActiveTab);
Michael Kolb8233fac2010-10-26 16:08:53 -0700314 }
Michael Kolb77df4562010-11-19 14:49:34 -0800315 mActiveTab = tab;
Michael Kolb8233fac2010-10-26 16:08:53 -0700316 attachTabToContentView(tab);
317 setShouldShowErrorConsole(tab, mUiController.shouldShowErrorConsole());
318
319 WebView view = tab.getWebView();
Michael Kolb77df4562010-11-19 14:49:34 -0800320 // TabControl.setCurrentTab has been called before this,
321 // so the tab is guaranteed to have a webview
322 if (view == null) {
323 Log.e(LOGTAG, "active tab with no webview detected");
324 return;
325 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700326 view.setEmbeddedTitleBar(mTitleBar);
327 if (tab.isInVoiceSearchMode()) {
328 showVoiceTitleBar(tab.getVoiceDisplayTitle());
329 } else {
330 revertVoiceTitleBar(tab);
331 }
332
333 if (mXLargeScreenSize) {
334 // Request focus on the top window.
335 mTabBar.onSetActiveTab(tab);
336 }
337 resetTitleIconAndProgress(tab);
338 updateLockIconToLatest(tab);
339 tab.getTopWindow().requestFocus();
340 }
341
342 @Override
Michael Kolb1bf23132010-11-19 12:55:12 -0800343 public void updateTabs(List<Tab> tabs) {
344 if (mXLargeScreenSize) {
345 mTabBar.updateTabs(tabs);
346 }
347 }
348
349 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700350 public void removeTab(Tab tab) {
Michael Kolb77df4562010-11-19 14:49:34 -0800351 if (mActiveTab == tab) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700352 removeTabFromContentView(tab);
Michael Kolb77df4562010-11-19 14:49:34 -0800353 mActiveTab = null;
Michael Kolb8233fac2010-10-26 16:08:53 -0700354 }
355 if (mXLargeScreenSize) {
356 mTabBar.onRemoveTab(tab);
357 }
358 }
359
360 @Override
361 public void detachTab(Tab tab) {
362 removeTabFromContentView(tab);
363 }
364
365 @Override
366 public void attachTab(Tab tab) {
367 attachTabToContentView(tab);
368 }
369
370 private void attachTabToContentView(Tab tab) {
371 if (tab.getWebView() == null) {
372 return;
373 }
374 View container = tab.getViewContainer();
375 WebView mainView = tab.getWebView();
376 // Attach the WebView to the container and then attach the
377 // container to the content view.
378 FrameLayout wrapper =
379 (FrameLayout) container.findViewById(R.id.webview_wrapper);
380 ViewGroup parent = (ViewGroup) mainView.getParent();
381 if (parent != wrapper) {
382 if (parent != null) {
383 Log.w(LOGTAG, "mMainView already has a parent in"
384 + " attachTabToContentView!");
385 parent.removeView(mainView);
386 }
387 wrapper.addView(mainView);
388 } else {
389 Log.w(LOGTAG, "mMainView is already attached to wrapper in"
390 + " attachTabToContentView!");
391 }
392 parent = (ViewGroup) container.getParent();
393 if (parent != mContentView) {
394 if (parent != null) {
395 Log.w(LOGTAG, "mContainer already has a parent in"
396 + " attachTabToContentView!");
397 parent.removeView(container);
398 }
399 mContentView.addView(container, COVER_SCREEN_PARAMS);
400 } else {
401 Log.w(LOGTAG, "mContainer is already attached to content in"
402 + " attachTabToContentView!");
403 }
404 mUiController.attachSubWindow(tab);
405 }
406
407 private void removeTabFromContentView(Tab tab) {
408 // Remove the container that contains the main WebView.
409 WebView mainView = tab.getWebView();
410 View container = tab.getViewContainer();
411 if (mainView == null) {
412 return;
413 }
414 // Remove the container from the content and then remove the
415 // WebView from the container. This will trigger a focus change
416 // needed by WebView.
417 FrameLayout wrapper =
418 (FrameLayout) container.findViewById(R.id.webview_wrapper);
419 wrapper.removeView(mainView);
420 mContentView.removeView(container);
421 mUiController.endActionMode();
422 mUiController.removeSubWindow(tab);
423 ErrorConsoleView errorConsole = tab.getErrorConsole(false);
424 if (errorConsole != null) {
425 mErrorConsoleContainer.removeView(errorConsole);
426 }
427 mainView.setEmbeddedTitleBar(null);
428 }
429
Michael Kolba713ec82010-11-29 17:27:06 -0800430 @Override
431 public void onSetWebView(Tab tab, WebView webView) {
432 View container = tab.getViewContainer();
433 if (container == null) {
434 // The tab consists of a container view, which contains the main
435 // WebView, as well as any other UI elements associated with the tab.
436 container = mActivity.getLayoutInflater().inflate(R.layout.tab,
437 null);
438 tab.setViewContainer(container);
439 }
440 if (tab.getWebView() != webView) {
441 // Just remove the old one.
442 FrameLayout wrapper =
443 (FrameLayout) container.findViewById(R.id.webview_wrapper);
444 wrapper.removeView(tab.getWebView());
445 }
446 }
447
Michael Kolb8233fac2010-10-26 16:08:53 -0700448 /**
Michael Kolb1514bb72010-11-22 09:11:48 -0800449 * create a sub window container and webview for the tab
450 * Note: this methods operates through side-effects for now
451 * it sets both the subView and subViewContainer for the given tab
452 * @param tab tab to create the sub window for
453 * @param subView webview to be set as a subwindow for the tab
454 */
455 @Override
456 public void createSubWindow(Tab tab, WebView subView) {
457 View subViewContainer = mActivity.getLayoutInflater().inflate(
458 R.layout.browser_subwindow, null);
459 ViewGroup inner = (ViewGroup) subViewContainer
460 .findViewById(R.id.inner_container);
461 inner.addView(subView, new LayoutParams(LayoutParams.MATCH_PARENT,
462 LayoutParams.MATCH_PARENT));
463 final ImageButton cancel = (ImageButton) subViewContainer
464 .findViewById(R.id.subwindow_close);
465 final WebView cancelSubView = subView;
466 cancel.setOnClickListener(new OnClickListener() {
467 public void onClick(View v) {
468 cancelSubView.getWebChromeClient().onCloseWindow(cancelSubView);
469 }
470 });
471 tab.setSubWebView(subView);
472 tab.setSubViewContainer(subViewContainer);
473 }
474
475 /**
Michael Kolb8233fac2010-10-26 16:08:53 -0700476 * Remove the sub window from the content view.
477 */
478 @Override
479 public void removeSubWindow(View subviewContainer) {
480 mContentView.removeView(subviewContainer);
481 mUiController.endActionMode();
482 }
483
484 /**
485 * Attach the sub window to the content view.
486 */
487 @Override
488 public void attachSubWindow(View container) {
Michael Kolb1514bb72010-11-22 09:11:48 -0800489 if (container.getParent() != null) {
490 // already attached, remove first
491 ((ViewGroup) container.getParent()).removeView(container);
492 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700493 mContentView.addView(container, COVER_SCREEN_PARAMS);
494 }
495
496 void showFakeTitleBar() {
497 if (!isFakeTitleBarShowing() && mActiveTabsPage == null &&
498 !mActivityPaused) {
499 WebView mainView = mUiController.getCurrentWebView();
500 // if there is no current WebView, don't show the faked title bar;
501 if (mainView == null) {
502 return;
503 }
504 // Do not need to check for null, since the current tab will have
505 // at least a main WebView, or we would have returned above.
506 if (mUiController.isInCustomActionMode()) {
507 // Do not show the fake title bar, while a custom ActionMode
508 // (i.e. find or select) is showing.
509 return;
510 }
511 if (mXLargeScreenSize) {
512 mContentView.addView(mFakeTitleBar);
513 mTabBar.onShowTitleBar();
514 } else {
515 WindowManager manager = (WindowManager)
516 mActivity.getSystemService(Context.WINDOW_SERVICE);
517
518 // Add the title bar to the window manager so it can receive
519 // touches
520 // while the menu is up
521 WindowManager.LayoutParams params =
522 new WindowManager.LayoutParams(
523 ViewGroup.LayoutParams.MATCH_PARENT,
524 ViewGroup.LayoutParams.WRAP_CONTENT,
525 WindowManager.LayoutParams.TYPE_APPLICATION,
526 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
527 PixelFormat.TRANSLUCENT);
528 params.gravity = Gravity.TOP;
529 boolean atTop = mainView.getScrollY() == 0;
530 params.windowAnimations = atTop ? 0 : R.style.TitleBar;
531 manager.addView(mFakeTitleBar, params);
532 }
533 }
534 }
535
536 void hideFakeTitleBar() {
537 if (!isFakeTitleBarShowing()) return;
538 if (mXLargeScreenSize) {
539 mContentView.removeView(mFakeTitleBar);
540 mTabBar.onHideTitleBar();
541 } else {
542 WindowManager.LayoutParams params =
543 (WindowManager.LayoutParams) mFakeTitleBar.getLayoutParams();
544 WebView mainView = mUiController.getCurrentWebView();
545 // Although we decided whether or not to animate based on the
546 // current
547 // scroll position, the scroll position may have changed since the
548 // fake title bar was displayed. Make sure it has the appropriate
549 // animation/lack thereof before removing.
550 params.windowAnimations =
551 mainView != null && mainView.getScrollY() == 0 ?
552 0 : R.style.TitleBar;
553 WindowManager manager = (WindowManager) mActivity
554 .getSystemService(Context.WINDOW_SERVICE);
555 manager.updateViewLayout(mFakeTitleBar, params);
556 manager.removeView(mFakeTitleBar);
557 }
558 }
559
560 boolean isFakeTitleBarShowing() {
561 return (mFakeTitleBar.getParent() != null);
562 }
563
564 @Override
565 public void showComboView(boolean startWithHistory, Bundle extras) {
566 mComboView = new CombinedBookmarkHistoryView(mActivity,
567 mUiController,
568 startWithHistory ?
569 CombinedBookmarkHistoryView.FRAGMENT_ID_HISTORY
570 : CombinedBookmarkHistoryView.FRAGMENT_ID_BOOKMARKS,
571 extras);
572 mTitleBar.setVisibility(View.GONE);
573 hideFakeTitleBar();
574 mContentView.addView(mComboView, COVER_SCREEN_PARAMS);
575 }
576
577 /**
578 * dismiss the ComboPage
579 */
580 @Override
581 public void hideComboView() {
582 if (mComboView != null) {
583 mContentView.removeView(mComboView);
584 mTitleBar.setVisibility(View.VISIBLE);
585 mComboView = null;
586 }
587 }
588
589 @Override
590 public void showCustomView(View view,
591 WebChromeClient.CustomViewCallback callback) {
592 // if a view already exists then immediately terminate the new one
593 if (mCustomView != null) {
594 callback.onCustomViewHidden();
595 return;
596 }
597
598 // Add the custom view to its container.
599 mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
600 mCustomView = view;
601 mCustomViewCallback = callback;
602 // Hide the content view.
603 mContentView.setVisibility(View.GONE);
604 // Finally show the custom view container.
605 setStatusBarVisibility(false);
606 mCustomViewContainer.setVisibility(View.VISIBLE);
607 mCustomViewContainer.bringToFront();
608 }
609
610 @Override
611 public void onHideCustomView() {
612 if (mCustomView == null)
613 return;
614
615 // Hide the custom view.
616 mCustomView.setVisibility(View.GONE);
617 // Remove the custom view from its container.
618 mCustomViewContainer.removeView(mCustomView);
619 mCustomView = null;
620 mCustomViewContainer.setVisibility(View.GONE);
621 mCustomViewCallback.onCustomViewHidden();
622 // Show the content view.
623 setStatusBarVisibility(true);
624 mContentView.setVisibility(View.VISIBLE);
625 }
626
627 @Override
628 public boolean isCustomViewShowing() {
629 return mCustomView != null;
630 }
631
632 @Override
633 public void showVoiceTitleBar(String title) {
634 mTitleBar.setInVoiceMode(true);
635 mTitleBar.setDisplayTitle(title);
636 mFakeTitleBar.setInVoiceMode(true);
637 mFakeTitleBar.setDisplayTitle(title);
638 }
639
640 @Override
641 public void revertVoiceTitleBar(Tab tab) {
642 mTitleBar.setInVoiceMode(false);
643 String url = tab.getCurrentUrl();
644 mTitleBar.setDisplayTitle(url);
645 mFakeTitleBar.setInVoiceMode(false);
646 mFakeTitleBar.setDisplayTitle(url);
647 }
648
649 // -------------------------------------------------------------------------
650
651 @Override
652 public void resetTitleAndRevertLockIcon(Tab tab) {
653 tab.revertLockIcon();
654 updateLockIconToLatest(tab);
655 resetTitleIconAndProgress(tab);
656 }
657
658 /**
659 * Resets the lock icon. This method is called when we start a new load and
660 * know the url to be loaded.
661 */
662 private void resetLockIcon(Tab tab, String url) {
663 // Save the lock-icon state (we revert to it if the load gets cancelled)
664 tab.resetLockIcon(url);
665 updateLockIconImage(Tab.LOCK_ICON_UNSECURE);
666 }
667
668 /**
669 * Update the lock icon to correspond to our latest state.
670 */
671 private void updateLockIconToLatest(Tab t) {
672 if (t != null) {
673 updateLockIconImage(t.getLockIconType());
674 }
675 }
676
677 /**
678 * Reset the title, favicon, and progress.
679 */
680 private void resetTitleIconAndProgress(Tab tab) {
681 WebView current = tab.getWebView();
682 if (current == null) {
683 return;
684 }
685 resetTitleAndIcon(current);
686 int progress = current.getProgress();
687 current.getWebChromeClient().onProgressChanged(current, progress);
688 }
689
690 @Override
691 public void resetTitleAndIcon(Tab tab) {
692 WebView current = tab.getWebView();
693 if (current != null) {
694 resetTitleAndIcon(current);
695 }
696 }
697
698 // Reset the title and the icon based on the given item.
699 private void resetTitleAndIcon(WebView view) {
700 WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
701 Tab tab = mTabControl.getTabFromView(view);
702 if (item != null) {
703 setUrlTitle(tab, item.getUrl(), item.getTitle());
704 setFavicon(tab, item.getFavicon());
705 } else {
706 setUrlTitle(tab, null, null);
707 setFavicon(tab, null);
708 }
709 }
710
711 /**
712 * Updates the lock-icon image in the title-bar.
713 */
714 private void updateLockIconImage(int lockIconType) {
715 Drawable d = null;
716 if (lockIconType == Tab.LOCK_ICON_SECURE) {
717 d = mSecLockIcon;
718 } else if (lockIconType == Tab.LOCK_ICON_MIXED) {
719 d = mMixLockIcon;
720 }
721 mTitleBar.setLock(d);
722 mFakeTitleBar.setLock(d);
723 }
724
725 // active tabs page
726
727 public void showActiveTabsPage() {
728 mActiveTabsPage = new ActiveTabsPage(mActivity, mUiController);
729 mTitleBar.setVisibility(View.GONE);
730 hideFakeTitleBar();
731 mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
732 mActiveTabsPage.requestFocus();
733 }
734
735 /**
736 * Remove the active tabs page.
737 * @param needToAttach If true, the active tabs page did not attach a tab
738 * to the content view, so we need to do that here.
739 */
740 public void removeActiveTabsPage() {
741 mContentView.removeView(mActiveTabsPage);
742 mTitleBar.setVisibility(View.VISIBLE);
743 mActiveTabsPage = null;
744 }
745
746 // action mode callbacks
747
748 @Override
749 public void onActionModeStarted(ActionMode mode) {
750 // hide the fake title bar when CAB is shown
751 hideFakeTitleBar();
752 }
753
754 @Override
755 public void onActionModeFinished(boolean inLoad) {
756 if (inLoad) {
757 // the titlebar was removed when the CAB was shown
758 // if the page is loading, show it again
759 showFakeTitleBar();
760 }
761 }
762
763 // menu handling callbacks
764
765 @Override
766 public void onOptionsMenuOpened() {
767 mOptionsMenuOpen = true;
768 // options menu opened, show fake title bar
769 showFakeTitleBar();
770 }
771
772 @Override
773 public void onExtendedMenuOpened() {
774 // Switching the menu to expanded view, so hide the
775 // title bar.
776 mExtendedMenuOpen = true;
777 hideFakeTitleBar();
778 }
779
780 @Override
781 public void onOptionsMenuClosed(boolean inLoad) {
782 mOptionsMenuOpen = false;
783 if (!inLoad) {
784 hideFakeTitleBar();
785 }
786 }
787
788 @Override
789 public void onExtendedMenuClosed(boolean inLoad) {
790 mExtendedMenuOpen = false;
791 if (inLoad) {
792 showFakeTitleBar();
793 }
794 }
795
796 @Override
797 public void onContextMenuCreated(Menu menu) {
798 hideFakeTitleBar();
799 }
800
801 @Override
802 public void onContextMenuClosed(Menu menu, boolean inLoad) {
803 if (inLoad) {
804 showFakeTitleBar();
805 }
806 }
807
808 @Override
809 public void onScroll(boolean titleVisible) {
810 if (mTabBar != null) {
811 mTabBar.onScroll(titleVisible);
812 }
813 }
814
815 // error console
816
817 @Override
818 public void setShouldShowErrorConsole(Tab tab, boolean flag) {
819 ErrorConsoleView errorConsole = tab.getErrorConsole(true);
820 if (flag) {
821 // Setting the show state of the console will cause it's the layout
822 // to be inflated.
823 if (errorConsole.numberOfErrors() > 0) {
824 errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
825 } else {
826 errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
827 }
828 if (errorConsole.getParent() != null) {
829 mErrorConsoleContainer.removeView(errorConsole);
830 }
831 // Now we can add it to the main view.
832 mErrorConsoleContainer.addView(errorConsole,
833 new LinearLayout.LayoutParams(
834 ViewGroup.LayoutParams.MATCH_PARENT,
835 ViewGroup.LayoutParams.WRAP_CONTENT));
836 } else {
837 mErrorConsoleContainer.removeView(errorConsole);
838 }
839 }
840
841 private void setStatusBarVisibility(boolean visible) {
842 int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
843 mActivity.getWindow().setFlags(flag,
844 WindowManager.LayoutParams.FLAG_FULLSCREEN);
845 }
846
847 @Override
848 public void setUrlTitle(Tab tab, String url, String title) {
849 if (TextUtils.isEmpty(title)) {
850 if (TextUtils.isEmpty(url)) {
851 title = mActivity.getResources()
852 .getString(R.string.title_bar_loading);
853 } else {
854 title = url;
855 }
856 }
857 if (tab.isInVoiceSearchMode()) return;
858 if (tab.inForeground()) {
859 mTitleBar.setDisplayTitle(url);
860 mFakeTitleBar.setDisplayTitle(url);
861 }
862 if (mXLargeScreenSize) {
863 mTabBar.onUrlAndTitle(tab, url, title);
864 }
865 }
866
867 // Set the favicon in the title bar.
868 @Override
869 public void setFavicon(Tab tab, Bitmap icon) {
870 mTitleBar.setFavicon(icon);
871 mFakeTitleBar.setFavicon(icon);
872 if (mXLargeScreenSize) {
873 mTabBar.onFavicon(tab, icon);
874 }
875 }
876 @Override
877 public boolean showsWeb() {
878 return mCustomView == null && mActiveTabsPage == null
879 && mComboView == null;
880 }
881
882 @Override
883 public void onPrepareOptionsMenu(Menu menu) {
884 if (!mXLargeScreenSize) {
885 final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
886 newtab.setEnabled(mUiController.getTabControl().canCreateNewTab());
887 }
888 }
889
890 // -------------------------------------------------------------------------
891 // Helper function for WebChromeClient
892 // -------------------------------------------------------------------------
893
894 @Override
895 public Bitmap getDefaultVideoPoster() {
896 if (mDefaultVideoPoster == null) {
897 mDefaultVideoPoster = BitmapFactory.decodeResource(
898 mActivity.getResources(), R.drawable.default_video_poster);
899 }
900 return mDefaultVideoPoster;
901 }
902
903 @Override
904 public View getVideoLoadingProgressView() {
905 if (mVideoProgressView == null) {
906 LayoutInflater inflater = LayoutInflater.from(mActivity);
907 mVideoProgressView = inflater.inflate(
908 R.layout.video_loading_progress, null);
909 }
910 return mVideoProgressView;
911 }
912
913}