1 /* 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 17 package com.android.browser; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.res.Configuration; 23 import android.content.res.Resources; 24 import android.graphics.Bitmap; 25 import android.graphics.BitmapFactory; 26 import android.graphics.Color; 27 import android.graphics.drawable.BitmapDrawable; 28 import android.graphics.drawable.Drawable; 29 import android.graphics.drawable.LayerDrawable; 30 import android.graphics.drawable.PaintDrawable; 31 import android.os.Bundle; 32 import android.os.Handler; 33 import android.os.Message; 34 import android.text.TextUtils; 35 import android.view.Gravity; 36 import android.view.LayoutInflater; 37 import android.view.Menu; 38 import android.view.MenuItem; 39 import android.view.MotionEvent; 40 import android.view.View; 41 import android.view.View.OnClickListener; 42 import android.view.ViewGroup; 43 import android.view.ViewGroup.LayoutParams; 44 import android.view.Window; 45 import android.view.WindowManager; 46 import android.view.inputmethod.InputMethodManager; 47 import android.webkit.WebChromeClient; 48 import android.webkit.WebView; 49 import android.widget.FrameLayout; 50 import android.widget.ImageButton; 51 import android.widget.LinearLayout; 52 import android.widget.Toast; 53 54 import com.android.browser.Tab.SecurityState; 55 import com.android.internal.view.menu.MenuBuilder; 56 57 import java.util.List; 58 59 /** 60 * UI interface definitions 61 */ 62 public abstract class BaseUi implements UI { 63 64 private static final String LOGTAG = "BaseUi"; 65 66 protected static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = 67 new FrameLayout.LayoutParams( 68 ViewGroup.LayoutParams.MATCH_PARENT, 69 ViewGroup.LayoutParams.MATCH_PARENT); 70 71 protected static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER = 72 new FrameLayout.LayoutParams( 73 ViewGroup.LayoutParams.MATCH_PARENT, 74 ViewGroup.LayoutParams.MATCH_PARENT, 75 Gravity.CENTER); 76 77 private static final int MSG_HIDE_TITLEBAR = 1; 78 public static final int HIDE_TITLEBAR_DELAY = 1500; // in ms 79 80 Activity mActivity; 81 UiController mUiController; 82 TabControl mTabControl; 83 protected Tab mActiveTab; 84 private InputMethodManager mInputManager; 85 86 private Drawable mLockIconSecure; 87 private Drawable mLockIconMixed; 88 protected Drawable mGenericFavicon; 89 90 protected FrameLayout mContentView; 91 protected FrameLayout mCustomViewContainer; 92 protected FrameLayout mFullscreenContainer; 93 private FrameLayout mFixedTitlebarContainer; 94 95 private View mCustomView; 96 private WebChromeClient.CustomViewCallback mCustomViewCallback; 97 private int mOriginalOrientation; 98 99 private LinearLayout mErrorConsoleContainer = null; 100 101 private UrlBarAutoShowManager mUrlBarAutoShowManager; 102 103 private Toast mStopToast; 104 105 // the default <video> poster 106 private Bitmap mDefaultVideoPoster; 107 // the video progress view 108 private View mVideoProgressView; 109 110 private boolean mActivityPaused; 111 protected boolean mUseQuickControls; 112 protected TitleBar mTitleBar; 113 private NavigationBarBase mNavigationBar; 114 protected PieControl mPieControl; 115 private boolean mBlockFocusAnimations; 116 BaseUi(Activity browser, UiController controller)117 public BaseUi(Activity browser, UiController controller) { 118 mActivity = browser; 119 mUiController = controller; 120 mTabControl = controller.getTabControl(); 121 Resources res = mActivity.getResources(); 122 mInputManager = (InputMethodManager) 123 browser.getSystemService(Activity.INPUT_METHOD_SERVICE); 124 mLockIconSecure = res.getDrawable(R.drawable.ic_secure_holo_dark); 125 mLockIconMixed = res.getDrawable(R.drawable.ic_secure_partial_holo_dark); 126 FrameLayout frameLayout = (FrameLayout) mActivity.getWindow() 127 .getDecorView().findViewById(android.R.id.content); 128 LayoutInflater.from(mActivity) 129 .inflate(R.layout.custom_screen, frameLayout); 130 mFixedTitlebarContainer = (FrameLayout) frameLayout.findViewById( 131 R.id.fixed_titlebar_container); 132 mContentView = (FrameLayout) frameLayout.findViewById( 133 R.id.main_content); 134 mCustomViewContainer = (FrameLayout) frameLayout.findViewById( 135 R.id.fullscreen_custom_content); 136 mErrorConsoleContainer = (LinearLayout) frameLayout 137 .findViewById(R.id.error_console); 138 setFullscreen(BrowserSettings.getInstance().useFullscreen()); 139 mGenericFavicon = res.getDrawable( 140 R.drawable.app_web_browser_sm); 141 mTitleBar = new TitleBar(mActivity, mUiController, this, 142 mContentView); 143 mTitleBar.setProgress(100); 144 mNavigationBar = mTitleBar.getNavigationBar(); 145 mUrlBarAutoShowManager = new UrlBarAutoShowManager(this); 146 } 147 cancelStopToast()148 private void cancelStopToast() { 149 if (mStopToast != null) { 150 mStopToast.cancel(); 151 mStopToast = null; 152 } 153 } 154 155 // lifecycle 156 onPause()157 public void onPause() { 158 if (isCustomViewShowing()) { 159 onHideCustomView(); 160 } 161 cancelStopToast(); 162 mActivityPaused = true; 163 } 164 onResume()165 public void onResume() { 166 mActivityPaused = false; 167 // check if we exited without setting active tab 168 // b: 5188145 169 final Tab ct = mTabControl.getCurrentTab(); 170 if (ct != null) { 171 setActiveTab(ct); 172 } 173 mTitleBar.onResume(); 174 } 175 isActivityPaused()176 protected boolean isActivityPaused() { 177 return mActivityPaused; 178 } 179 onConfigurationChanged(Configuration config)180 public void onConfigurationChanged(Configuration config) { 181 } 182 getActivity()183 public Activity getActivity() { 184 return mActivity; 185 } 186 187 // key handling 188 189 @Override onBackKey()190 public boolean onBackKey() { 191 if (mCustomView != null) { 192 mUiController.hideCustomView(); 193 return true; 194 } 195 return false; 196 } 197 198 @Override onMenuKey()199 public boolean onMenuKey() { 200 return false; 201 } 202 203 @Override setUseQuickControls(boolean useQuickControls)204 public void setUseQuickControls(boolean useQuickControls) { 205 mUseQuickControls = useQuickControls; 206 mTitleBar.setUseQuickControls(mUseQuickControls); 207 if (useQuickControls) { 208 mPieControl = new PieControl(mActivity, mUiController, this); 209 mPieControl.attachToContainer(mContentView); 210 } else { 211 if (mPieControl != null) { 212 mPieControl.removeFromContainer(mContentView); 213 } 214 } 215 updateUrlBarAutoShowManagerTarget(); 216 } 217 218 // Tab callbacks 219 @Override onTabDataChanged(Tab tab)220 public void onTabDataChanged(Tab tab) { 221 setUrlTitle(tab); 222 setFavicon(tab); 223 updateLockIconToLatest(tab); 224 updateNavigationState(tab); 225 mTitleBar.onTabDataChanged(tab); 226 mNavigationBar.onTabDataChanged(tab); 227 onProgressChanged(tab); 228 } 229 230 @Override onProgressChanged(Tab tab)231 public void onProgressChanged(Tab tab) { 232 int progress = tab.getLoadProgress(); 233 if (tab.inForeground()) { 234 mTitleBar.setProgress(progress); 235 } 236 } 237 238 @Override bookmarkedStatusHasChanged(Tab tab)239 public void bookmarkedStatusHasChanged(Tab tab) { 240 if (tab.inForeground()) { 241 boolean isBookmark = tab.isBookmarkedSite(); 242 mNavigationBar.setCurrentUrlIsBookmark(isBookmark); 243 } 244 } 245 246 @Override onPageStopped(Tab tab)247 public void onPageStopped(Tab tab) { 248 cancelStopToast(); 249 if (tab.inForeground()) { 250 mStopToast = Toast 251 .makeText(mActivity, R.string.stopping, Toast.LENGTH_SHORT); 252 mStopToast.show(); 253 } 254 } 255 256 @Override needsRestoreAllTabs()257 public boolean needsRestoreAllTabs() { 258 return true; 259 } 260 261 @Override addTab(Tab tab)262 public void addTab(Tab tab) { 263 } 264 265 @Override setActiveTab(final Tab tab)266 public void setActiveTab(final Tab tab) { 267 if (tab == null) return; 268 // block unnecessary focus change animations during tab switch 269 mBlockFocusAnimations = true; 270 mHandler.removeMessages(MSG_HIDE_TITLEBAR); 271 if ((tab != mActiveTab) && (mActiveTab != null)) { 272 removeTabFromContentView(mActiveTab); 273 WebView web = mActiveTab.getWebView(); 274 if (web != null) { 275 web.setOnTouchListener(null); 276 } 277 } 278 mActiveTab = tab; 279 BrowserWebView web = (BrowserWebView) mActiveTab.getWebView(); 280 updateUrlBarAutoShowManagerTarget(); 281 attachTabToContentView(tab); 282 if (web != null) { 283 // Request focus on the top window. 284 if (mUseQuickControls) { 285 mPieControl.forceToTop(mContentView); 286 web.setTitleBar(null); 287 mTitleBar.hide(); 288 } else { 289 web.setTitleBar(mTitleBar); 290 mTitleBar.onScrollChanged(); 291 } 292 } 293 mTitleBar.bringToFront(); 294 tab.getTopWindow().requestFocus(); 295 setShouldShowErrorConsole(tab, mUiController.shouldShowErrorConsole()); 296 onTabDataChanged(tab); 297 onProgressChanged(tab); 298 mNavigationBar.setIncognitoMode(tab.isPrivateBrowsingEnabled()); 299 updateAutoLogin(tab, false); 300 mBlockFocusAnimations = false; 301 } 302 updateUrlBarAutoShowManagerTarget()303 protected void updateUrlBarAutoShowManagerTarget() { 304 WebView web = mActiveTab != null ? mActiveTab.getWebView() : null; 305 if (!mUseQuickControls && web instanceof BrowserWebView) { 306 mUrlBarAutoShowManager.setTarget((BrowserWebView) web); 307 } else { 308 mUrlBarAutoShowManager.setTarget(null); 309 } 310 } 311 getActiveTab()312 Tab getActiveTab() { 313 return mActiveTab; 314 } 315 316 @Override updateTabs(List<Tab> tabs)317 public void updateTabs(List<Tab> tabs) { 318 } 319 320 @Override removeTab(Tab tab)321 public void removeTab(Tab tab) { 322 if (mActiveTab == tab) { 323 removeTabFromContentView(tab); 324 mActiveTab = null; 325 } 326 } 327 328 @Override detachTab(Tab tab)329 public void detachTab(Tab tab) { 330 removeTabFromContentView(tab); 331 } 332 333 @Override attachTab(Tab tab)334 public void attachTab(Tab tab) { 335 attachTabToContentView(tab); 336 } 337 attachTabToContentView(Tab tab)338 protected void attachTabToContentView(Tab tab) { 339 if ((tab == null) || (tab.getWebView() == null)) { 340 return; 341 } 342 View container = tab.getViewContainer(); 343 WebView mainView = tab.getWebView(); 344 // Attach the WebView to the container and then attach the 345 // container to the content view. 346 FrameLayout wrapper = 347 (FrameLayout) container.findViewById(R.id.webview_wrapper); 348 ViewGroup parent = (ViewGroup) mainView.getParent(); 349 if (parent != wrapper) { 350 if (parent != null) { 351 parent.removeView(mainView); 352 } 353 wrapper.addView(mainView); 354 } 355 parent = (ViewGroup) container.getParent(); 356 if (parent != mContentView) { 357 if (parent != null) { 358 parent.removeView(container); 359 } 360 mContentView.addView(container, COVER_SCREEN_PARAMS); 361 } 362 mUiController.attachSubWindow(tab); 363 } 364 removeTabFromContentView(Tab tab)365 private void removeTabFromContentView(Tab tab) { 366 hideTitleBar(); 367 // Remove the container that contains the main WebView. 368 WebView mainView = tab.getWebView(); 369 View container = tab.getViewContainer(); 370 if (mainView == null) { 371 return; 372 } 373 // Remove the container from the content and then remove the 374 // WebView from the container. This will trigger a focus change 375 // needed by WebView. 376 FrameLayout wrapper = 377 (FrameLayout) container.findViewById(R.id.webview_wrapper); 378 wrapper.removeView(mainView); 379 mContentView.removeView(container); 380 mUiController.endActionMode(); 381 mUiController.removeSubWindow(tab); 382 ErrorConsoleView errorConsole = tab.getErrorConsole(false); 383 if (errorConsole != null) { 384 mErrorConsoleContainer.removeView(errorConsole); 385 } 386 } 387 388 @Override onSetWebView(Tab tab, WebView webView)389 public void onSetWebView(Tab tab, WebView webView) { 390 View container = tab.getViewContainer(); 391 if (container == null) { 392 // The tab consists of a container view, which contains the main 393 // WebView, as well as any other UI elements associated with the tab. 394 container = mActivity.getLayoutInflater().inflate(R.layout.tab, 395 mContentView, false); 396 tab.setViewContainer(container); 397 } 398 if (tab.getWebView() != webView) { 399 // Just remove the old one. 400 FrameLayout wrapper = 401 (FrameLayout) container.findViewById(R.id.webview_wrapper); 402 wrapper.removeView(tab.getWebView()); 403 } 404 } 405 406 /** 407 * create a sub window container and webview for the tab 408 * Note: this methods operates through side-effects for now 409 * it sets both the subView and subViewContainer for the given tab 410 * @param tab tab to create the sub window for 411 * @param subView webview to be set as a subwindow for the tab 412 */ 413 @Override createSubWindow(Tab tab, WebView subView)414 public void createSubWindow(Tab tab, WebView subView) { 415 View subViewContainer = mActivity.getLayoutInflater().inflate( 416 R.layout.browser_subwindow, null); 417 ViewGroup inner = (ViewGroup) subViewContainer 418 .findViewById(R.id.inner_container); 419 inner.addView(subView, new LayoutParams(LayoutParams.MATCH_PARENT, 420 LayoutParams.MATCH_PARENT)); 421 final ImageButton cancel = (ImageButton) subViewContainer 422 .findViewById(R.id.subwindow_close); 423 final WebView cancelSubView = subView; 424 cancel.setOnClickListener(new OnClickListener() { 425 @Override 426 public void onClick(View v) { 427 ((BrowserWebView) cancelSubView).getWebChromeClient().onCloseWindow(cancelSubView); 428 } 429 }); 430 tab.setSubWebView(subView); 431 tab.setSubViewContainer(subViewContainer); 432 } 433 434 /** 435 * Remove the sub window from the content view. 436 */ 437 @Override removeSubWindow(View subviewContainer)438 public void removeSubWindow(View subviewContainer) { 439 mContentView.removeView(subviewContainer); 440 mUiController.endActionMode(); 441 } 442 443 /** 444 * Attach the sub window to the content view. 445 */ 446 @Override attachSubWindow(View container)447 public void attachSubWindow(View container) { 448 if (container.getParent() != null) { 449 // already attached, remove first 450 ((ViewGroup) container.getParent()).removeView(container); 451 } 452 mContentView.addView(container, COVER_SCREEN_PARAMS); 453 } 454 refreshWebView()455 protected void refreshWebView() { 456 WebView web = getWebView(); 457 if (web != null) { 458 web.invalidate(); 459 } 460 } 461 editUrl(boolean clearInput, boolean forceIME)462 public void editUrl(boolean clearInput, boolean forceIME) { 463 if (mUiController.isInCustomActionMode()) { 464 mUiController.endActionMode(); 465 } 466 showTitleBar(); 467 if ((getActiveTab() != null) && !getActiveTab().isSnapshot()) { 468 mNavigationBar.startEditingUrl(clearInput, forceIME); 469 } 470 } 471 canShowTitleBar()472 boolean canShowTitleBar() { 473 return !isTitleBarShowing() 474 && !isActivityPaused() 475 && (getActiveTab() != null) 476 && (getWebView() != null) 477 && !mUiController.isInCustomActionMode(); 478 } 479 showTitleBar()480 protected void showTitleBar() { 481 mHandler.removeMessages(MSG_HIDE_TITLEBAR); 482 if (canShowTitleBar()) { 483 mTitleBar.show(); 484 } 485 } 486 hideTitleBar()487 protected void hideTitleBar() { 488 if (mTitleBar.isShowing()) { 489 mTitleBar.hide(); 490 } 491 } 492 isTitleBarShowing()493 protected boolean isTitleBarShowing() { 494 return mTitleBar.isShowing(); 495 } 496 isEditingUrl()497 public boolean isEditingUrl() { 498 return mTitleBar.isEditingUrl(); 499 } 500 stopEditingUrl()501 public void stopEditingUrl() { 502 mTitleBar.getNavigationBar().stopEditingUrl(); 503 } 504 getTitleBar()505 public TitleBar getTitleBar() { 506 return mTitleBar; 507 } 508 509 @Override showComboView(ComboViews startingView, Bundle extras)510 public void showComboView(ComboViews startingView, Bundle extras) { 511 Intent intent = new Intent(mActivity, ComboViewActivity.class); 512 intent.putExtra(ComboViewActivity.EXTRA_INITIAL_VIEW, startingView.name()); 513 intent.putExtra(ComboViewActivity.EXTRA_COMBO_ARGS, extras); 514 Tab t = getActiveTab(); 515 if (t != null) { 516 intent.putExtra(ComboViewActivity.EXTRA_CURRENT_URL, t.getUrl()); 517 } 518 mActivity.startActivityForResult(intent, Controller.COMBO_VIEW); 519 } 520 521 @Override showCustomView(View view, int requestedOrientation, WebChromeClient.CustomViewCallback callback)522 public void showCustomView(View view, int requestedOrientation, 523 WebChromeClient.CustomViewCallback callback) { 524 // if a view already exists then immediately terminate the new one 525 if (mCustomView != null) { 526 callback.onCustomViewHidden(); 527 return; 528 } 529 530 mOriginalOrientation = mActivity.getRequestedOrientation(); 531 FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView(); 532 mFullscreenContainer = new FullscreenHolder(mActivity); 533 mFullscreenContainer.addView(view, COVER_SCREEN_PARAMS); 534 decor.addView(mFullscreenContainer, COVER_SCREEN_PARAMS); 535 mCustomView = view; 536 setFullscreen(true); 537 ((BrowserWebView) getWebView()).setVisibility(View.INVISIBLE); 538 mCustomViewCallback = callback; 539 mActivity.setRequestedOrientation(requestedOrientation); 540 } 541 542 @Override onHideCustomView()543 public void onHideCustomView() { 544 ((BrowserWebView) getWebView()).setVisibility(View.VISIBLE); 545 if (mCustomView == null) 546 return; 547 setFullscreen(false); 548 FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView(); 549 decor.removeView(mFullscreenContainer); 550 mFullscreenContainer = null; 551 mCustomView = null; 552 mCustomViewCallback.onCustomViewHidden(); 553 // Show the content view. 554 mActivity.setRequestedOrientation(mOriginalOrientation); 555 } 556 557 @Override isCustomViewShowing()558 public boolean isCustomViewShowing() { 559 return mCustomView != null; 560 } 561 dismissIME()562 protected void dismissIME() { 563 if (mInputManager.isActive()) { 564 mInputManager.hideSoftInputFromWindow(mContentView.getWindowToken(), 565 0); 566 } 567 } 568 569 @Override isWebShowing()570 public boolean isWebShowing() { 571 return mCustomView == null; 572 } 573 574 @Override showAutoLogin(Tab tab)575 public void showAutoLogin(Tab tab) { 576 updateAutoLogin(tab, true); 577 } 578 579 @Override hideAutoLogin(Tab tab)580 public void hideAutoLogin(Tab tab) { 581 updateAutoLogin(tab, true); 582 } 583 584 // ------------------------------------------------------------------------- 585 updateNavigationState(Tab tab)586 protected void updateNavigationState(Tab tab) { 587 } 588 updateAutoLogin(Tab tab, boolean animate)589 protected void updateAutoLogin(Tab tab, boolean animate) { 590 mTitleBar.updateAutoLogin(tab, animate); 591 } 592 593 /** 594 * Update the lock icon to correspond to our latest state. 595 */ updateLockIconToLatest(Tab t)596 protected void updateLockIconToLatest(Tab t) { 597 if (t != null && t.inForeground()) { 598 updateLockIconImage(t.getSecurityState()); 599 } 600 } 601 602 /** 603 * Updates the lock-icon image in the title-bar. 604 */ updateLockIconImage(SecurityState securityState)605 private void updateLockIconImage(SecurityState securityState) { 606 Drawable d = null; 607 if (securityState == SecurityState.SECURITY_STATE_SECURE) { 608 d = mLockIconSecure; 609 } else if (securityState == SecurityState.SECURITY_STATE_MIXED 610 || securityState == SecurityState.SECURITY_STATE_BAD_CERTIFICATE) { 611 // TODO: It would be good to have different icons for insecure vs mixed content. 612 // See http://b/5403800 613 d = mLockIconMixed; 614 } 615 mNavigationBar.setLock(d); 616 } 617 setUrlTitle(Tab tab)618 protected void setUrlTitle(Tab tab) { 619 String url = tab.getUrl(); 620 String title = tab.getTitle(); 621 if (TextUtils.isEmpty(title)) { 622 title = url; 623 } 624 if (tab.inForeground()) { 625 mNavigationBar.setDisplayTitle(url); 626 } 627 } 628 629 // Set the favicon in the title bar. setFavicon(Tab tab)630 protected void setFavicon(Tab tab) { 631 if (tab.inForeground()) { 632 Bitmap icon = tab.getFavicon(); 633 mNavigationBar.setFavicon(icon); 634 } 635 } 636 637 @Override onActionModeFinished(boolean inLoad)638 public void onActionModeFinished(boolean inLoad) { 639 } 640 641 // active tabs page 642 showActiveTabsPage()643 public void showActiveTabsPage() { 644 } 645 646 /** 647 * Remove the active tabs page. 648 */ removeActiveTabsPage()649 public void removeActiveTabsPage() { 650 } 651 652 // menu handling callbacks 653 654 @Override onPrepareOptionsMenu(Menu menu)655 public boolean onPrepareOptionsMenu(Menu menu) { 656 return true; 657 } 658 659 @Override updateMenuState(Tab tab, Menu menu)660 public void updateMenuState(Tab tab, Menu menu) { 661 } 662 663 @Override onOptionsMenuOpened()664 public void onOptionsMenuOpened() { 665 } 666 667 @Override onExtendedMenuOpened()668 public void onExtendedMenuOpened() { 669 } 670 671 @Override onOptionsItemSelected(MenuItem item)672 public boolean onOptionsItemSelected(MenuItem item) { 673 return false; 674 } 675 676 @Override onOptionsMenuClosed(boolean inLoad)677 public void onOptionsMenuClosed(boolean inLoad) { 678 } 679 680 @Override onExtendedMenuClosed(boolean inLoad)681 public void onExtendedMenuClosed(boolean inLoad) { 682 } 683 684 @Override onContextMenuCreated(Menu menu)685 public void onContextMenuCreated(Menu menu) { 686 } 687 688 @Override onContextMenuClosed(Menu menu, boolean inLoad)689 public void onContextMenuClosed(Menu menu, boolean inLoad) { 690 } 691 692 // error console 693 694 @Override setShouldShowErrorConsole(Tab tab, boolean flag)695 public void setShouldShowErrorConsole(Tab tab, boolean flag) { 696 if (tab == null) return; 697 ErrorConsoleView errorConsole = tab.getErrorConsole(true); 698 if (flag) { 699 // Setting the show state of the console will cause it's the layout 700 // to be inflated. 701 if (errorConsole.numberOfErrors() > 0) { 702 errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED); 703 } else { 704 errorConsole.showConsole(ErrorConsoleView.SHOW_NONE); 705 } 706 if (errorConsole.getParent() != null) { 707 mErrorConsoleContainer.removeView(errorConsole); 708 } 709 // Now we can add it to the main view. 710 mErrorConsoleContainer.addView(errorConsole, 711 new LinearLayout.LayoutParams( 712 ViewGroup.LayoutParams.MATCH_PARENT, 713 ViewGroup.LayoutParams.WRAP_CONTENT)); 714 } else { 715 mErrorConsoleContainer.removeView(errorConsole); 716 } 717 } 718 719 // ------------------------------------------------------------------------- 720 // Helper function for WebChromeClient 721 // ------------------------------------------------------------------------- 722 723 @Override getDefaultVideoPoster()724 public Bitmap getDefaultVideoPoster() { 725 if (mDefaultVideoPoster == null) { 726 mDefaultVideoPoster = BitmapFactory.decodeResource( 727 mActivity.getResources(), R.drawable.default_video_poster); 728 } 729 return mDefaultVideoPoster; 730 } 731 732 @Override getVideoLoadingProgressView()733 public View getVideoLoadingProgressView() { 734 if (mVideoProgressView == null) { 735 LayoutInflater inflater = LayoutInflater.from(mActivity); 736 mVideoProgressView = inflater.inflate( 737 R.layout.video_loading_progress, null); 738 } 739 return mVideoProgressView; 740 } 741 742 @Override showMaxTabsWarning()743 public void showMaxTabsWarning() { 744 Toast warning = Toast.makeText(mActivity, 745 mActivity.getString(R.string.max_tabs_warning), 746 Toast.LENGTH_SHORT); 747 warning.show(); 748 } 749 getWebView()750 protected WebView getWebView() { 751 if (mActiveTab != null) { 752 return mActiveTab.getWebView(); 753 } else { 754 return null; 755 } 756 } 757 getMenu()758 protected Menu getMenu() { 759 MenuBuilder menu = new MenuBuilder(mActivity); 760 mActivity.getMenuInflater().inflate(R.menu.browser, menu); 761 return menu; 762 } 763 setFullscreen(boolean enabled)764 public void setFullscreen(boolean enabled) { 765 Window win = mActivity.getWindow(); 766 WindowManager.LayoutParams winParams = win.getAttributes(); 767 final int bits = WindowManager.LayoutParams.FLAG_FULLSCREEN; 768 if (enabled) { 769 winParams.flags |= bits; 770 } else { 771 winParams.flags &= ~bits; 772 if (mCustomView != null) { 773 mCustomView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 774 } else { 775 mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 776 } 777 } 778 win.setAttributes(winParams); 779 } 780 getFaviconDrawable(Bitmap icon)781 public Drawable getFaviconDrawable(Bitmap icon) { 782 Drawable[] array = new Drawable[3]; 783 array[0] = new PaintDrawable(Color.BLACK); 784 PaintDrawable p = new PaintDrawable(Color.WHITE); 785 array[1] = p; 786 if (icon == null) { 787 array[2] = mGenericFavicon; 788 } else { 789 array[2] = new BitmapDrawable(icon); 790 } 791 LayerDrawable d = new LayerDrawable(array); 792 d.setLayerInset(1, 1, 1, 1, 1); 793 d.setLayerInset(2, 2, 2, 2, 2); 794 return d; 795 } 796 isLoading()797 public boolean isLoading() { 798 return mActiveTab != null ? mActiveTab.inPageLoad() : false; 799 } 800 801 /** 802 * Suggest to the UI that the title bar can be hidden. The UI will then 803 * decide whether or not to hide based off a number of factors, such 804 * as if the user is editing the URL bar or if the page is loading 805 */ suggestHideTitleBar()806 public void suggestHideTitleBar() { 807 if (!isLoading() && !isEditingUrl() && !mTitleBar.wantsToBeVisible() 808 && !mNavigationBar.isMenuShowing()) { 809 hideTitleBar(); 810 } 811 } 812 showTitleBarForDuration()813 protected final void showTitleBarForDuration() { 814 showTitleBarForDuration(HIDE_TITLEBAR_DELAY); 815 } 816 showTitleBarForDuration(long duration)817 protected final void showTitleBarForDuration(long duration) { 818 showTitleBar(); 819 Message msg = Message.obtain(mHandler, MSG_HIDE_TITLEBAR); 820 mHandler.sendMessageDelayed(msg, duration); 821 } 822 823 protected Handler mHandler = new Handler() { 824 825 @Override 826 public void handleMessage(Message msg) { 827 if (msg.what == MSG_HIDE_TITLEBAR) { 828 suggestHideTitleBar(); 829 } 830 BaseUi.this.handleMessage(msg); 831 } 832 }; 833 handleMessage(Message msg)834 protected void handleMessage(Message msg) {} 835 836 @Override showWeb(boolean animate)837 public void showWeb(boolean animate) { 838 mUiController.hideCustomView(); 839 } 840 841 static class FullscreenHolder extends FrameLayout { 842 FullscreenHolder(Context ctx)843 public FullscreenHolder(Context ctx) { 844 super(ctx); 845 setBackgroundColor(ctx.getResources().getColor(R.color.black)); 846 } 847 848 @Override onTouchEvent(MotionEvent evt)849 public boolean onTouchEvent(MotionEvent evt) { 850 return true; 851 } 852 853 } 854 addFixedTitleBar(View view)855 public void addFixedTitleBar(View view) { 856 mFixedTitlebarContainer.addView(view); 857 } 858 setContentViewMarginTop(int margin)859 public void setContentViewMarginTop(int margin) { 860 LinearLayout.LayoutParams params = 861 (LinearLayout.LayoutParams) mContentView.getLayoutParams(); 862 if (params.topMargin != margin) { 863 params.topMargin = margin; 864 mContentView.setLayoutParams(params); 865 } 866 } 867 868 @Override blockFocusAnimations()869 public boolean blockFocusAnimations() { 870 return mBlockFocusAnimations; 871 } 872 873 @Override onVoiceResult(String result)874 public void onVoiceResult(String result) { 875 mNavigationBar.onVoiceResult(result); 876 } 877 878 } 879