blob: 31dbfd3aefa51977c777e8440b649dbf1427ca4b [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.weblayer_private;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import org.chromium.base.ContextUtils;
import org.chromium.components.external_intents.ExternalNavigationDelegate;
import org.chromium.components.external_intents.ExternalNavigationDelegate.StartActivityIfNeededResult;
import org.chromium.components.external_intents.ExternalNavigationHandler;
import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
import org.chromium.components.external_intents.ExternalNavigationParams;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.base.WindowAndroid;
/**
* WebLayer's implementation of the {@link ExternalNavigationDelegate}.
*/
public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegate {
private final TabImpl mTab;
private boolean mTabDestroyed;
public ExternalNavigationDelegateImpl(TabImpl tab) {
mTab = tab;
}
public void onTabDestroyed() {
mTabDestroyed = true;
}
@Override
public Activity getActivityContext() {
return ContextUtils.activityFromContext(mTab.getBrowser().getContext());
}
private Context getAvailableContext() {
return ExternalNavigationHandler.getAvailableContext(this);
}
@Override
public boolean willChromeHandleIntent(Intent intent) {
return false;
}
@Override
public boolean shouldDisableExternalIntentRequestsForUrl(String url) {
return false;
}
@Override
public boolean handlesInstantAppLaunchingInternally() {
return false;
}
@Override
public void dispatchAuthenticatedIntent(Intent intent) {
// This method should never be invoked in WebLayer as this class always returns false for
// isIntentToInstantApp().
assert false;
}
@Override
public void didStartActivity(Intent intent) {}
@Override
public @StartActivityIfNeededResult int maybeHandleStartActivityIfNeeded(
Intent intent, boolean proxy) {
assert !proxy
: "|proxy| should be true only for instant apps, which WebLayer doesn't handle";
return StartActivityIfNeededResult.DID_NOT_HANDLE;
}
@Override
public boolean startIncognitoIntent(final Intent intent, final String referrerUrl,
final String fallbackUrl, final boolean needsToCloseTab, final boolean proxy) {
// TODO(crbug.com/1063399): Determine if this behavior should be refined.
ExternalNavigationHandler.startActivity(intent, proxy, this);
return true;
}
// This method should never be invoked as WebLayer does not handle incoming intents.
@Override
public @OverrideUrlLoadingResult int handleIncognitoIntentTargetingSelf(
final Intent intent, final String referrerUrl, final String fallbackUrl) {
assert false;
return OverrideUrlLoadingResult.NO_OVERRIDE;
}
@Override
public void loadUrlIfPossible(LoadUrlParams loadUrlParams) {
if (!hasValidTab()) return;
mTab.loadUrl(loadUrlParams);
}
@Override
public boolean isChromeAppInForeground() {
return mTab.getBrowser().isResumed();
}
@Override
public void maybeSetWindowId(Intent intent) {}
@Override
public boolean supportsCreatingNewTabs() {
// In WebLayer all URLs that ExternalNavigationHandler loads internally are loaded within
// the current tab; this flow is sufficient for WebLayer from a UX POV, and there is no
// reason to add the complexity of a flow to create new tabs here. In particular, in Chrome
// that new tab creation is done by launching an activity targeted at the Chrome package.
// This would not work for WebLayer as the embedder does not in general handle incoming
// browsing intents.
return false;
}
@Override
public void loadUrlInNewTab(final String url, final boolean launchIncognito) {
// Should never be invoked based on the implementation of supportsCreatingNewTabs().
assert false;
}
@Override
public boolean canLoadUrlInCurrentTab() {
return true;
}
@Override
public void closeTab() {
InterceptNavigationDelegateClientImpl.closeTab(mTab);
}
@Override
public boolean isIncognito() {
return mTab.getProfile().isIncognito();
}
@Override
public void maybeAdjustInstantAppExtras(Intent intent, boolean isIntentToInstantApp) {}
@Override
// This is relevant only if the intent ends up being handled by this app, which does not happen
// for WebLayer.
public void maybeSetUserGesture(Intent intent) {}
@Override
// This is relevant only if the intent ends up being handled by this app, which does not happen
// for WebLayer.
public void maybeSetPendingReferrer(Intent intent, String referrerUrl) {}
@Override
// This is relevant only if the intent ends up being handled by this app, which does not happen
// for WebLayer.
public void maybeSetPendingIncognitoUrl(Intent intent) {}
@Override
public boolean maybeLaunchInstantApp(
String url, String referrerUrl, boolean isIncomingRedirect, boolean isSerpReferrer) {
return false;
}
@Override
public WindowAndroid getWindowAndroid() {
if (mTab == null) return null;
return mTab.getBrowser().getWindowAndroid();
}
@Override
public WebContents getWebContents() {
if (mTab == null) return null;
return mTab.getWebContents();
}
@Override
public boolean hasValidTab() {
assert mTab != null;
return !mTabDestroyed;
}
@Override
public boolean isIntentForTrustedCallingApp(Intent intent) {
return false;
}
@Override
public boolean isIntentToInstantApp(Intent intent) {
return false;
}
@Override
public boolean isIntentToAutofillAssistant(Intent intent) {
return false;
}
@Override
public boolean isValidWebApk(String packageName) {
// TODO(crbug.com/1063874): Determine whether to refine this.
return false;
}
@Override
public boolean handleWithAutofillAssistant(ExternalNavigationParams params, Intent targetIntent,
String browserFallbackUrl, boolean isGoogleReferrer) {
return false;
}
}