Commit 81cef30e authored by Colin Blundell's avatar Colin Blundell Committed by Commit Bot

[Android] Abstract most of InterceptNavigationDelegateImpl's Tab deps

This CL abstracts the bulk of InterceptNavigationDelegateImpl's
remaining deps on Tab through InterceptNavigationDelegateClient to
support reuse of InterceptNavigationDelegateImpl by WebLayer. The one
remaining dep is the observance of Tab via EmptyTabObserver, which is
complex enough to warrant its own CL.

As part of this CL, we change InterceptNavigationDelegateImpl from
obtaining the //chrome-level AuthenticatorNavigationInterceptor via
AppHooks#createAuthenticatorNavigationInterceptor() to obtaining the
//components-level AuthenticatorNavigationInterceptor via
AppHooks#createAuthenticatorNavigationInterceptorV2(). The two methods
return the same object in their downstream implementations (an impl
that implements both identical interfaces), so this change has no
behavioral impact; it is necessary as the //components-level Client
interface can refer only to the //components-level
AuthenticatorNavigationInterceptor interface.

Bug: 1031465
Change-Id: I7e69fadf4fc563e9d2839311d5aabe9856517532
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2134233
Commit-Queue: Colin Blundell <blundell@chromium.org>
Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#758483}
parent f706c50e
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
package org.chromium.chrome.browser.tab; package org.chromium.chrome.browser.tab;
import org.chromium.components.external_intents.AuthenticatorNavigationInterceptor;
/** /**
* Temporary wrapper to isolate downstream from the exact API surfaces used to get an * Temporary wrapper to isolate downstream from the exact API surfaces used to get an
* AuthenticatorNavigationInterceptor instance from a Tab while those API surfaces are being * AuthenticatorNavigationInterceptor instance from a Tab while those API surfaces are being
......
...@@ -26,6 +26,10 @@ include_rules = [ ...@@ -26,6 +26,10 @@ include_rules = [
] ]
specific_include_rules = { specific_include_rules = {
'InterceptNavigationDelegateClientImpl\.java': [
"+chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java",
"+chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelector.java",
],
'RedirectHandlerTabHelper\.java': [ 'RedirectHandlerTabHelper\.java': [
"+chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java", "+chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java",
"+chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java", "+chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java",
......
...@@ -4,7 +4,15 @@ ...@@ -4,7 +4,15 @@
package org.chromium.chrome.browser.tab; package org.chromium.chrome.browser.tab;
import android.app.Activity;
import org.chromium.chrome.browser.AppHooks;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.components.external_intents.AuthenticatorNavigationInterceptor;
import org.chromium.components.external_intents.ExternalNavigationHandler;
import org.chromium.components.external_intents.InterceptNavigationDelegateClient; import org.chromium.components.external_intents.InterceptNavigationDelegateClient;
import org.chromium.components.external_intents.RedirectHandlerImpl;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
/** /**
...@@ -22,4 +30,58 @@ public class InterceptNavigationDelegateClientImpl implements InterceptNavigatio ...@@ -22,4 +30,58 @@ public class InterceptNavigationDelegateClientImpl implements InterceptNavigatio
public WebContents getWebContents() { public WebContents getWebContents() {
return mTab.getWebContents(); return mTab.getWebContents();
} }
@Override
public ExternalNavigationHandler createExternalNavigationHandler() {
return mTab.getDelegateFactory().createExternalNavigationHandler(mTab);
}
@Override
public long getLastUserInteractionTime() {
ChromeActivity associatedActivity = mTab.getActivity();
return (associatedActivity == null) ? -1 : associatedActivity.getLastUserInteractionTime();
}
@Override
public RedirectHandlerImpl getOrCreateRedirectHandler() {
return RedirectHandlerTabHelper.getOrCreateHandlerFor(mTab);
}
@Override
public AuthenticatorNavigationInterceptor createAuthenticatorNavigationInterceptor() {
// NOTE: This will be transitioned back to calling
// AppHooks#createAuthenticatorNavigationInterceptor() once the latter has been transitioned
// to talk in terms of the //components-level interface.
return AppHooks.get().createAuthenticatorNavigationInterceptorV2(mTab);
}
@Override
public boolean isIncognito() {
return mTab.isIncognito();
}
@Override
public boolean isHidden() {
return mTab.isHidden();
}
@Override
public Activity getActivity() {
return mTab.getActivity();
}
@Override
public boolean wasTabLaunchedFromExternalApp() {
return mTab.getLaunchType() == TabLaunchType.FROM_EXTERNAL_APP;
}
@Override
public boolean wasTabLaunchedFromLongPressInBackground() {
return mTab.getLaunchType() == TabLaunchType.FROM_LONGPRESS_BACKGROUND;
}
@Override
public void closeTab() {
TabModelSelector.from(mTab).closeTab(mTab);
}
} }
...@@ -12,9 +12,7 @@ import org.chromium.base.annotations.NativeMethods; ...@@ -12,9 +12,7 @@ import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.task.PostTask; import org.chromium.base.task.PostTask;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.AppHooks; import org.chromium.components.external_intents.AuthenticatorNavigationInterceptor;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.components.external_intents.ExternalNavigationHandler; import org.chromium.components.external_intents.ExternalNavigationHandler;
import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult; import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
import org.chromium.components.external_intents.ExternalNavigationParams; import org.chromium.components.external_intents.ExternalNavigationParams;
...@@ -60,7 +58,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg ...@@ -60,7 +58,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
InterceptNavigationDelegateImpl(Tab tab, InterceptNavigationDelegateClient client) { InterceptNavigationDelegateImpl(Tab tab, InterceptNavigationDelegateClient client) {
mTab = (TabImpl) tab; mTab = (TabImpl) tab;
mClient = client; mClient = client;
mAuthenticatorHelper = AppHooks.get().createAuthenticatorNavigationInterceptor(mTab); mAuthenticatorHelper = mClient.createAuthenticatorNavigationInterceptor();
mDelegateObserver = new EmptyTabObserver() { mDelegateObserver = new EmptyTabObserver() {
@Override @Override
public void onContentChanged(Tab tab) { public void onContentChanged(Tab tab) {
...@@ -70,8 +68,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg ...@@ -70,8 +68,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
@Override @Override
public void onActivityAttachmentChanged(Tab tab, @Nullable WindowAndroid window) { public void onActivityAttachmentChanged(Tab tab, @Nullable WindowAndroid window) {
if (window != null) { if (window != null) {
setExternalNavigationHandler( setExternalNavigationHandler(mClient.createExternalNavigationHandler());
mTab.getDelegateFactory().createExternalNavigationHandler(tab));
} }
} }
...@@ -106,8 +103,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg ...@@ -106,8 +103,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
// Lazily initialize the external navigation handler. // Lazily initialize the external navigation handler.
if (mExternalNavHandler == null) { if (mExternalNavHandler == null) {
setExternalNavigationHandler( setExternalNavigationHandler(mClient.createExternalNavigationHandler());
mTab.getDelegateFactory().createExternalNavigationHandler(mTab));
} }
InterceptNavigationDelegateImplJni.get().associateWithWebContents(this, mWebContents); InterceptNavigationDelegateImplJni.get().associateWithWebContents(this, mWebContents);
} }
...@@ -133,9 +129,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg ...@@ -133,9 +129,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
@Override @Override
public boolean shouldIgnoreNavigation(NavigationParams navigationParams) { public boolean shouldIgnoreNavigation(NavigationParams navigationParams) {
String url = navigationParams.url; String url = navigationParams.url;
ChromeActivity associatedActivity = mTab.getActivity(); long lastUserInteractionTime = mClient.getLastUserInteractionTime();
long lastUserInteractionTime =
(associatedActivity == null) ? -1 : associatedActivity.getLastUserInteractionTime();
if (mAuthenticatorHelper != null && mAuthenticatorHelper.handleAuthenticatorUrl(url)) { if (mAuthenticatorHelper != null && mAuthenticatorHelper.handleAuthenticatorUrl(url)) {
return true; return true;
...@@ -143,7 +137,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg ...@@ -143,7 +137,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
RedirectHandlerImpl redirectHandler = null; RedirectHandlerImpl redirectHandler = null;
if (navigationParams.isMainFrame) { if (navigationParams.isMainFrame) {
redirectHandler = RedirectHandlerTabHelper.getOrCreateHandlerFor(mTab); redirectHandler = mClient.getOrCreateRedirectHandler();
} else if (navigationParams.isExternalProtocol) { } else if (navigationParams.isExternalProtocol) {
// Only external protocol navigations are intercepted for iframe navigations. Since // Only external protocol navigations are intercepted for iframe navigations. Since
// we do not see all previous navigations for the iframe, we can not build a complete // we do not see all previous navigations for the iframe, we can not build a complete
...@@ -208,16 +202,16 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg ...@@ -208,16 +202,16 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
NavigationParams navigationParams, RedirectHandlerImpl redirectHandler, NavigationParams navigationParams, RedirectHandlerImpl redirectHandler,
boolean shouldCloseTab) { boolean shouldCloseTab) {
boolean isInitialTabLaunchInBackground = boolean isInitialTabLaunchInBackground =
mTab.getLaunchType() == TabLaunchType.FROM_LONGPRESS_BACKGROUND && shouldCloseTab; mClient.wasTabLaunchedFromLongPressInBackground() && shouldCloseTab;
// http://crbug.com/448977: If a new tab is closed by this overriding, we should open an // http://crbug.com/448977: If a new tab is closed by this overriding, we should open an
// Intent in a new tab when Chrome receives it again. // Intent in a new tab when Chrome receives it again.
return new ExternalNavigationParams return new ExternalNavigationParams
.Builder(navigationParams.url, mTab.isIncognito(), navigationParams.referrer, .Builder(navigationParams.url, mClient.isIncognito(), navigationParams.referrer,
navigationParams.pageTransitionType, navigationParams.isRedirect) navigationParams.pageTransitionType, navigationParams.isRedirect)
.setApplicationMustBeInForeground(true) .setApplicationMustBeInForeground(true)
.setRedirectHandler(redirectHandler) .setRedirectHandler(redirectHandler)
.setOpenInNewTab(shouldCloseTab) .setOpenInNewTab(shouldCloseTab)
.setIsBackgroundTabNavigation(mTab.isHidden() && !isInitialTabLaunchInBackground) .setIsBackgroundTabNavigation(mClient.isHidden() && !isInitialTabLaunchInBackground)
.setIsMainFrame(navigationParams.isMainFrame) .setIsMainFrame(navigationParams.isMainFrame)
.setHasUserGesture(navigationParams.hasUserGesture) .setHasUserGesture(navigationParams.hasUserGesture)
.setShouldCloseContentsOnOverrideUrlLoadingAndLaunchIntent( .setShouldCloseContentsOnOverrideUrlLoadingAndLaunchIntent(
...@@ -240,7 +234,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg ...@@ -240,7 +234,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
NavigationController navigationController = NavigationController navigationController =
webContents.getNavigationController(); webContents.getNavigationController();
int indexBeforeRedirection = int indexBeforeRedirection =
RedirectHandlerTabHelper.getOrCreateHandlerFor(mTab) mClient.getOrCreateRedirectHandler()
.getLastCommittedEntryIndexBeforeStartingNavigation(); .getLastCommittedEntryIndexBeforeStartingNavigation();
int lastCommittedEntryIndex = getLastCommittedEntryIndex(); int lastCommittedEntryIndex = getLastCommittedEntryIndex();
for (int i = lastCommittedEntryIndex - 1; i > indexBeforeRedirection; --i) { for (int i = lastCommittedEntryIndex - 1; i > indexBeforeRedirection; --i) {
...@@ -270,8 +264,8 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg ...@@ -270,8 +264,8 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
// navigation is invalid, it means that this navigation is the first one since this tab was // navigation is invalid, it means that this navigation is the first one since this tab was
// created. // created.
// In such case, we would like to close this tab. // In such case, we would like to close this tab.
if (RedirectHandlerTabHelper.getOrCreateHandlerFor(mTab).isOnNavigation()) { if (mClient.getOrCreateRedirectHandler().isOnNavigation()) {
return RedirectHandlerTabHelper.getOrCreateHandlerFor(mTab) return mClient.getOrCreateRedirectHandler()
.getLastCommittedEntryIndexBeforeStartingNavigation() .getLastCommittedEntryIndexBeforeStartingNavigation()
== RedirectHandlerImpl.INVALID_ENTRY_INDEX; == RedirectHandlerImpl.INVALID_ENTRY_INDEX;
} }
...@@ -291,23 +285,23 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg ...@@ -291,23 +285,23 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
// url, we would like to close it as we will load this url in a // url, we would like to close it as we will load this url in a
// different Activity. // different Activity.
if (shouldCloseTab) { if (shouldCloseTab) {
if (mTab.getLaunchType() == TabLaunchType.FROM_EXTERNAL_APP) { if (mClient.wasTabLaunchedFromExternalApp()) {
// Moving task back before closing the tab allows back button to function better // Moving task back before closing the tab allows back button to function better
// when Chrome was an intermediate link redirector between two apps. // when Chrome was an intermediate link redirector between two apps.
// crbug.com/487938. // crbug.com/487938.
mTab.getActivity().moveTaskToBack(false); mClient.getActivity().moveTaskToBack(false);
} }
// Defer closing a tab (and the associated WebContents) till the navigation // Defer closing a tab (and the associated WebContents) till the navigation
// request and the throttle finishes the job with it. // request and the throttle finishes the job with it.
PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() {
@Override @Override
public void run() { public void run() {
TabModelSelector.from(mTab).closeTab(mTab); mClient.closeTab();
} }
}); });
} else if (RedirectHandlerTabHelper.getOrCreateHandlerFor(mTab).isOnNavigation()) { } else if (mClient.getOrCreateRedirectHandler().isOnNavigation()) {
int lastCommittedEntryIndexBeforeNavigation = int lastCommittedEntryIndexBeforeNavigation =
RedirectHandlerTabHelper.getOrCreateHandlerFor(mTab) mClient.getOrCreateRedirectHandler()
.getLastCommittedEntryIndexBeforeStartingNavigation(); .getLastCommittedEntryIndexBeforeStartingNavigation();
if (getLastCommittedEntryIndex() > lastCommittedEntryIndexBeforeNavigation) { if (getLastCommittedEntryIndex() > lastCommittedEntryIndexBeforeNavigation) {
// http://crbug/426679 : we want to go back to the last committed entry index which // http://crbug/426679 : we want to go back to the last committed entry index which
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
package org.chromium.components.external_intents; package org.chromium.components.external_intents;
import android.app.Activity;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
/** /**
...@@ -11,5 +13,40 @@ import org.chromium.content_public.browser.WebContents; ...@@ -11,5 +13,40 @@ import org.chromium.content_public.browser.WebContents;
* InterceptNavigationDelegateImpl needs. * InterceptNavigationDelegateImpl needs.
*/ */
public interface InterceptNavigationDelegateClient { public interface InterceptNavigationDelegateClient {
/* Returns the WebContents in the context of which this InterceptNavigationDelegateImpl instance
* is operating. */
WebContents getWebContents(); WebContents getWebContents();
/* Creates an ExternalNavigationHandler instance that is configured for this client. */
ExternalNavigationHandler createExternalNavigationHandler();
/* Returns the time of the user's last interaction with the app. */
long getLastUserInteractionTime();
/* Gets a RedirectHandlerImpl instance that is associated with this client, creating it if
* necessary. */
RedirectHandlerImpl getOrCreateRedirectHandler();
/* Creates an AuthenticatorNavigationInterceptor instance that is configured for this client.
*/
AuthenticatorNavigationInterceptor createAuthenticatorNavigationInterceptor();
/* Returns whether whether the tab associated with this client is incognito. */
boolean isIncognito();
/* Returns whether whether the tab associated with this client is currently hidden. */
boolean isHidden();
/* Returns the Activity associated with this client. */
Activity getActivity();
/* Returns true if the tab associated with this client was launched from an external app. */
boolean wasTabLaunchedFromExternalApp();
/* Returns true if the tab associated with this client was launched from a long press in the
* background. */
boolean wasTabLaunchedFromLongPressInBackground();
/* Invoked when the tab associated with this client should be closed. */
void closeTab();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment