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