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