| 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.app.Activity; | 7 import android.app.Activity; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.content.Intent; | 9 import android.content.Intent; |
| 10 import android.content.res.Resources; | 10 import android.content.res.Resources; |
| 11 import android.graphics.Bitmap; | 11 import android.graphics.Bitmap; |
| 12 import android.graphics.Color; | 12 import android.graphics.Color; |
| 13 import android.os.Handler; | 13 import android.os.Handler; |
| 14 import android.os.Message; | 14 import android.os.Message; |
| 15 import android.provider.Browser; | 15 import android.provider.Browser; |
| 16 import android.text.TextUtils; | 16 import android.text.TextUtils; |
| 17 import android.util.Log; | 17 import android.util.Log; |
| 18 import android.view.ContextThemeWrapper; |
| 18 import android.view.View; | 19 import android.view.View; |
| 19 import android.view.View.OnClickListener; | 20 import android.view.View.OnClickListener; |
| 20 import android.view.ViewGroup; | 21 import android.view.ViewGroup; |
| 21 import android.view.ViewGroup.LayoutParams; | 22 import android.view.ViewGroup.LayoutParams; |
| 22 import android.widget.FrameLayout; | 23 import android.widget.FrameLayout; |
| 23 | 24 |
| 24 import org.chromium.base.ApiCompatibilityUtils; | 25 import org.chromium.base.ApiCompatibilityUtils; |
| 25 import org.chromium.base.ApplicationStatus; | 26 import org.chromium.base.ApplicationStatus; |
| 26 import org.chromium.base.ObserverList; | 27 import org.chromium.base.ObserverList; |
| 27 import org.chromium.base.ObserverList.RewindableIterator; | 28 import org.chromium.base.ObserverList.RewindableIterator; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 * The required page load percentage for the page to be considered ready ass
uming the | 129 * The required page load percentage for the page to be considered ready ass
uming the |
| 129 * TextureView is also ready. | 130 * TextureView is also ready. |
| 130 */ | 131 */ |
| 131 private static final int CONSIDERED_READY_LOAD_PERCENTAGE = 100; | 132 private static final int CONSIDERED_READY_LOAD_PERCENTAGE = 100; |
| 132 | 133 |
| 133 /** Used for logging. */ | 134 /** Used for logging. */ |
| 134 private static final String TAG = "Tab"; | 135 private static final String TAG = "Tab"; |
| 135 | 136 |
| 136 /** | 137 /** |
| 137 * The {@link Activity} used to create {@link View}s and other Android compo
nents. Unlike | 138 * The {@link Activity} used to create {@link View}s and other Android compo
nents. Unlike |
| 138 * {@link #mApplicationContext}, this is not publicly exposed to help preven
t leaking the | 139 * {@link #mThemedApplicationContext}, this is not publicly exposed to help
prevent leaking the |
| 139 * {@link Activity}. | 140 * {@link Activity}. |
| 140 */ | 141 */ |
| 141 protected final ChromeActivity mActivity; | 142 protected final ChromeActivity mActivity; |
| 142 | 143 |
| 143 private long mNativeTabAndroid; | 144 private long mNativeTabAndroid; |
| 144 | 145 |
| 145 /** Unique id of this tab (within its container). */ | 146 /** Unique id of this tab (within its container). */ |
| 146 private final int mId; | 147 private final int mId; |
| 147 | 148 |
| 148 /** Whether or not this tab is an incognito tab. */ | 149 /** Whether or not this tab is an incognito tab. */ |
| 149 private final boolean mIncognito; | 150 private final boolean mIncognito; |
| 150 | 151 |
| 151 /** | 152 /** |
| 152 * An Application {@link Context}. Unlike {@link #mActivity}, this is the o
nly one that is | 153 * An Application {@link Context}. Unlike {@link #mActivity}, this is the o
nly one that is |
| 153 * publicly exposed to help prevent leaking the {@link Activity}. | 154 * publicly exposed to help prevent leaking the {@link Activity}. |
| 154 */ | 155 */ |
| 155 private final Context mApplicationContext; | 156 private final Context mThemedApplicationContext; |
| 156 | 157 |
| 157 /** Gives {@link Tab} a way to interact with the Android window. */ | 158 /** Gives {@link Tab} a way to interact with the Android window. */ |
| 158 private final WindowAndroid mWindowAndroid; | 159 private final WindowAndroid mWindowAndroid; |
| 159 | 160 |
| 160 /** Whether or not this {@link Tab} is initialized and should be interacted
with. */ | 161 /** Whether or not this {@link Tab} is initialized and should be interacted
with. */ |
| 161 private boolean mIsInitialized; | 162 private boolean mIsInitialized; |
| 162 | 163 |
| 163 /** The current native page (e.g. chrome-native://newtab), or {@code null} i
f there is none. */ | 164 /** The current native page (e.g. chrome-native://newtab), or {@code null} i
f there is none. */ |
| 164 private NativePage mNativePage; | 165 private NativePage mNativePage; |
| 165 | 166 |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 * accounting. When null, TabUma will not be initialize
d. | 537 * accounting. When null, TabUma will not be initialize
d. |
| 537 * @param frozenState State containing information about this Tab, if it was
persisted. | 538 * @param frozenState State containing information about this Tab, if it was
persisted. |
| 538 */ | 539 */ |
| 539 public Tab(int id, int parentId, boolean incognito, ChromeActivity activity, | 540 public Tab(int id, int parentId, boolean incognito, ChromeActivity activity, |
| 540 WindowAndroid window, TabLaunchType type, TabCreationState creationS
tate, | 541 WindowAndroid window, TabLaunchType type, TabCreationState creationS
tate, |
| 541 TabState frozenState) { | 542 TabState frozenState) { |
| 542 mId = TabIdManager.getInstance().generateValidId(id); | 543 mId = TabIdManager.getInstance().generateValidId(id); |
| 543 mParentId = parentId; | 544 mParentId = parentId; |
| 544 mIncognito = incognito; | 545 mIncognito = incognito; |
| 545 mActivity = activity; | 546 mActivity = activity; |
| 546 mApplicationContext = activity != null ? activity.getApplicationContext(
) : null; | 547 mThemedApplicationContext = activity != null ? new ContextThemeWrapper( |
| 548 activity.getApplicationContext(), ChromeActivity.getThemeId()) :
null; |
| 547 mWindowAndroid = window; | 549 mWindowAndroid = window; |
| 548 mLaunchType = type; | 550 mLaunchType = type; |
| 549 if (mActivity != null) { | 551 if (mThemedApplicationContext != null) { |
| 550 Resources resources = mActivity.getResources(); | 552 Resources resources = mThemedApplicationContext.getResources(); |
| 551 mIdealFaviconSize = resources.getDimensionPixelSize(R.dimen.default_
favicon_size); | 553 mIdealFaviconSize = resources.getDimensionPixelSize(R.dimen.default_
favicon_size); |
| 552 mDefaultThemeColor = mIncognito | 554 mDefaultThemeColor = mIncognito |
| 553 ? ApiCompatibilityUtils.getColor(resources, R.color.incognit
o_primary_color) | 555 ? ApiCompatibilityUtils.getColor(resources, R.color.incognit
o_primary_color) |
| 554 : ApiCompatibilityUtils.getColor(resources, R.color.default_
primary_color); | 556 : ApiCompatibilityUtils.getColor(resources, R.color.default_
primary_color); |
| 555 } else { | 557 } else { |
| 556 mIdealFaviconSize = 16; | 558 mIdealFaviconSize = 16; |
| 557 mDefaultThemeColor = 0; | 559 mDefaultThemeColor = 0; |
| 558 } | 560 } |
| 559 | 561 |
| 560 // Restore data from the TabState, if it existed. | 562 // Restore data from the TabState, if it existed. |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 */ | 800 */ |
| 799 public int getHeight() { | 801 public int getHeight() { |
| 800 View view = getView(); | 802 View view = getView(); |
| 801 return view != null ? view.getHeight() : 0; | 803 return view != null ? view.getHeight() : 0; |
| 802 } | 804 } |
| 803 | 805 |
| 804 /** | 806 /** |
| 805 * @return The application {@link Context} associated with this tab. | 807 * @return The application {@link Context} associated with this tab. |
| 806 */ | 808 */ |
| 807 protected Context getApplicationContext() { | 809 protected Context getApplicationContext() { |
| 808 return mApplicationContext; | 810 return mThemedApplicationContext.getApplicationContext(); |
| 809 } | 811 } |
| 810 | 812 |
| 811 /** | 813 /** |
| 812 * @return The infobar container. | 814 * @return The infobar container. |
| 813 */ | 815 */ |
| 814 public final InfoBarContainer getInfoBarContainer() { | 816 public final InfoBarContainer getInfoBarContainer() { |
| 815 return mInfoBarContainer; | 817 return mInfoBarContainer; |
| 816 } | 818 } |
| 817 | 819 |
| 818 /** @return An opaque "state" object that can be persisted to storage. */ | 820 /** @return An opaque "state" object that can be persisted to storage. */ |
| (...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1473 mIsInitialized = true; | 1475 mIsInitialized = true; |
| 1474 } | 1476 } |
| 1475 | 1477 |
| 1476 /** | 1478 /** |
| 1477 * Creates and initializes the {@link ContentViewCore}. | 1479 * Creates and initializes the {@link ContentViewCore}. |
| 1478 * | 1480 * |
| 1479 * @param webContents The WebContents object that will be used to build the | 1481 * @param webContents The WebContents object that will be used to build the |
| 1480 * {@link ContentViewCore}. | 1482 * {@link ContentViewCore}. |
| 1481 */ | 1483 */ |
| 1482 protected void initContentViewCore(WebContents webContents) { | 1484 protected void initContentViewCore(WebContents webContents) { |
| 1483 ContentViewCore cvc = new ContentViewCore(mActivity); | 1485 ContentViewCore cvc = new ContentViewCore(mThemedApplicationContext); |
| 1484 ContentView cv = ContentView.createContentView(mActivity, cvc); | 1486 ContentView cv = ContentView.createContentView(mThemedApplicationContext
, cvc); |
| 1485 cv.setContentDescription(mActivity.getResources().getString( | 1487 cv.setContentDescription(mThemedApplicationContext.getResources().getStr
ing( |
| 1486 R.string.accessibility_content_view)); | 1488 R.string.accessibility_content_view)); |
| 1487 cvc.initialize(cv, cv, webContents, getWindowAndroid()); | 1489 cvc.initialize(cv, cv, webContents, getWindowAndroid()); |
| 1488 setContentViewCore(cvc); | 1490 setContentViewCore(cvc); |
| 1489 } | 1491 } |
| 1490 | 1492 |
| 1491 /** | 1493 /** |
| 1492 * Completes the {@link ContentViewCore} specific initialization around a na
tive WebContents | 1494 * Completes the {@link ContentViewCore} specific initialization around a na
tive WebContents |
| 1493 * pointer. {@link #getNativePage()} will still return the {@link NativePage
} if there is one. | 1495 * pointer. {@link #getNativePage()} will still return the {@link NativePage
} if there is one. |
| 1494 * All initialization that needs to reoccur after a web contents swap should
be added here. | 1496 * All initialization that needs to reoccur after a web contents swap should
be added here. |
| 1495 * <p /> | 1497 * <p /> |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1511 | 1513 |
| 1512 // Wrap the ContentView in a FrameLayout, which will contain both th
e ContentView and | 1514 // Wrap the ContentView in a FrameLayout, which will contain both th
e ContentView and |
| 1513 // the InfoBarContainer. The alternative -- placing the InfoBarConta
iner inside the | 1515 // the InfoBarContainer. The alternative -- placing the InfoBarConta
iner inside the |
| 1514 // ContentView -- causes problems since then the ContentView would c
ontain both real | 1516 // ContentView -- causes problems since then the ContentView would c
ontain both real |
| 1515 // views (the infobars) and virtual views (the web page elements), w
hich breaks Android | 1517 // views (the infobars) and virtual views (the web page elements), w
hich breaks Android |
| 1516 // accessibility. http://crbug.com/416663 | 1518 // accessibility. http://crbug.com/416663 |
| 1517 if (mContentViewParent != null) { | 1519 if (mContentViewParent != null) { |
| 1518 assert false; | 1520 assert false; |
| 1519 mContentViewParent.removeAllViews(); | 1521 mContentViewParent.removeAllViews(); |
| 1520 } | 1522 } |
| 1521 mContentViewParent = new FrameLayout(mActivity); | 1523 mContentViewParent = new FrameLayout(mThemedApplicationContext); |
| 1522 mContentViewParent.addView(cvc.getContainerView(), | 1524 mContentViewParent.addView(cvc.getContainerView(), |
| 1523 new FrameLayout.LayoutParams( | 1525 new FrameLayout.LayoutParams( |
| 1524 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT
)); | 1526 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT
)); |
| 1525 | 1527 |
| 1526 mWebContentsDelegate = mDelegateFactory.createWebContentsDelegate(th
is, mActivity); | 1528 mWebContentsDelegate = mDelegateFactory.createWebContentsDelegate(th
is, mActivity); |
| 1527 mWebContentsObserver = | 1529 mWebContentsObserver = |
| 1528 new TabWebContentsObserver(mContentViewCore.getWebContents()
, this); | 1530 new TabWebContentsObserver(mContentViewCore.getWebContents()
, this); |
| 1529 | 1531 |
| 1530 if (mContentViewClient != null) { | 1532 if (mContentViewClient != null) { |
| 1531 mContentViewCore.setContentViewClient(mContentViewClient); | 1533 mContentViewCore.setContentViewClient(mContentViewClient); |
| 1532 } | 1534 } |
| 1533 | 1535 |
| 1534 assert mNativeTabAndroid != 0; | 1536 assert mNativeTabAndroid != 0; |
| 1535 nativeInitWebContents( | 1537 nativeInitWebContents( |
| 1536 mNativeTabAndroid, mIncognito, mContentViewCore, mWebContent
sDelegate, | 1538 mNativeTabAndroid, mIncognito, mContentViewCore, mWebContent
sDelegate, |
| 1537 new TabContextMenuPopulator( | 1539 new TabContextMenuPopulator( |
| 1538 mDelegateFactory.createContextMenuPopulator(this, mA
ctivity), this)); | 1540 mDelegateFactory.createContextMenuPopulator(this, mA
ctivity), this)); |
| 1539 | 1541 |
| 1540 // In the case where restoring a Tab or showing a prerendered one we
already have a | 1542 // In the case where restoring a Tab or showing a prerendered one we
already have a |
| 1541 // valid infobar container, no need to recreate one. | 1543 // valid infobar container, no need to recreate one. |
| 1542 if (mInfoBarContainer == null) { | 1544 if (mInfoBarContainer == null) { |
| 1543 // The InfoBarContainer needs to be created after the ContentVie
w has been natively | 1545 // The InfoBarContainer needs to be created after the ContentVie
w has been natively |
| 1544 // initialized. | 1546 // initialized. |
| 1545 mInfoBarContainer = | 1547 mInfoBarContainer = new InfoBarContainer( |
| 1546 new InfoBarContainer(mActivity, getId(), mContentViewPar
ent, this); | 1548 mThemedApplicationContext, getId(), mContentViewParent,
this); |
| 1547 } else { | 1549 } else { |
| 1548 mInfoBarContainer.onParentViewChanged(getId(), mContentViewParen
t); | 1550 mInfoBarContainer.onParentViewChanged(getId(), mContentViewParen
t); |
| 1549 } | 1551 } |
| 1550 mInfoBarContainer.setContentViewCore(mContentViewCore); | 1552 mInfoBarContainer.setContentViewCore(mContentViewCore); |
| 1551 | 1553 |
| 1552 mSwipeRefreshHandler = new SwipeRefreshHandler(mActivity); | 1554 mSwipeRefreshHandler = new SwipeRefreshHandler(mThemedApplicationCon
text); |
| 1553 mSwipeRefreshHandler.setContentViewCore(mContentViewCore); | 1555 mSwipeRefreshHandler.setContentViewCore(mContentViewCore); |
| 1554 | 1556 |
| 1555 for (TabObserver observer : mObservers) observer.onContentChanged(th
is); | 1557 for (TabObserver observer : mObservers) observer.onContentChanged(th
is); |
| 1556 | 1558 |
| 1557 // For browser tabs, we want to set accessibility focus to the page | 1559 // For browser tabs, we want to set accessibility focus to the page |
| 1558 // when it loads. This is not the default behavior for embedded | 1560 // when it loads. This is not the default behavior for embedded |
| 1559 // web views. | 1561 // web views. |
| 1560 mContentViewCore.setShouldSetAccessibilityFocusOnPageLoad(true); | 1562 mContentViewCore.setShouldSetAccessibilityFocusOnPageLoad(true); |
| 1561 | 1563 |
| 1562 mDownloadDelegate = new ChromeDownloadDelegate(mActivity, | 1564 mDownloadDelegate = new ChromeDownloadDelegate(mThemedApplicationCon
text, |
| 1563 mActivity.getTabModelSelector(), this); | 1565 mActivity.getTabModelSelector(), this); |
| 1564 cvc.setDownloadDelegate(mDownloadDelegate); | 1566 cvc.setDownloadDelegate(mDownloadDelegate); |
| 1565 | 1567 |
| 1566 setInterceptNavigationDelegate(mDelegateFactory | 1568 setInterceptNavigationDelegate(mDelegateFactory |
| 1567 .createInterceptNavigationDelegate(this, mActivity)); | 1569 .createInterceptNavigationDelegate(this, mActivity)); |
| 1568 | 1570 |
| 1569 if (mGestureStateListener == null) { | 1571 if (mGestureStateListener == null) { |
| 1570 mGestureStateListener = createGestureStateListener(); | 1572 mGestureStateListener = createGestureStateListener(); |
| 1571 } | 1573 } |
| 1572 cvc.addGestureStateListener(mGestureStateListener); | 1574 cvc.addGestureStateListener(mGestureStateListener); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 OnClickListener reloadButtonAction = new OnClickListener() { | 1636 OnClickListener reloadButtonAction = new OnClickListener() { |
| 1635 @Override | 1637 @Override |
| 1636 public void onClick(View view) { | 1638 public void onClick(View view) { |
| 1637 reload(); | 1639 reload(); |
| 1638 } | 1640 } |
| 1639 }; | 1641 }; |
| 1640 | 1642 |
| 1641 // Make sure we are not adding the "Aw, snap" view over an existing
one. | 1643 // Make sure we are not adding the "Aw, snap" view over an existing
one. |
| 1642 assert mSadTabView == null; | 1644 assert mSadTabView == null; |
| 1643 mSadTabView = SadTabViewFactory.createSadTabView( | 1645 mSadTabView = SadTabViewFactory.createSadTabView( |
| 1644 mActivity, suggestionAction, reloadButtonAction); | 1646 mThemedApplicationContext, suggestionAction, reloadButtonAct
ion); |
| 1645 | 1647 |
| 1646 // Show the sad tab inside ContentView. | 1648 // Show the sad tab inside ContentView. |
| 1647 getContentViewCore().getContainerView().addView( | 1649 getContentViewCore().getContainerView().addView( |
| 1648 mSadTabView, new FrameLayout.LayoutParams( | 1650 mSadTabView, new FrameLayout.LayoutParams( |
| 1649 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT
)); | 1651 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT
)); |
| 1650 for (TabObserver observer : mObservers) observer.onContentChanged(th
is); | 1652 for (TabObserver observer : mObservers) observer.onContentChanged(th
is); |
| 1651 } | 1653 } |
| 1652 FullscreenManager fullscreenManager = getFullscreenManager(); | 1654 FullscreenManager fullscreenManager = getFullscreenManager(); |
| 1653 if (fullscreenManager != null) { | 1655 if (fullscreenManager != null) { |
| 1654 fullscreenManager.setPositionsForTabToNonFullscreen(); | 1656 fullscreenManager.setPositionsForTabToNonFullscreen(); |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2131 @CalledByNative | 2133 @CalledByNative |
| 2132 private long getNativePtr() { | 2134 private long getNativePtr() { |
| 2133 return mNativeTabAndroid; | 2135 return mNativeTabAndroid; |
| 2134 } | 2136 } |
| 2135 | 2137 |
| 2136 /** This is currently called when committing a pre-rendered page. */ | 2138 /** This is currently called when committing a pre-rendered page. */ |
| 2137 @VisibleForTesting | 2139 @VisibleForTesting |
| 2138 @CalledByNative | 2140 @CalledByNative |
| 2139 public void swapWebContents( | 2141 public void swapWebContents( |
| 2140 WebContents webContents, boolean didStartLoad, boolean didFinishLoad
) { | 2142 WebContents webContents, boolean didStartLoad, boolean didFinishLoad
) { |
| 2141 ContentViewCore cvc = new ContentViewCore(mActivity); | 2143 ContentViewCore cvc = new ContentViewCore(mThemedApplicationContext); |
| 2142 ContentView cv = ContentView.createContentView(mActivity, cvc); | 2144 ContentView cv = ContentView.createContentView(mThemedApplicationContext
, cvc); |
| 2143 cv.setContentDescription(mActivity.getResources().getString( | 2145 cv.setContentDescription(mThemedApplicationContext.getResources().getStr
ing( |
| 2144 R.string.accessibility_content_view)); | 2146 R.string.accessibility_content_view)); |
| 2145 cvc.initialize(cv, cv, webContents, getWindowAndroid()); | 2147 cvc.initialize(cv, cv, webContents, getWindowAndroid()); |
| 2146 swapContentViewCore(cvc, false, didStartLoad, didFinishLoad); | 2148 swapContentViewCore(cvc, false, didStartLoad, didFinishLoad); |
| 2147 } | 2149 } |
| 2148 | 2150 |
| 2149 /** | 2151 /** |
| 2150 * Called to swap out the current view with the one passed in. | 2152 * Called to swap out the current view with the one passed in. |
| 2151 * | 2153 * |
| 2152 * @param newContentViewCore The content view that should be swapped into th
e tab. | 2154 * @param newContentViewCore The content view that should be swapped into th
e tab. |
| 2153 * @param deleteOldNativeWebContents Whether to delete the native web | 2155 * @param deleteOldNativeWebContents Whether to delete the native web |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2860 private native void nativeSetInterceptNavigationDelegate(long nativeTabAndro
id, | 2862 private native void nativeSetInterceptNavigationDelegate(long nativeTabAndro
id, |
| 2861 InterceptNavigationDelegate delegate); | 2863 InterceptNavigationDelegate delegate); |
| 2862 private native void nativeAttachToTabContentManager(long nativeTabAndroid, | 2864 private native void nativeAttachToTabContentManager(long nativeTabAndroid, |
| 2863 TabContentManager tabContentManager); | 2865 TabContentManager tabContentManager); |
| 2864 private native void nativeAttachOverlayContentViewCore(long nativeTabAndroid
, | 2866 private native void nativeAttachOverlayContentViewCore(long nativeTabAndroid
, |
| 2865 ContentViewCore content, boolean visible); | 2867 ContentViewCore content, boolean visible); |
| 2866 private native void nativeDetachOverlayContentViewCore(long nativeTabAndroid
, | 2868 private native void nativeDetachOverlayContentViewCore(long nativeTabAndroid
, |
| 2867 ContentViewCore content); | 2869 ContentViewCore content); |
| 2868 private native boolean nativeHasPrerenderedUrl(long nativeTabAndroid, String
url); | 2870 private native boolean nativeHasPrerenderedUrl(long nativeTabAndroid, String
url); |
| 2869 } | 2871 } |
| OLD | NEW |