blob: 70813e5865f6cd5195ea4cde4cd84a893e0199b6 [file] [log] [blame]
Michael Kolb8233fac2010-10-26 16:08:53 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
19import android.app.ActionBar;
20import android.app.Activity;
21import android.content.Context;
22import android.content.res.Configuration;
23import android.content.res.Resources;
24import android.graphics.Bitmap;
25import android.graphics.BitmapFactory;
26import android.graphics.PixelFormat;
27import android.graphics.drawable.Drawable;
28import android.os.Bundle;
29import android.text.TextUtils;
30import android.util.Log;
31import android.view.ActionMode;
32import android.view.Gravity;
33import android.view.LayoutInflater;
34import android.view.Menu;
35import android.view.MenuItem;
36import android.view.View;
Michael Kolb1514bb72010-11-22 09:11:48 -080037import android.view.View.OnClickListener;
Michael Kolb8233fac2010-10-26 16:08:53 -070038import android.view.ViewGroup;
Michael Kolb1514bb72010-11-22 09:11:48 -080039import android.view.ViewGroup.LayoutParams;
Michael Kolb8233fac2010-10-26 16:08:53 -070040import android.view.WindowManager;
Michael Kolb3a696282010-12-05 13:23:24 -080041import android.view.inputmethod.InputMethodManager;
Michael Kolb8233fac2010-10-26 16:08:53 -070042import android.webkit.WebChromeClient;
43import android.webkit.WebHistoryItem;
44import android.webkit.WebView;
45import android.widget.FrameLayout;
Michael Kolb1514bb72010-11-22 09:11:48 -080046import android.widget.ImageButton;
Michael Kolb8233fac2010-10-26 16:08:53 -070047import android.widget.LinearLayout;
48import android.widget.Toast;
49
Michael Kolb1bf23132010-11-19 12:55:12 -080050import java.util.List;
51
Michael Kolb8233fac2010-10-26 16:08:53 -070052/**
53 * UI interface definitions
54 */
55public class BaseUi implements UI, WebViewFactory {
56
57 private static final String LOGTAG = "BaseUi";
58
59 private static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
60 new FrameLayout.LayoutParams(
61 ViewGroup.LayoutParams.MATCH_PARENT,
62 ViewGroup.LayoutParams.MATCH_PARENT);
63
64 private static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
65 new FrameLayout.LayoutParams(
66 ViewGroup.LayoutParams.MATCH_PARENT,
67 ViewGroup.LayoutParams.MATCH_PARENT,
68 Gravity.CENTER);
69
70 Activity mActivity;
71 UiController mUiController;
72 TabControl mTabControl;
Michael Kolb77df4562010-11-19 14:49:34 -080073 private Tab mActiveTab;
Michael Kolb3a696282010-12-05 13:23:24 -080074 private InputMethodManager mInputManager;
Michael Kolb8233fac2010-10-26 16:08:53 -070075
76 private Drawable mSecLockIcon;
77 private Drawable mMixLockIcon;
78
79 private boolean mXLargeScreenSize;
80 private FrameLayout mBrowserFrameLayout;
81 private FrameLayout mContentView;
82 private FrameLayout mCustomViewContainer;
83 private TitleBarBase mTitleBar;
84 private TitleBarBase mFakeTitleBar;
85 private TabBar mTabBar;
86
87 private View mCustomView;
88 private WebChromeClient.CustomViewCallback mCustomViewCallback;
89
90 private CombinedBookmarkHistoryView mComboView;
91
92 private LinearLayout mErrorConsoleContainer = null;
93
94 private Toast mStopToast;
95 private ActiveTabsPage mActiveTabsPage;
96
97 // the default <video> poster
98 private Bitmap mDefaultVideoPoster;
99 // the video progress view
100 private View mVideoProgressView;
101
102 boolean mExtendedMenuOpen;
103 boolean mOptionsMenuOpen;
104
105 private boolean mActivityPaused;
106
107 public BaseUi(Activity browser, UiController controller) {
108 mActivity = browser;
109 mUiController = controller;
110 mTabControl = controller.getTabControl();
111 Resources res = mActivity.getResources();
Michael Kolb3a696282010-12-05 13:23:24 -0800112 mInputManager = (InputMethodManager)
113 browser.getSystemService(Activity.INPUT_METHOD_SERVICE);
Michael Kolb8233fac2010-10-26 16:08:53 -0700114 mSecLockIcon = res.getDrawable(R.drawable.ic_secure);
115 mMixLockIcon = res.getDrawable(R.drawable.ic_partial_secure);
116
117
118 mXLargeScreenSize = (res.getConfiguration().screenLayout
119 & Configuration.SCREENLAYOUT_SIZE_MASK)
120 == Configuration.SCREENLAYOUT_SIZE_XLARGE;
121
122 FrameLayout frameLayout = (FrameLayout) mActivity.getWindow()
123 .getDecorView().findViewById(android.R.id.content);
124 mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(mActivity)
125 .inflate(R.layout.custom_screen, null);
126 mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
127 R.id.main_content);
128 mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
129 .findViewById(R.id.error_console);
130 mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
131 .findViewById(R.id.fullscreen_custom_content);
132 frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
133
134 if (mXLargeScreenSize) {
Michael Kolb81b6f832010-12-12 12:44:27 -0800135 mTitleBar = new TitleBarXLarge(mActivity, mUiController, this);
Michael Kolb8233fac2010-10-26 16:08:53 -0700136 mTitleBar.setProgress(100);
Michael Kolb81b6f832010-12-12 12:44:27 -0800137 mFakeTitleBar = new TitleBarXLarge(mActivity, mUiController, this);
Michael Kolb8233fac2010-10-26 16:08:53 -0700138 ActionBar actionBar = mActivity.getActionBar();
139 mTabBar = new TabBar(mActivity, mUiController, this);
140 actionBar.setCustomNavigationMode(mTabBar);
141 } else {
142 mTitleBar = new TitleBar(mActivity, mUiController);
143 // mTitleBar will be always be shown in the fully loaded mode on
144 // phone
145 mTitleBar.setProgress(100);
146 mFakeTitleBar = new TitleBar(mActivity, mUiController);
147 }
148 }
149
150 // webview factory
151
152 @Override
153 public WebView createWebView(boolean privateBrowsing) {
154 // Create a new WebView
155 ScrollWebView w = new ScrollWebView(mActivity, null,
156 android.R.attr.webViewStyle, privateBrowsing);
157 w.setScrollbarFadingEnabled(true);
158 w.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
159 w.setMapTrackballToArrowKeys(false); // use trackball directly
160 // Enable the built-in zoom
161 w.getSettings().setBuiltInZoomControls(true);
162 if (mXLargeScreenSize) {
163 w.setScrollListener(mTabBar);
164 w.getSettings().setDisplayZoomControls(false);
165 }
166
167 // Add this WebView to the settings observer list and update the
168 // settings
169 final BrowserSettings s = BrowserSettings.getInstance();
170 s.addObserver(w.getSettings()).update(s, null);
171 return w;
172 }
173
Michael Kolb1514bb72010-11-22 09:11:48 -0800174 @Override
175 public WebView createSubWebView(boolean privateBrowsing) {
176 ScrollWebView web = (ScrollWebView) createWebView(privateBrowsing);
177 if (mXLargeScreenSize) {
178 // no scroll listener for subview
179 web.setScrollListener(null);
180 }
181 return web;
182 }
183
Michael Kolb8233fac2010-10-26 16:08:53 -0700184 void stopWebViewScrolling() {
185 ScrollWebView web = (ScrollWebView) mUiController.getCurrentWebView();
186 if (web != null) {
187 web.stopScroll();
188 }
189 }
190
191 private void cancelStopToast() {
192 if (mStopToast != null) {
193 mStopToast.cancel();
194 mStopToast = null;
195 }
196 }
197
198 // lifecycle
199
200 public void onPause() {
201 // FIXME: This removes the active tabs page and resets the menu to
202 // MAIN_MENU. A better solution might be to do this work in onNewIntent
203 // but then we would need to save it in onSaveInstanceState and restore
204 // it in onCreate/onRestoreInstanceState
205 if (mActiveTabsPage != null) {
206 mUiController.removeActiveTabsPage(true);
207 }
Michael Kolb7a5cf472010-11-30 13:23:53 -0800208 if (isCustomViewShowing()) {
209 onHideCustomView();
210 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700211 cancelStopToast();
212 mActivityPaused = true;
213 }
214
215 public void onResume() {
216 mActivityPaused = false;
217 }
218
219 public void onDestroy() {
220 hideFakeTitleBar();
221 }
222
223 public void onConfigurationChanged(Configuration config) {
224 }
225
226 // key handling
227
228 @Override
229 public boolean onBackKey() {
230 if (mActiveTabsPage != null) {
231 // if tab page is showing, hide it
232 mUiController.removeActiveTabsPage(true);
233 return true;
234 }
235 if (mComboView != null) {
236 if (!mComboView.onBackPressed()) {
237 mUiController.removeComboView();
238 }
239 return true;
240 }
241 if (mCustomView != null) {
242 mUiController.hideCustomView();
243 return true;
244 }
245 return false;
246 }
247
248 // WebView callbacks
249
250 @Override
251 public void onPageStarted(Tab tab, String url, Bitmap favicon) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700252 if (tab.inForeground()) {
253 resetLockIcon(tab, url);
254 setUrlTitle(tab, url, null);
255 setFavicon(tab, favicon);
256 }
John Reckef074262010-12-02 16:09:14 -0800257 if (mXLargeScreenSize) {
258 mTabBar.onPageStarted(tab, url, favicon);
259 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700260 }
261
262 @Override
Leon Scroggins4cd97792010-12-03 15:31:56 -0500263 public void bookmarkedStatusHasChanged(Tab tab) {
264 if (tab.inForeground() && mXLargeScreenSize) {
265 boolean isBookmark = tab.isBookmarkedSite();
266 ((TitleBarXLarge) mTitleBar).setCurrentUrlIsBookmark(isBookmark);
267 ((TitleBarXLarge) mFakeTitleBar).setCurrentUrlIsBookmark(isBookmark);
268 }
269 }
270
271 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700272 public void onPageFinished(Tab tab, String url) {
273 if (mXLargeScreenSize) {
274 mTabBar.onPageFinished(tab);
275 }
276 if (tab.inForeground()) {
277 // Reset the title and icon in case we stopped a provisional load.
278 resetTitleAndIcon(tab);
279 // Update the lock icon image only once we are done loading
280 updateLockIconToLatest(tab);
281 }
282 }
283
284 @Override
285 public void onPageStopped(Tab tab) {
286 cancelStopToast();
287 if (tab.inForeground()) {
288 mStopToast = Toast
289 .makeText(mActivity, R.string.stopping, Toast.LENGTH_SHORT);
290 mStopToast.show();
291 }
292 }
293
294 @Override
295 public void onProgressChanged(Tab tab, int progress) {
296 if (mXLargeScreenSize) {
297 mTabBar.onProgress(tab, progress);
298 }
299 if (tab.inForeground()) {
300 mFakeTitleBar.setProgress(progress);
301 if (progress == 100) {
302 if (!mOptionsMenuOpen || !mExtendedMenuOpen) {
303 hideFakeTitleBar();
304 }
305 } else {
306 if (!mOptionsMenuOpen || mExtendedMenuOpen) {
307 showFakeTitleBar();
308 }
309 }
310 }
311 }
312
313 @Override
Michael Kolb1bf23132010-11-19 12:55:12 -0800314 public boolean needsRestoreAllTabs() {
315 return mXLargeScreenSize;
316 }
317
318 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700319 public void addTab(Tab tab) {
320 if (mXLargeScreenSize) {
321 mTabBar.onNewTab(tab);
322 }
323 }
324
325 @Override
326 public void setActiveTab(Tab tab) {
Michael Kolb77df4562010-11-19 14:49:34 -0800327 if ((tab != mActiveTab) && (mActiveTab != null)) {
328 removeTabFromContentView(mActiveTab);
Michael Kolb8233fac2010-10-26 16:08:53 -0700329 }
Michael Kolb77df4562010-11-19 14:49:34 -0800330 mActiveTab = tab;
Michael Kolb8233fac2010-10-26 16:08:53 -0700331 attachTabToContentView(tab);
332 setShouldShowErrorConsole(tab, mUiController.shouldShowErrorConsole());
333
334 WebView view = tab.getWebView();
Michael Kolb77df4562010-11-19 14:49:34 -0800335 // TabControl.setCurrentTab has been called before this,
336 // so the tab is guaranteed to have a webview
337 if (view == null) {
338 Log.e(LOGTAG, "active tab with no webview detected");
339 return;
340 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700341 view.setEmbeddedTitleBar(mTitleBar);
342 if (tab.isInVoiceSearchMode()) {
343 showVoiceTitleBar(tab.getVoiceDisplayTitle());
344 } else {
345 revertVoiceTitleBar(tab);
346 }
347
348 if (mXLargeScreenSize) {
349 // Request focus on the top window.
350 mTabBar.onSetActiveTab(tab);
351 }
352 resetTitleIconAndProgress(tab);
353 updateLockIconToLatest(tab);
354 tab.getTopWindow().requestFocus();
355 }
356
357 @Override
Michael Kolb1bf23132010-11-19 12:55:12 -0800358 public void updateTabs(List<Tab> tabs) {
359 if (mXLargeScreenSize) {
360 mTabBar.updateTabs(tabs);
361 }
362 }
363
364 @Override
Michael Kolb8233fac2010-10-26 16:08:53 -0700365 public void removeTab(Tab tab) {
Michael Kolb77df4562010-11-19 14:49:34 -0800366 if (mActiveTab == tab) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700367 removeTabFromContentView(tab);
Michael Kolb77df4562010-11-19 14:49:34 -0800368 mActiveTab = null;
Michael Kolb8233fac2010-10-26 16:08:53 -0700369 }
370 if (mXLargeScreenSize) {
371 mTabBar.onRemoveTab(tab);
372 }
373 }
374
375 @Override
376 public void detachTab(Tab tab) {
377 removeTabFromContentView(tab);
378 }
379
380 @Override
381 public void attachTab(Tab tab) {
382 attachTabToContentView(tab);
383 }
384
385 private void attachTabToContentView(Tab tab) {
386 if (tab.getWebView() == null) {
387 return;
388 }
389 View container = tab.getViewContainer();
390 WebView mainView = tab.getWebView();
391 // Attach the WebView to the container and then attach the
392 // container to the content view.
393 FrameLayout wrapper =
394 (FrameLayout) container.findViewById(R.id.webview_wrapper);
395 ViewGroup parent = (ViewGroup) mainView.getParent();
396 if (parent != wrapper) {
397 if (parent != null) {
398 Log.w(LOGTAG, "mMainView already has a parent in"
399 + " attachTabToContentView!");
400 parent.removeView(mainView);
401 }
402 wrapper.addView(mainView);
403 } else {
404 Log.w(LOGTAG, "mMainView is already attached to wrapper in"
405 + " attachTabToContentView!");
406 }
407 parent = (ViewGroup) container.getParent();
408 if (parent != mContentView) {
409 if (parent != null) {
410 Log.w(LOGTAG, "mContainer already has a parent in"
411 + " attachTabToContentView!");
412 parent.removeView(container);
413 }
414 mContentView.addView(container, COVER_SCREEN_PARAMS);
415 } else {
416 Log.w(LOGTAG, "mContainer is already attached to content in"
417 + " attachTabToContentView!");
418 }
419 mUiController.attachSubWindow(tab);
420 }
421
422 private void removeTabFromContentView(Tab tab) {
423 // Remove the container that contains the main WebView.
424 WebView mainView = tab.getWebView();
425 View container = tab.getViewContainer();
426 if (mainView == null) {
427 return;
428 }
429 // Remove the container from the content and then remove the
430 // WebView from the container. This will trigger a focus change
431 // needed by WebView.
432 FrameLayout wrapper =
433 (FrameLayout) container.findViewById(R.id.webview_wrapper);
434 wrapper.removeView(mainView);
435 mContentView.removeView(container);
436 mUiController.endActionMode();
437 mUiController.removeSubWindow(tab);
438 ErrorConsoleView errorConsole = tab.getErrorConsole(false);
439 if (errorConsole != null) {
440 mErrorConsoleContainer.removeView(errorConsole);
441 }
442 mainView.setEmbeddedTitleBar(null);
443 }
444
Michael Kolba713ec82010-11-29 17:27:06 -0800445 @Override
446 public void onSetWebView(Tab tab, WebView webView) {
447 View container = tab.getViewContainer();
448 if (container == null) {
449 // The tab consists of a container view, which contains the main
450 // WebView, as well as any other UI elements associated with the tab.
451 container = mActivity.getLayoutInflater().inflate(R.layout.tab,
452 null);
453 tab.setViewContainer(container);
454 }
455 if (tab.getWebView() != webView) {
456 // Just remove the old one.
457 FrameLayout wrapper =
458 (FrameLayout) container.findViewById(R.id.webview_wrapper);
459 wrapper.removeView(tab.getWebView());
460 }
461 }
462
Michael Kolb8233fac2010-10-26 16:08:53 -0700463 /**
Michael Kolb1514bb72010-11-22 09:11:48 -0800464 * create a sub window container and webview for the tab
465 * Note: this methods operates through side-effects for now
466 * it sets both the subView and subViewContainer for the given tab
467 * @param tab tab to create the sub window for
468 * @param subView webview to be set as a subwindow for the tab
469 */
470 @Override
471 public void createSubWindow(Tab tab, WebView subView) {
472 View subViewContainer = mActivity.getLayoutInflater().inflate(
473 R.layout.browser_subwindow, null);
474 ViewGroup inner = (ViewGroup) subViewContainer
475 .findViewById(R.id.inner_container);
476 inner.addView(subView, new LayoutParams(LayoutParams.MATCH_PARENT,
477 LayoutParams.MATCH_PARENT));
478 final ImageButton cancel = (ImageButton) subViewContainer
479 .findViewById(R.id.subwindow_close);
480 final WebView cancelSubView = subView;
481 cancel.setOnClickListener(new OnClickListener() {
482 public void onClick(View v) {
483 cancelSubView.getWebChromeClient().onCloseWindow(cancelSubView);
484 }
485 });
486 tab.setSubWebView(subView);
487 tab.setSubViewContainer(subViewContainer);
488 }
489
490 /**
Michael Kolb8233fac2010-10-26 16:08:53 -0700491 * Remove the sub window from the content view.
492 */
493 @Override
494 public void removeSubWindow(View subviewContainer) {
495 mContentView.removeView(subviewContainer);
496 mUiController.endActionMode();
497 }
498
499 /**
500 * Attach the sub window to the content view.
501 */
502 @Override
503 public void attachSubWindow(View container) {
Michael Kolb1514bb72010-11-22 09:11:48 -0800504 if (container.getParent() != null) {
505 // already attached, remove first
506 ((ViewGroup) container.getParent()).removeView(container);
507 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700508 mContentView.addView(container, COVER_SCREEN_PARAMS);
509 }
510
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800511 int getTitleBarWidth() {
512 if (mTitleBar != null) {
513 return mTitleBar.getWidth();
514 }
515 return 0;
516 }
517
Michael Kolb81b6f832010-12-12 12:44:27 -0800518 void editUrl(boolean clearInput) {
519 showFakeTitleBar();
520 ((TitleBarXLarge) mFakeTitleBar).onEditUrl(clearInput);
521 }
522
Michael Kolb8233fac2010-10-26 16:08:53 -0700523 void showFakeTitleBar() {
524 if (!isFakeTitleBarShowing() && mActiveTabsPage == null &&
525 !mActivityPaused) {
526 WebView mainView = mUiController.getCurrentWebView();
527 // if there is no current WebView, don't show the faked title bar;
528 if (mainView == null) {
529 return;
530 }
531 // Do not need to check for null, since the current tab will have
532 // at least a main WebView, or we would have returned above.
533 if (mUiController.isInCustomActionMode()) {
534 // Do not show the fake title bar, while a custom ActionMode
535 // (i.e. find or select) is showing.
536 return;
537 }
538 if (mXLargeScreenSize) {
539 mContentView.addView(mFakeTitleBar);
540 mTabBar.onShowTitleBar();
541 } else {
542 WindowManager manager = (WindowManager)
543 mActivity.getSystemService(Context.WINDOW_SERVICE);
544
545 // Add the title bar to the window manager so it can receive
546 // touches
547 // while the menu is up
548 WindowManager.LayoutParams params =
549 new WindowManager.LayoutParams(
550 ViewGroup.LayoutParams.MATCH_PARENT,
551 ViewGroup.LayoutParams.WRAP_CONTENT,
552 WindowManager.LayoutParams.TYPE_APPLICATION,
553 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
554 PixelFormat.TRANSLUCENT);
555 params.gravity = Gravity.TOP;
556 boolean atTop = mainView.getScrollY() == 0;
557 params.windowAnimations = atTop ? 0 : R.style.TitleBar;
558 manager.addView(mFakeTitleBar, params);
559 }
560 }
561 }
562
563 void hideFakeTitleBar() {
564 if (!isFakeTitleBarShowing()) return;
565 if (mXLargeScreenSize) {
566 mContentView.removeView(mFakeTitleBar);
567 mTabBar.onHideTitleBar();
568 } else {
569 WindowManager.LayoutParams params =
570 (WindowManager.LayoutParams) mFakeTitleBar.getLayoutParams();
571 WebView mainView = mUiController.getCurrentWebView();
572 // Although we decided whether or not to animate based on the
573 // current
574 // scroll position, the scroll position may have changed since the
575 // fake title bar was displayed. Make sure it has the appropriate
576 // animation/lack thereof before removing.
577 params.windowAnimations =
578 mainView != null && mainView.getScrollY() == 0 ?
579 0 : R.style.TitleBar;
580 WindowManager manager = (WindowManager) mActivity
581 .getSystemService(Context.WINDOW_SERVICE);
582 manager.updateViewLayout(mFakeTitleBar, params);
583 manager.removeView(mFakeTitleBar);
584 }
585 }
586
587 boolean isFakeTitleBarShowing() {
588 return (mFakeTitleBar.getParent() != null);
589 }
590
591 @Override
592 public void showComboView(boolean startWithHistory, Bundle extras) {
593 mComboView = new CombinedBookmarkHistoryView(mActivity,
594 mUiController,
595 startWithHistory ?
596 CombinedBookmarkHistoryView.FRAGMENT_ID_HISTORY
597 : CombinedBookmarkHistoryView.FRAGMENT_ID_BOOKMARKS,
598 extras);
599 mTitleBar.setVisibility(View.GONE);
600 hideFakeTitleBar();
Michael Kolb3a696282010-12-05 13:23:24 -0800601 dismissIME();
602 if (mActiveTab != null) {
603 WebView web = mActiveTab.getWebView();
604 mActiveTab.putInBackground();
605 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700606 mContentView.addView(mComboView, COVER_SCREEN_PARAMS);
607 }
608
609 /**
610 * dismiss the ComboPage
611 */
612 @Override
613 public void hideComboView() {
614 if (mComboView != null) {
615 mContentView.removeView(mComboView);
616 mTitleBar.setVisibility(View.VISIBLE);
617 mComboView = null;
618 }
Michael Kolb3a696282010-12-05 13:23:24 -0800619 if (mActiveTab != null) {
620 mActiveTab.putInForeground();
621 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700622 }
623
624 @Override
625 public void showCustomView(View view,
626 WebChromeClient.CustomViewCallback callback) {
627 // if a view already exists then immediately terminate the new one
628 if (mCustomView != null) {
629 callback.onCustomViewHidden();
630 return;
631 }
632
633 // Add the custom view to its container.
634 mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
635 mCustomView = view;
636 mCustomViewCallback = callback;
637 // Hide the content view.
638 mContentView.setVisibility(View.GONE);
639 // Finally show the custom view container.
640 setStatusBarVisibility(false);
641 mCustomViewContainer.setVisibility(View.VISIBLE);
642 mCustomViewContainer.bringToFront();
643 }
644
645 @Override
646 public void onHideCustomView() {
647 if (mCustomView == null)
648 return;
649
650 // Hide the custom view.
651 mCustomView.setVisibility(View.GONE);
652 // Remove the custom view from its container.
653 mCustomViewContainer.removeView(mCustomView);
654 mCustomView = null;
655 mCustomViewContainer.setVisibility(View.GONE);
656 mCustomViewCallback.onCustomViewHidden();
657 // Show the content view.
658 setStatusBarVisibility(true);
659 mContentView.setVisibility(View.VISIBLE);
660 }
661
662 @Override
663 public boolean isCustomViewShowing() {
664 return mCustomView != null;
665 }
666
667 @Override
668 public void showVoiceTitleBar(String title) {
669 mTitleBar.setInVoiceMode(true);
670 mTitleBar.setDisplayTitle(title);
671 mFakeTitleBar.setInVoiceMode(true);
672 mFakeTitleBar.setDisplayTitle(title);
673 }
674
675 @Override
676 public void revertVoiceTitleBar(Tab tab) {
677 mTitleBar.setInVoiceMode(false);
678 String url = tab.getCurrentUrl();
679 mTitleBar.setDisplayTitle(url);
680 mFakeTitleBar.setInVoiceMode(false);
681 mFakeTitleBar.setDisplayTitle(url);
682 }
683
Michael Kolb3a696282010-12-05 13:23:24 -0800684 private void dismissIME() {
685 if (mInputManager.isActive()) {
686 mInputManager.hideSoftInputFromWindow(mContentView.getWindowToken(),
687 0);
688 }
689 }
690
Michael Kolb8233fac2010-10-26 16:08:53 -0700691 // -------------------------------------------------------------------------
692
693 @Override
694 public void resetTitleAndRevertLockIcon(Tab tab) {
695 tab.revertLockIcon();
696 updateLockIconToLatest(tab);
697 resetTitleIconAndProgress(tab);
698 }
699
700 /**
701 * Resets the lock icon. This method is called when we start a new load and
702 * know the url to be loaded.
703 */
704 private void resetLockIcon(Tab tab, String url) {
705 // Save the lock-icon state (we revert to it if the load gets cancelled)
706 tab.resetLockIcon(url);
707 updateLockIconImage(Tab.LOCK_ICON_UNSECURE);
708 }
709
710 /**
711 * Update the lock icon to correspond to our latest state.
712 */
713 private void updateLockIconToLatest(Tab t) {
714 if (t != null) {
715 updateLockIconImage(t.getLockIconType());
716 }
717 }
718
719 /**
720 * Reset the title, favicon, and progress.
721 */
722 private void resetTitleIconAndProgress(Tab tab) {
723 WebView current = tab.getWebView();
724 if (current == null) {
725 return;
726 }
Michael Kolb41d3b942010-12-05 11:35:20 -0800727 resetTitleAndIcon(tab, current);
Michael Kolb8233fac2010-10-26 16:08:53 -0700728 int progress = current.getProgress();
729 current.getWebChromeClient().onProgressChanged(current, progress);
730 }
731
732 @Override
733 public void resetTitleAndIcon(Tab tab) {
734 WebView current = tab.getWebView();
735 if (current != null) {
Michael Kolb41d3b942010-12-05 11:35:20 -0800736 resetTitleAndIcon(tab, current);
Michael Kolb8233fac2010-10-26 16:08:53 -0700737 }
738 }
739
740 // Reset the title and the icon based on the given item.
Michael Kolb41d3b942010-12-05 11:35:20 -0800741 private void resetTitleAndIcon(Tab tab, WebView view) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700742 WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
Michael Kolb8233fac2010-10-26 16:08:53 -0700743 if (item != null) {
744 setUrlTitle(tab, item.getUrl(), item.getTitle());
745 setFavicon(tab, item.getFavicon());
746 } else {
John Reckef074262010-12-02 16:09:14 -0800747 setUrlTitle(tab, null, mActivity.getString(R.string.new_tab));
Michael Kolb8233fac2010-10-26 16:08:53 -0700748 setFavicon(tab, null);
749 }
750 }
751
752 /**
753 * Updates the lock-icon image in the title-bar.
754 */
755 private void updateLockIconImage(int lockIconType) {
756 Drawable d = null;
757 if (lockIconType == Tab.LOCK_ICON_SECURE) {
758 d = mSecLockIcon;
759 } else if (lockIconType == Tab.LOCK_ICON_MIXED) {
760 d = mMixLockIcon;
761 }
762 mTitleBar.setLock(d);
763 mFakeTitleBar.setLock(d);
764 }
765
766 // active tabs page
767
768 public void showActiveTabsPage() {
769 mActiveTabsPage = new ActiveTabsPage(mActivity, mUiController);
770 mTitleBar.setVisibility(View.GONE);
771 hideFakeTitleBar();
772 mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
773 mActiveTabsPage.requestFocus();
774 }
775
776 /**
777 * Remove the active tabs page.
Michael Kolb8233fac2010-10-26 16:08:53 -0700778 */
779 public void removeActiveTabsPage() {
780 mContentView.removeView(mActiveTabsPage);
781 mTitleBar.setVisibility(View.VISIBLE);
782 mActiveTabsPage = null;
783 }
784
785 // action mode callbacks
786
787 @Override
788 public void onActionModeStarted(ActionMode mode) {
Michael Kolb81b6f832010-12-12 12:44:27 -0800789 if (!mXLargeScreenSize
790 || !((TitleBarXLarge) mFakeTitleBar).isEditingUrl()) {
791 // hide the fake title bar when CAB is shown
792 hideFakeTitleBar();
793 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700794 }
795
796 @Override
797 public void onActionModeFinished(boolean inLoad) {
798 if (inLoad) {
799 // the titlebar was removed when the CAB was shown
800 // if the page is loading, show it again
801 showFakeTitleBar();
802 }
803 }
804
805 // menu handling callbacks
806
807 @Override
808 public void onOptionsMenuOpened() {
809 mOptionsMenuOpen = true;
810 // options menu opened, show fake title bar
811 showFakeTitleBar();
812 }
813
814 @Override
815 public void onExtendedMenuOpened() {
816 // Switching the menu to expanded view, so hide the
817 // title bar.
818 mExtendedMenuOpen = true;
819 hideFakeTitleBar();
820 }
821
822 @Override
823 public void onOptionsMenuClosed(boolean inLoad) {
824 mOptionsMenuOpen = false;
825 if (!inLoad) {
826 hideFakeTitleBar();
827 }
828 }
829
830 @Override
831 public void onExtendedMenuClosed(boolean inLoad) {
832 mExtendedMenuOpen = false;
833 if (inLoad) {
834 showFakeTitleBar();
835 }
836 }
837
838 @Override
839 public void onContextMenuCreated(Menu menu) {
840 hideFakeTitleBar();
841 }
842
843 @Override
844 public void onContextMenuClosed(Menu menu, boolean inLoad) {
845 if (inLoad) {
846 showFakeTitleBar();
847 }
848 }
849
850 @Override
851 public void onScroll(boolean titleVisible) {
852 if (mTabBar != null) {
853 mTabBar.onScroll(titleVisible);
854 }
855 }
856
857 // error console
858
859 @Override
860 public void setShouldShowErrorConsole(Tab tab, boolean flag) {
861 ErrorConsoleView errorConsole = tab.getErrorConsole(true);
862 if (flag) {
863 // Setting the show state of the console will cause it's the layout
864 // to be inflated.
865 if (errorConsole.numberOfErrors() > 0) {
866 errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
867 } else {
868 errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
869 }
870 if (errorConsole.getParent() != null) {
871 mErrorConsoleContainer.removeView(errorConsole);
872 }
873 // Now we can add it to the main view.
874 mErrorConsoleContainer.addView(errorConsole,
875 new LinearLayout.LayoutParams(
876 ViewGroup.LayoutParams.MATCH_PARENT,
877 ViewGroup.LayoutParams.WRAP_CONTENT));
878 } else {
879 mErrorConsoleContainer.removeView(errorConsole);
880 }
881 }
882
883 private void setStatusBarVisibility(boolean visible) {
884 int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
885 mActivity.getWindow().setFlags(flag,
886 WindowManager.LayoutParams.FLAG_FULLSCREEN);
887 }
888
889 @Override
890 public void setUrlTitle(Tab tab, String url, String title) {
891 if (TextUtils.isEmpty(title)) {
John Reckef074262010-12-02 16:09:14 -0800892 title = url;
Michael Kolb8233fac2010-10-26 16:08:53 -0700893 }
894 if (tab.isInVoiceSearchMode()) return;
895 if (tab.inForeground()) {
896 mTitleBar.setDisplayTitle(url);
897 mFakeTitleBar.setDisplayTitle(url);
898 }
899 if (mXLargeScreenSize) {
900 mTabBar.onUrlAndTitle(tab, url, title);
901 }
902 }
903
904 // Set the favicon in the title bar.
905 @Override
906 public void setFavicon(Tab tab, Bitmap icon) {
907 mTitleBar.setFavicon(icon);
908 mFakeTitleBar.setFavicon(icon);
909 if (mXLargeScreenSize) {
910 mTabBar.onFavicon(tab, icon);
911 }
912 }
913 @Override
914 public boolean showsWeb() {
915 return mCustomView == null && mActiveTabsPage == null
916 && mComboView == null;
917 }
918
919 @Override
920 public void onPrepareOptionsMenu(Menu menu) {
921 if (!mXLargeScreenSize) {
922 final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
923 newtab.setEnabled(mUiController.getTabControl().canCreateNewTab());
924 }
925 }
926
927 // -------------------------------------------------------------------------
928 // Helper function for WebChromeClient
929 // -------------------------------------------------------------------------
930
931 @Override
932 public Bitmap getDefaultVideoPoster() {
933 if (mDefaultVideoPoster == null) {
934 mDefaultVideoPoster = BitmapFactory.decodeResource(
935 mActivity.getResources(), R.drawable.default_video_poster);
936 }
937 return mDefaultVideoPoster;
938 }
939
940 @Override
941 public View getVideoLoadingProgressView() {
942 if (mVideoProgressView == null) {
943 LayoutInflater inflater = LayoutInflater.from(mActivity);
944 mVideoProgressView = inflater.inflate(
945 R.layout.video_loading_progress, null);
946 }
947 return mVideoProgressView;
948 }
949
Michael Kolb843510f2010-12-09 10:51:49 -0800950 @Override
951 public void showMaxTabsWarning() {
952 Toast warning = Toast.makeText(mActivity,
953 mActivity.getString(R.string.max_tabs_warning),
954 Toast.LENGTH_SHORT);
955 warning.show();
956 }
957
Michael Kolb8233fac2010-10-26 16:08:53 -0700958}