OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.tab; | 5 package org.chromium.chrome.browser.tab; |
6 | 6 |
7 import android.annotation.TargetApi; | |
8 import android.app.Activity; | 7 import android.app.Activity; |
9 import android.app.ActivityManager; | |
10 import android.content.Context; | 8 import android.content.Context; |
11 import android.content.Intent; | 9 import android.content.Intent; |
12 import android.content.res.Resources; | 10 import android.content.res.Resources; |
13 import android.graphics.Bitmap; | 11 import android.graphics.Bitmap; |
14 import android.graphics.Color; | 12 import android.graphics.Color; |
15 import android.graphics.Rect; | |
16 import android.media.AudioManager; | |
17 import android.os.Build; | |
18 import android.os.Handler; | 13 import android.os.Handler; |
19 import android.os.Message; | 14 import android.os.Message; |
20 import android.provider.Browser; | 15 import android.provider.Browser; |
21 import android.text.TextUtils; | 16 import android.text.TextUtils; |
22 import android.util.Log; | 17 import android.util.Log; |
23 import android.util.Pair; | |
24 import android.view.ContextMenu; | 18 import android.view.ContextMenu; |
25 import android.view.KeyEvent; | |
26 import android.view.View; | 19 import android.view.View; |
27 import android.view.View.OnClickListener; | 20 import android.view.View.OnClickListener; |
28 import android.view.ViewGroup; | 21 import android.view.ViewGroup; |
29 import android.view.ViewGroup.LayoutParams; | 22 import android.view.ViewGroup.LayoutParams; |
30 import android.widget.FrameLayout; | 23 import android.widget.FrameLayout; |
31 | 24 |
32 import org.chromium.base.ActivityState; | 25 import org.chromium.base.ActivityState; |
33 import org.chromium.base.ApiCompatibilityUtils; | 26 import org.chromium.base.ApiCompatibilityUtils; |
34 import org.chromium.base.ApplicationState; | 27 import org.chromium.base.ApplicationState; |
35 import org.chromium.base.ApplicationStatus; | 28 import org.chromium.base.ApplicationStatus; |
36 import org.chromium.base.CommandLine; | 29 import org.chromium.base.CommandLine; |
37 import org.chromium.base.ObserverList; | 30 import org.chromium.base.ObserverList; |
38 import org.chromium.base.ObserverList.RewindableIterator; | 31 import org.chromium.base.ObserverList.RewindableIterator; |
39 import org.chromium.base.TraceEvent; | 32 import org.chromium.base.TraceEvent; |
40 import org.chromium.base.VisibleForTesting; | 33 import org.chromium.base.VisibleForTesting; |
41 import org.chromium.base.annotations.CalledByNative; | 34 import org.chromium.base.annotations.CalledByNative; |
42 import org.chromium.base.metrics.RecordHistogram; | 35 import org.chromium.base.metrics.RecordHistogram; |
43 import org.chromium.base.metrics.RecordUserAction; | 36 import org.chromium.base.metrics.RecordUserAction; |
44 import org.chromium.chrome.R; | 37 import org.chromium.chrome.R; |
45 import org.chromium.chrome.browser.AccessibilityUtil; | 38 import org.chromium.chrome.browser.AccessibilityUtil; |
46 import org.chromium.chrome.browser.ChromeActivity; | 39 import org.chromium.chrome.browser.ChromeActivity; |
47 import org.chromium.chrome.browser.ChromeApplication; | |
48 import org.chromium.chrome.browser.ChromeSwitches; | 40 import org.chromium.chrome.browser.ChromeSwitches; |
49 import org.chromium.chrome.browser.ChromeWebContentsDelegateAndroid; | 41 import org.chromium.chrome.browser.ChromeWebContentsDelegateAndroid; |
50 import org.chromium.chrome.browser.FrozenNativePage; | 42 import org.chromium.chrome.browser.FrozenNativePage; |
51 import org.chromium.chrome.browser.IntentHandler.TabOpenType; | 43 import org.chromium.chrome.browser.IntentHandler.TabOpenType; |
52 import org.chromium.chrome.browser.NativePage; | 44 import org.chromium.chrome.browser.NativePage; |
53 import org.chromium.chrome.browser.RepostFormWarningDialog; | |
54 import org.chromium.chrome.browser.SwipeRefreshHandler; | 45 import org.chromium.chrome.browser.SwipeRefreshHandler; |
55 import org.chromium.chrome.browser.TabState; | 46 import org.chromium.chrome.browser.TabState; |
56 import org.chromium.chrome.browser.TabState.WebContentsState; | 47 import org.chromium.chrome.browser.TabState.WebContentsState; |
57 import org.chromium.chrome.browser.UrlConstants; | 48 import org.chromium.chrome.browser.UrlConstants; |
58 import org.chromium.chrome.browser.WebContentsFactory; | 49 import org.chromium.chrome.browser.WebContentsFactory; |
59 import org.chromium.chrome.browser.banners.AppBannerManager; | 50 import org.chromium.chrome.browser.banners.AppBannerManager; |
60 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; | 51 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; |
61 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItemDelegate; | 52 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItemDelegate; |
62 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator; | 53 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator; |
63 import org.chromium.chrome.browser.contextmenu.ContextMenuParams; | 54 import org.chromium.chrome.browser.contextmenu.ContextMenuParams; |
64 import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator; | 55 import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator; |
65 import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorWrapper; | 56 import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorWrapper; |
66 import org.chromium.chrome.browser.crash.MinidumpUploadService; | 57 import org.chromium.chrome.browser.crash.MinidumpUploadService; |
67 import org.chromium.chrome.browser.customtabs.CustomTabActivity; | 58 import org.chromium.chrome.browser.customtabs.CustomTabActivity; |
68 import org.chromium.chrome.browser.document.DocumentUtils; | |
69 import org.chromium.chrome.browser.document.DocumentWebContentsDelegate; | |
70 import org.chromium.chrome.browser.download.ChromeDownloadDelegate; | 59 import org.chromium.chrome.browser.download.ChromeDownloadDelegate; |
71 import org.chromium.chrome.browser.fullscreen.FullscreenManager; | 60 import org.chromium.chrome.browser.fullscreen.FullscreenManager; |
72 import org.chromium.chrome.browser.help.HelpAndFeedback; | 61 import org.chromium.chrome.browser.help.HelpAndFeedback; |
73 import org.chromium.chrome.browser.infobar.InfoBarContainer; | 62 import org.chromium.chrome.browser.infobar.InfoBarContainer; |
74 import org.chromium.chrome.browser.media.MediaCaptureNotificationService; | |
75 import org.chromium.chrome.browser.metrics.UmaSessionStats; | 63 import org.chromium.chrome.browser.metrics.UmaSessionStats; |
76 import org.chromium.chrome.browser.metrics.UmaUtils; | 64 import org.chromium.chrome.browser.metrics.UmaUtils; |
77 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; | 65 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; |
78 import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader; | 66 import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader; |
79 import org.chromium.chrome.browser.policy.PolicyAuditor; | |
80 import org.chromium.chrome.browser.policy.PolicyAuditor.AuditEvent; | |
81 import org.chromium.chrome.browser.preferences.PrefServiceBridge; | 67 import org.chromium.chrome.browser.preferences.PrefServiceBridge; |
82 import org.chromium.chrome.browser.printing.TabPrinter; | 68 import org.chromium.chrome.browser.printing.TabPrinter; |
83 import org.chromium.chrome.browser.profiles.Profile; | 69 import org.chromium.chrome.browser.profiles.Profile; |
84 import org.chromium.chrome.browser.search_engines.TemplateUrlService; | 70 import org.chromium.chrome.browser.search_engines.TemplateUrlService; |
85 import org.chromium.chrome.browser.snackbar.SnackbarManager; | 71 import org.chromium.chrome.browser.snackbar.SnackbarManager; |
86 import org.chromium.chrome.browser.ssl.ConnectionSecurityLevel; | 72 import org.chromium.chrome.browser.ssl.ConnectionSecurityLevel; |
87 import org.chromium.chrome.browser.ssl.SecurityStateModel; | 73 import org.chromium.chrome.browser.ssl.SecurityStateModel; |
88 import org.chromium.chrome.browser.tab.TabUma.TabCreationState; | 74 import org.chromium.chrome.browser.tab.TabUma.TabCreationState; |
89 import org.chromium.chrome.browser.tabmodel.TabCreatorManager.TabCreator; | |
90 import org.chromium.chrome.browser.tabmodel.TabModel; | |
91 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; | 75 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; |
92 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; | 76 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; |
93 import org.chromium.chrome.browser.tabmodel.TabModelBase; | 77 import org.chromium.chrome.browser.tabmodel.TabModelBase; |
94 import org.chromium.chrome.browser.tabmodel.TabModelSelector; | 78 import org.chromium.chrome.browser.tabmodel.TabModelSelector; |
95 import org.chromium.chrome.browser.tabmodel.TabModelUtils; | |
96 import org.chromium.chrome.browser.util.FeatureUtilities; | 79 import org.chromium.chrome.browser.util.FeatureUtilities; |
97 import org.chromium.components.navigation_interception.InterceptNavigationDelega
te; | 80 import org.chromium.components.navigation_interception.InterceptNavigationDelega
te; |
98 import org.chromium.content.browser.ActivityContentVideoViewClient; | 81 import org.chromium.content.browser.ActivityContentVideoViewClient; |
99 import org.chromium.content.browser.ContentVideoViewClient; | 82 import org.chromium.content.browser.ContentVideoViewClient; |
100 import org.chromium.content.browser.ContentView; | 83 import org.chromium.content.browser.ContentView; |
101 import org.chromium.content.browser.ContentViewClient; | 84 import org.chromium.content.browser.ContentViewClient; |
102 import org.chromium.content.browser.ContentViewCore; | 85 import org.chromium.content.browser.ContentViewCore; |
103 import org.chromium.content_public.browser.InvalidateTypes; | |
104 import org.chromium.content_public.browser.LoadUrlParams; | 86 import org.chromium.content_public.browser.LoadUrlParams; |
105 import org.chromium.content_public.browser.WebContents; | 87 import org.chromium.content_public.browser.WebContents; |
106 import org.chromium.content_public.browser.WebContentsObserver; | 88 import org.chromium.content_public.browser.WebContentsObserver; |
107 import org.chromium.content_public.common.Referrer; | 89 import org.chromium.content_public.common.Referrer; |
108 import org.chromium.content_public.common.TopControlsState; | 90 import org.chromium.content_public.common.TopControlsState; |
109 import org.chromium.printing.PrintManagerDelegateImpl; | 91 import org.chromium.printing.PrintManagerDelegateImpl; |
110 import org.chromium.printing.PrintingController; | 92 import org.chromium.printing.PrintingController; |
111 import org.chromium.printing.PrintingControllerImpl; | 93 import org.chromium.printing.PrintingControllerImpl; |
112 import org.chromium.ui.WindowOpenDisposition; | 94 import org.chromium.ui.WindowOpenDisposition; |
113 import org.chromium.ui.base.Clipboard; | 95 import org.chromium.ui.base.Clipboard; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 * The mInterceptNavigationDelegate will be consulted for top-level frame na
vigations. This | 323 * The mInterceptNavigationDelegate will be consulted for top-level frame na
vigations. This |
342 * allows presenting the intent picker to the user so that a native Android
application can be | 324 * allows presenting the intent picker to the user so that a native Android
application can be |
343 * used if available. | 325 * used if available. |
344 */ | 326 */ |
345 private InterceptNavigationDelegate mInterceptNavigationDelegate; | 327 private InterceptNavigationDelegate mInterceptNavigationDelegate; |
346 | 328 |
347 private FullscreenManager mFullscreenManager; | 329 private FullscreenManager mFullscreenManager; |
348 private float mPreviousFullscreenTopControlsOffsetY = Float.NaN; | 330 private float mPreviousFullscreenTopControlsOffsetY = Float.NaN; |
349 private float mPreviousFullscreenContentOffsetY = Float.NaN; | 331 private float mPreviousFullscreenContentOffsetY = Float.NaN; |
350 private float mPreviousFullscreenOverdrawBottomHeight = Float.NaN; | 332 private float mPreviousFullscreenOverdrawBottomHeight = Float.NaN; |
351 private int mFullscreenHungRendererToken = FullscreenManager.INVALID_TOKEN; | 333 int mFullscreenHungRendererToken = FullscreenManager.INVALID_TOKEN; |
352 | 334 |
353 /** | 335 /** |
354 * The UMA object used to report stats for this tab. Note that this may be n
ull under certain | 336 * The UMA object used to report stats for this tab. Note that this may be n
ull under certain |
355 * conditions, such as incognito mode. | 337 * conditions, such as incognito mode. |
356 */ | 338 */ |
357 private TabUma mTabUma; | 339 private TabUma mTabUma; |
358 | 340 |
359 /** | 341 /** |
360 * Reference to the current sadTabView if one is defined. | 342 * Reference to the current sadTabView if one is defined. |
361 */ | 343 */ |
(...skipping 15 matching lines...) Expand all Loading... |
377 /** | 359 /** |
378 * The last page load had request headers indicating that the data reduction
proxy should | 360 * The last page load had request headers indicating that the data reduction
proxy should |
379 * be put in pass through mode, if true. | 361 * be put in pass through mode, if true. |
380 */ | 362 */ |
381 protected boolean mLastPageLoadHasSpdyProxyPassthroughHeaders; | 363 protected boolean mLastPageLoadHasSpdyProxyPassthroughHeaders; |
382 | 364 |
383 private ChromeDownloadDelegate mDownloadDelegate; | 365 private ChromeDownloadDelegate mDownloadDelegate; |
384 | 366 |
385 protected Handler mHandler; | 367 protected Handler mHandler; |
386 | 368 |
387 private final Runnable mCloseContentsRunnable = new Runnable() { | |
388 @Override | |
389 public void run() { | |
390 boolean isSelected = mActivity.getTabModelSelector().getCurrentTab()
== Tab.this; | |
391 mActivity.getTabModelSelector().closeTab(Tab.this); | |
392 | |
393 // If the parent Tab belongs to another Activity, fire the Intent to
bring it back. | |
394 if (isSelected && getParentIntent() != null | |
395 && mActivity.getIntent() != getParentIntent()) { | |
396 boolean mayLaunch = FeatureUtilities.isDocumentMode(mActivity) | |
397 ? isParentInAndroidOverview() : true; | |
398 if (mayLaunch) mActivity.startActivity(getParentIntent()); | |
399 } | |
400 } | |
401 | |
402 /** If the API allows it, returns whether a Task still exists for the pa
rent Activity. */ | |
403 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | |
404 private boolean isParentInAndroidOverview() { | |
405 ActivityManager activityManager = | |
406 (ActivityManager) mActivity.getSystemService(Context.ACTIVIT
Y_SERVICE); | |
407 for (ActivityManager.AppTask task : activityManager.getAppTasks()) { | |
408 Intent taskIntent = DocumentUtils.getBaseIntentFromTask(task); | |
409 if (taskIntent != null && taskIntent.filterEquals(getParentInten
t())) return true; | |
410 } | |
411 return false; | |
412 } | |
413 }; | |
414 | |
415 /** | 369 /** |
416 * A default {@link ChromeContextMenuItemDelegate} that supports some of the
context menu | 370 * A default {@link ChromeContextMenuItemDelegate} that supports some of the
context menu |
417 * functionality. | 371 * functionality. |
418 */ | 372 */ |
419 protected class TabChromeContextMenuItemDelegate implements ChromeContextMen
uItemDelegate { | 373 protected class TabChromeContextMenuItemDelegate implements ChromeContextMen
uItemDelegate { |
420 private final Clipboard mClipboard; | 374 private final Clipboard mClipboard; |
421 | 375 |
422 /** | 376 /** |
423 * Builds a {@link TabChromeContextMenuItemDelegate} instance. | 377 * Builds a {@link TabChromeContextMenuItemDelegate} instance. |
424 */ | 378 */ |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 mActivity.getTabModelSelector().openNewTab(loadUrlParams, | 466 mActivity.getTabModelSelector().openNewTab(loadUrlParams, |
513 TabLaunchType.FROM_LONGPRESS_BACKGROUND, Tab.this, isIncogni
to()); | 467 TabLaunchType.FROM_LONGPRESS_BACKGROUND, Tab.this, isIncogni
to()); |
514 } | 468 } |
515 | 469 |
516 @Override | 470 @Override |
517 public void onSearchByImageInNewTab() { | 471 public void onSearchByImageInNewTab() { |
518 triggerSearchByImage(); | 472 triggerSearchByImage(); |
519 } | 473 } |
520 } | 474 } |
521 | 475 |
522 /** | |
523 * A basic {@link ChromeWebContentsDelegateAndroid} that forwards some calls
to the registered | |
524 * {@link TabObserver}s. Meant to be overridden by subclasses. | |
525 */ | |
526 public class TabChromeWebContentsDelegateAndroid | |
527 extends ChromeWebContentsDelegateAndroid { | |
528 @Override | |
529 public void onLoadProgressChanged(int progress) { | |
530 if (!isLoading()) return; | |
531 notifyLoadProgress(getProgress()); | |
532 } | |
533 | 476 |
534 @Override | |
535 public void onLoadStarted() { | |
536 for (TabObserver observer : mObservers) observer.onLoadStarted(Tab.t
his); | |
537 } | |
538 | |
539 @Override | |
540 public void onLoadStopped() { | |
541 for (TabObserver observer : mObservers) observer.onLoadStopped(Tab.t
his); | |
542 } | |
543 | |
544 @Override | |
545 public void onUpdateUrl(String url) { | |
546 for (TabObserver observer : mObservers) observer.onUpdateUrl(Tab.thi
s, url); | |
547 } | |
548 | |
549 @Override | |
550 public void showRepostFormWarningDialog() { | |
551 // When the dialog is visible, keeping the refresh animation active | |
552 // in the background is distracting and unnecessary (and likely to | |
553 // jank when the dialog is shown). | |
554 if (mSwipeRefreshHandler != null) { | |
555 mSwipeRefreshHandler.reset(); | |
556 } | |
557 RepostFormWarningDialog warningDialog = new RepostFormWarningDialog( | |
558 new Runnable() { | |
559 @Override | |
560 public void run() { | |
561 getWebContents().getNavigationController().cancelPen
dingReload(); | |
562 } | |
563 }, new Runnable() { | |
564 @Override | |
565 public void run() { | |
566 getWebContents().getNavigationController().continueP
endingReload(); | |
567 } | |
568 }); | |
569 warningDialog.show(mActivity.getFragmentManager(), null); | |
570 } | |
571 | |
572 @Override | |
573 public void toggleFullscreenModeForTab(boolean enableFullscreen) { | |
574 if (mFullscreenManager != null) { | |
575 mFullscreenManager.setPersistentFullscreenMode(enableFullscreen)
; | |
576 } | |
577 | |
578 for (TabObserver observer : mObservers) { | |
579 observer.onToggleFullscreenMode(Tab.this, enableFullscreen); | |
580 } | |
581 } | |
582 | |
583 @Override | |
584 public void navigationStateChanged(int flags) { | |
585 if ((flags & InvalidateTypes.TAB) != 0) { | |
586 MediaCaptureNotificationService.updateMediaNotificationForTab( | |
587 getApplicationContext(), getId(), isCapturingAudio(), | |
588 isCapturingVideo(), getUrl()); | |
589 } | |
590 if ((flags & InvalidateTypes.TITLE) != 0) { | |
591 // Update cached title then notify observers. | |
592 updateTitle(); | |
593 } | |
594 if ((flags & InvalidateTypes.URL) != 0) { | |
595 for (TabObserver observer : mObservers) observer.onUrlUpdated(Ta
b.this); | |
596 } | |
597 } | |
598 | |
599 @Override | |
600 public void visibleSSLStateChanged() { | |
601 for (TabObserver observer : mObservers) observer.onSSLStateUpdated(T
ab.this); | |
602 } | |
603 | |
604 @Override | |
605 public void webContentsCreated(WebContents sourceWebContents, long opene
rRenderFrameId, | |
606 String frameName, String targetUrl, WebContents newWebContents)
{ | |
607 for (TabObserver observer : mObservers) { | |
608 observer.webContentsCreated(Tab.this, sourceWebContents, openerR
enderFrameId, | |
609 frameName, targetUrl, newWebContents); | |
610 } | |
611 // The URL can't be taken from the WebContents if it's paused. Save
it for later. | |
612 assert mWebContentsUrlMapping == null; | |
613 mWebContentsUrlMapping = Pair.create(newWebContents, targetUrl); | |
614 | |
615 // TODO(dfalcantara): Re-remove this once crbug.com/508366 is fixed. | |
616 TabCreator tabCreator = mActivity.getTabCreator(isIncognito()); | |
617 | |
618 if (tabCreator != null && tabCreator.createsTabsAsynchronously()) { | |
619 DocumentWebContentsDelegate.getInstance().attachDelegate(newWebC
ontents); | |
620 } | |
621 } | |
622 | |
623 @Override | |
624 public void rendererUnresponsive() { | |
625 super.rendererUnresponsive(); | |
626 if (mNativeTabAndroid != 0) nativeOnRendererUnresponsive(mNativeTabA
ndroid); | |
627 if (mFullscreenManager == null) return; | |
628 mFullscreenHungRendererToken = | |
629 mFullscreenManager.showControlsPersistentAndClearOldToken( | |
630 mFullscreenHungRendererToken); | |
631 } | |
632 | |
633 @Override | |
634 public void rendererResponsive() { | |
635 super.rendererResponsive(); | |
636 if (mNativeTabAndroid != 0) nativeOnRendererResponsive(mNativeTabAnd
roid); | |
637 if (mFullscreenManager == null) return; | |
638 mFullscreenManager.hideControlsPersistent(mFullscreenHungRendererTok
en); | |
639 mFullscreenHungRendererToken = FullscreenManager.INVALID_TOKEN; | |
640 } | |
641 | |
642 @Override | |
643 public boolean isFullscreenForTabOrPending() { | |
644 return mFullscreenManager == null | |
645 ? false : mFullscreenManager.getPersistentFullscreenMode(); | |
646 } | |
647 | |
648 @Override | |
649 public void openNewTab(String url, String extraHeaders, byte[] postData,
int disposition, | |
650 boolean isRendererInitiated) { | |
651 Tab.this.openNewTab( | |
652 url, extraHeaders, postData, disposition, true, isRendererIn
itiated); | |
653 } | |
654 | |
655 private Pair<WebContents, String> mWebContentsUrlMapping; | |
656 | |
657 protected TabModel getTabModel() { | |
658 // TODO(dfalcantara): Remove this when DocumentActivity.getTabModelS
elector() | |
659 // can return a TabModelSelector that activateCon
tents() can use. | |
660 return mActivity.getTabModelSelector().getModel(isIncognito()); | |
661 } | |
662 | |
663 @Override | |
664 public boolean shouldResumeRequestsForCreatedWindow() { | |
665 // Pause the WebContents if an Activity has to be created for it fir
st. | |
666 TabCreator tabCreator = mActivity.getTabCreator(isIncognito()); | |
667 assert tabCreator != null; | |
668 return !tabCreator.createsTabsAsynchronously(); | |
669 } | |
670 | |
671 @Override | |
672 public boolean addNewContents(WebContents sourceWebContents, WebContents
webContents, | |
673 int disposition, Rect initialPosition, boolean userGesture) { | |
674 assert mWebContentsUrlMapping.first == webContents; | |
675 | |
676 TabCreator tabCreator = mActivity.getTabCreator(isIncognito()); | |
677 assert tabCreator != null; | |
678 | |
679 // Grab the URL, which might not be available via the Tab. | |
680 String url = mWebContentsUrlMapping.second; | |
681 mWebContentsUrlMapping = null; | |
682 | |
683 // Skip opening a new Tab if it doesn't make sense. | |
684 if (isClosing()) return false; | |
685 | |
686 // Creating new Tabs asynchronously requires starting a new Activity
to create the Tab, | |
687 // so the Tab returned will always be null. There's no way to know
synchronously | |
688 // whether the Tab is created, so assume it's always successful. | |
689 boolean createdSuccessfully = tabCreator.createTabWithWebContents( | |
690 webContents, getId(), TabLaunchType.FROM_LONGPRESS_FOREGROUN
D, url); | |
691 boolean success = tabCreator.createsTabsAsynchronously() || createdS
uccessfully; | |
692 if (success && disposition == WindowOpenDisposition.NEW_POPUP) { | |
693 PolicyAuditor auditor = | |
694 ((ChromeApplication) getApplicationContext()).getPolicyA
uditor(); | |
695 auditor.notifyAuditEvent(getApplicationContext(), AuditEvent.OPE
N_POPUP_URL_SUCCESS, | |
696 url, ""); | |
697 } | |
698 | |
699 return success; | |
700 } | |
701 | |
702 @Override | |
703 public void activateContents() { | |
704 boolean activityIsDestroyed = false; | |
705 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { | |
706 activityIsDestroyed = mActivity.isDestroyed(); | |
707 } | |
708 if (activityIsDestroyed || !isInitialized()) { | |
709 Log.e(TAG, "Activity destroyed before calling activateContents()
. Bailing out."); | |
710 return; | |
711 } | |
712 | |
713 TabModel model = getTabModel(); | |
714 int index = model.indexOf(Tab.this); | |
715 if (index == TabModel.INVALID_TAB_INDEX) return; | |
716 TabModelUtils.setIndex(model, index); | |
717 bringActivityToForeground(); | |
718 } | |
719 | |
720 /** | |
721 * Brings chrome's Activity to foreground, if it is not so. | |
722 */ | |
723 protected void bringActivityToForeground() { | |
724 // This intent is sent in order to get the activity back to the fore
ground if it was | |
725 // not already. The previous call will activate the right tab in the
context of the | |
726 // TabModel but will only show the tab to the user if Chrome was alr
eady in the | |
727 // foreground. | |
728 // The intent is getting the tabId mostly because it does not cost m
uch to do so. | |
729 // When receiving the intent, the tab associated with the tabId shou
ld already be | |
730 // active. | |
731 // Note that calling only the intent in order to activate the tab is
slightly slower | |
732 // because it will change the tab when the intent is handled, which
happens after | |
733 // Chrome gets back to the foreground. | |
734 Intent newIntent = Tab.createBringTabToFrontIntent(Tab.this.getId())
; | |
735 newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
736 | |
737 getApplicationContext().startActivity(newIntent); | |
738 } | |
739 | |
740 @Override | |
741 public void closeContents() { | |
742 // Execute outside of callback, otherwise we end up deleting the nat
ive | |
743 // objects in the middle of executing methods on them. | |
744 mHandler.removeCallbacks(mCloseContentsRunnable); | |
745 mHandler.post(mCloseContentsRunnable); | |
746 } | |
747 | |
748 @Override | |
749 public boolean takeFocus(boolean reverse) { | |
750 if (reverse) { | |
751 View menuButton = mActivity.findViewById(R.id.menu_button); | |
752 if (menuButton == null || !menuButton.isShown()) { | |
753 menuButton = mActivity.findViewById(R.id.document_menu_butto
n); | |
754 } | |
755 if (menuButton != null && menuButton.isShown()) { | |
756 return menuButton.requestFocus(); | |
757 } | |
758 | |
759 View tabSwitcherButton = mActivity.findViewById(R.id.tab_switche
r_button); | |
760 if (tabSwitcherButton != null && tabSwitcherButton.isShown()) { | |
761 return tabSwitcherButton.requestFocus(); | |
762 } | |
763 } else { | |
764 View urlBar = mActivity.findViewById(R.id.url_bar); | |
765 if (urlBar != null) return urlBar.requestFocus(); | |
766 } | |
767 return false; | |
768 } | |
769 | |
770 @Override | |
771 public void handleKeyboardEvent(KeyEvent event) { | |
772 if (event.getAction() == KeyEvent.ACTION_DOWN) { | |
773 if (mActivity.onKeyDown(event.getKeyCode(), event)) return; | |
774 | |
775 // Handle the Escape key here (instead of in KeyboardShortcuts.j
ava), so it doesn't | |
776 // interfere with other parts of the activity (e.g. the URL bar)
. | |
777 if (event.getKeyCode() == KeyEvent.KEYCODE_ESCAPE && event.hasNo
Modifiers()) { | |
778 WebContents wc = getWebContents(); | |
779 if (wc != null) wc.stop(); | |
780 return; | |
781 } | |
782 } | |
783 handleMediaKey(event); | |
784 } | |
785 | |
786 /** | |
787 * Redispatches unhandled media keys. This allows bluetooth headphones w
ith play/pause or | |
788 * other buttons to function correctly. | |
789 */ | |
790 @TargetApi(19) | |
791 private void handleMediaKey(KeyEvent e) { | |
792 if (Build.VERSION.SDK_INT < 19) return; | |
793 switch (e.getKeyCode()) { | |
794 case KeyEvent.KEYCODE_MUTE: | |
795 case KeyEvent.KEYCODE_HEADSETHOOK: | |
796 case KeyEvent.KEYCODE_MEDIA_PLAY: | |
797 case KeyEvent.KEYCODE_MEDIA_PAUSE: | |
798 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: | |
799 case KeyEvent.KEYCODE_MEDIA_STOP: | |
800 case KeyEvent.KEYCODE_MEDIA_NEXT: | |
801 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: | |
802 case KeyEvent.KEYCODE_MEDIA_REWIND: | |
803 case KeyEvent.KEYCODE_MEDIA_RECORD: | |
804 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: | |
805 case KeyEvent.KEYCODE_MEDIA_CLOSE: | |
806 case KeyEvent.KEYCODE_MEDIA_EJECT: | |
807 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: | |
808 AudioManager am = (AudioManager) mActivity.getSystemService( | |
809 Context.AUDIO_SERVICE); | |
810 am.dispatchMediaKeyEvent(e); | |
811 break; | |
812 default: | |
813 break; | |
814 } | |
815 } | |
816 | |
817 /** | |
818 * @return Whether audio is being captured. | |
819 */ | |
820 private boolean isCapturingAudio() { | |
821 return !isClosing() | |
822 && ChromeWebContentsDelegateAndroid.nativeIsCapturingAudio(g
etWebContents()); | |
823 } | |
824 | |
825 /** | |
826 * @return Whether video is being captured. | |
827 */ | |
828 private boolean isCapturingVideo() { | |
829 return !isClosing() | |
830 && ChromeWebContentsDelegateAndroid.nativeIsCapturingVideo(g
etWebContents()); | |
831 } | |
832 } | |
833 | 477 |
834 private class TabContentViewClient extends ContentViewClient { | 478 private class TabContentViewClient extends ContentViewClient { |
835 @Override | 479 @Override |
836 public void onBackgroundColorChanged(int color) { | 480 public void onBackgroundColorChanged(int color) { |
837 Tab.this.onBackgroundColorChanged(color); | 481 Tab.this.onBackgroundColorChanged(color); |
838 } | 482 } |
839 | 483 |
840 @Override | 484 @Override |
841 public void onOffsetsForFullscreenChanged( | 485 public void onOffsetsForFullscreenChanged( |
842 float topControlsOffsetY, float contentOffsetY, float overdrawBo
ttomHeight) { | 486 float topControlsOffsetY, float contentOffsetY, float overdrawBo
ttomHeight) { |
(...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2214 | 1858 |
2215 /** | 1859 /** |
2216 * @return The tab title. | 1860 * @return The tab title. |
2217 */ | 1861 */ |
2218 @CalledByNative | 1862 @CalledByNative |
2219 public String getTitle() { | 1863 public String getTitle() { |
2220 if (mTitle == null) updateTitle(); | 1864 if (mTitle == null) updateTitle(); |
2221 return mTitle; | 1865 return mTitle; |
2222 } | 1866 } |
2223 | 1867 |
2224 private void updateTitle() { | 1868 void updateTitle() { |
2225 if (isFrozen()) return; | 1869 if (isFrozen()) return; |
2226 | 1870 |
2227 // When restoring the tabs, the title will no longer be populated, so re
quest it from the | 1871 // When restoring the tabs, the title will no longer be populated, so re
quest it from the |
2228 // ContentViewCore or NativePage (if present). | 1872 // ContentViewCore or NativePage (if present). |
2229 String title = ""; | 1873 String title = ""; |
2230 if (mNativePage != null) { | 1874 if (mNativePage != null) { |
2231 title = mNativePage.getTitle(); | 1875 title = mNativePage.getTitle(); |
2232 } else if (getWebContents() != null) { | 1876 } else if (getWebContents() != null) { |
2233 title = getWebContents().getTitle(); | 1877 title = getWebContents().getTitle(); |
2234 } | 1878 } |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2551 protected void destroyContentViewCoreInternal(ContentViewCore cvc) { | 2195 protected void destroyContentViewCoreInternal(ContentViewCore cvc) { |
2552 cvc.getContainerView().setOnHierarchyChangeListener(null); | 2196 cvc.getContainerView().setOnHierarchyChangeListener(null); |
2553 cvc.getContainerView().setOnSystemUiVisibilityChangeListener(null); | 2197 cvc.getContainerView().setOnSystemUiVisibilityChangeListener(null); |
2554 } | 2198 } |
2555 | 2199 |
2556 /** | 2200 /** |
2557 * A helper method to allow subclasses to build their own delegate. | 2201 * A helper method to allow subclasses to build their own delegate. |
2558 * @return An instance of a {@link TabChromeWebContentsDelegateAndroid}. | 2202 * @return An instance of a {@link TabChromeWebContentsDelegateAndroid}. |
2559 */ | 2203 */ |
2560 protected TabChromeWebContentsDelegateAndroid createWebContentsDelegate() { | 2204 protected TabChromeWebContentsDelegateAndroid createWebContentsDelegate() { |
2561 return new TabChromeWebContentsDelegateAndroid(); | 2205 return new TabChromeWebContentsDelegateAndroid(this, mActivity); |
2562 } | 2206 } |
2563 | 2207 |
2564 /** | 2208 /** |
2565 * A helper method to allow subclasses to handle the Instant support | 2209 * A helper method to allow subclasses to handle the Instant support |
2566 * disabled event. | 2210 * disabled event. |
2567 */ | 2211 */ |
2568 @CalledByNative | 2212 @CalledByNative |
2569 private void onWebContentsInstantSupportDisabled() { | 2213 private void onWebContentsInstantSupportDisabled() { |
2570 for (TabObserver observer : mObservers) observer.onWebContentsInstantSup
portDisabled(); | 2214 for (TabObserver observer : mObservers) observer.onWebContentsInstantSup
portDisabled(); |
2571 } | 2215 } |
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3243 /** | 2887 /** |
3244 * Check whether the context menu download should be intercepted. | 2888 * Check whether the context menu download should be intercepted. |
3245 * | 2889 * |
3246 * @param url URL to be downloaded. | 2890 * @param url URL to be downloaded. |
3247 * @return whether the download should be intercepted. | 2891 * @return whether the download should be intercepted. |
3248 */ | 2892 */ |
3249 protected boolean shouldInterceptContextMenuDownload(String url) { | 2893 protected boolean shouldInterceptContextMenuDownload(String url) { |
3250 return mDownloadDelegate.shouldInterceptContextMenuDownload(url); | 2894 return mDownloadDelegate.shouldInterceptContextMenuDownload(url); |
3251 } | 2895 } |
3252 | 2896 |
| 2897 void resetSwipeRefreshHandler() { |
| 2898 // When the dialog is visible, keeping the refresh animation active |
| 2899 // in the background is distracting and unnecessary (and likely to |
| 2900 // jank when the dialog is shown). |
| 2901 if (mSwipeRefreshHandler != null) { |
| 2902 mSwipeRefreshHandler.reset(); |
| 2903 } |
| 2904 } |
| 2905 |
3253 /** | 2906 /** |
3254 * Checks if spdy proxy is enabled for input url. | 2907 * Checks if spdy proxy is enabled for input url. |
3255 * @param url Input url to check for spdy setting. | 2908 * @param url Input url to check for spdy setting. |
3256 * @return true if url is enabled for spdy proxy. | 2909 * @return true if url is enabled for spdy proxy. |
3257 */ | 2910 */ |
3258 private boolean isSpdyProxyEnabledForUrl(String url) { | 2911 private boolean isSpdyProxyEnabledForUrl(String url) { |
3259 if (DataReductionProxySettings.getInstance().isDataReductionProxyEnabled
() | 2912 if (DataReductionProxySettings.getInstance().isDataReductionProxyEnabled
() |
3260 && url != null && !url.toLowerCase(Locale.US).startsWith("https:
//") | 2913 && url != null && !url.toLowerCase(Locale.US).startsWith("https:
//") |
3261 && !isIncognito()) { | 2914 && !isIncognito()) { |
3262 return true; | 2915 return true; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3311 private native String nativeGetOfflinePageOriginalUrl(long nativeTabAndroid)
; | 2964 private native String nativeGetOfflinePageOriginalUrl(long nativeTabAndroid)
; |
3312 private native void nativeSetInterceptNavigationDelegate(long nativeTabAndro
id, | 2965 private native void nativeSetInterceptNavigationDelegate(long nativeTabAndro
id, |
3313 InterceptNavigationDelegate delegate); | 2966 InterceptNavigationDelegate delegate); |
3314 private native void nativeAttachToTabContentManager(long nativeTabAndroid, | 2967 private native void nativeAttachToTabContentManager(long nativeTabAndroid, |
3315 TabContentManager tabContentManager); | 2968 TabContentManager tabContentManager); |
3316 private native void nativeAttachOverlayContentViewCore(long nativeTabAndroid
, | 2969 private native void nativeAttachOverlayContentViewCore(long nativeTabAndroid
, |
3317 ContentViewCore content, boolean visible); | 2970 ContentViewCore content, boolean visible); |
3318 private native void nativeDetachOverlayContentViewCore(long nativeTabAndroid
, | 2971 private native void nativeDetachOverlayContentViewCore(long nativeTabAndroid
, |
3319 ContentViewCore content); | 2972 ContentViewCore content); |
3320 private native boolean nativeHasPrerenderedUrl(long nativeTabAndroid, String
url); | 2973 private native boolean nativeHasPrerenderedUrl(long nativeTabAndroid, String
url); |
3321 private native void nativeOnRendererUnresponsive(long nativeTabAndroid); | |
3322 private native void nativeOnRendererResponsive(long nativeTabAndroid); | |
3323 | 2974 |
3324 private static native void nativeRecordStartupToCommitUma(); | 2975 private static native void nativeRecordStartupToCommitUma(); |
3325 } | 2976 } |
OLD | NEW |