| // Copyright 2015 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.components.external_intents; |
| |
| import android.content.Context; |
| import android.content.Intent; |
| |
| import androidx.annotation.IntDef; |
| import androidx.annotation.NonNull; |
| import androidx.annotation.Nullable; |
| |
| import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult; |
| import org.chromium.content_public.browser.LoadUrlParams; |
| import org.chromium.content_public.browser.WebContents; |
| import org.chromium.ui.base.WindowAndroid; |
| import org.chromium.url.Origin; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| |
| /** |
| * A delegate for {@link ExternalNavigationHandler}. |
| */ |
| public interface ExternalNavigationDelegate { |
| /** |
| * Returns the Context with which this delegate is associated, or null if there is no such |
| * Context at the time of invocation. The returned Context may or may not be a wrapper around an |
| * Activity with which the delegate is associated. Note that when obtaining resources, however, |
| * the handler should do so directly via the returned Context (i.e., not via the Activity that |
| * it is wrapping, even if it is in fact wrapping one). The reason is that some embedders handle |
| * resource fetching via special logic in the ContextWrapper object that is wrapping the |
| * Activity. |
| */ |
| Context getContext(); |
| |
| /** |
| * Determine if this app is the default or only handler for a given intent. If true, this app |
| * will handle the intent when started. |
| */ |
| boolean willAppHandleIntent(Intent intent); |
| |
| /** |
| * Returns whether to disable forwarding URL requests to external intents for the passed-in URL. |
| */ |
| boolean shouldDisableExternalIntentRequestsForUrl(String url); |
| |
| /** |
| * Returns whether the embedder has custom integration with InstantApps (most embedders will not |
| * have any such integration). |
| */ |
| boolean handlesInstantAppLaunchingInternally(); |
| |
| /** |
| * Dispatches the intent through a proxy activity, so that startActivityForResult can be used |
| * and the intent recipient can verify the caller. Will be invoked only in flows where |
| * ExternalNavigationDelegate#isIntentForInstantApp() returns true for |intent|. In particular, |
| * if that method always returns false in the given embedder, then the embedder's implementation |
| * of this method will never be invoked and can just assert false. |
| * @param intent The bare intent we were going to send. |
| */ |
| void dispatchAuthenticatedIntent(Intent intent); |
| |
| /** |
| * Informs the delegate that an Activity was started for an external intent (some embedders wish |
| * to log this information, primarily for testing purposes). |
| */ |
| void didStartActivity(Intent intent); |
| |
| /** |
| * Used by maybeHandleStartActivityIfNeeded() below. |
| */ |
| @IntDef({StartActivityIfNeededResult.HANDLED_WITH_ACTIVITY_START, |
| StartActivityIfNeededResult.HANDLED_WITHOUT_ACTIVITY_START, |
| StartActivityIfNeededResult.DID_NOT_HANDLE}) |
| @Retention(RetentionPolicy.SOURCE) |
| public @interface StartActivityIfNeededResult { |
| int HANDLED_WITH_ACTIVITY_START = 0; |
| int HANDLED_WITHOUT_ACTIVITY_START = 1; |
| int DID_NOT_HANDLE = 2; |
| } |
| |
| /** |
| * Gives the embedder the opportunity to handle starting an activity for the intent. Used for |
| * intents that may be handled internally or externally. If the embedder handles this intent, |
| * this method should return StartActivityIfNeededResult.HANDLED_{WITH, WITHOUT}_ACTIVITY_START |
| * as appropriate. To have ExternalNavigationHandler handle this intent, return |
| * StartActivityIfNeededResult.NOT_HANDLED. |
| * @param intent The intent we want to send. |
| * @param proxy Whether we need to proxy the intent through AuthenticatedProxyActivity (this is |
| * used by Instant Apps intents). |
| */ |
| @StartActivityIfNeededResult |
| int maybeHandleStartActivityIfNeeded(Intent intent, boolean proxy); |
| |
| /** |
| * Handle the incognito intent by loading it as a URL in the embedder, using the fallbackUrl if |
| * the intent URL cannot be handled by the embedder. |
| * @param intent The intent to be handled by the embedder. |
| * @param referrerUrl The referrer for the current navigation. |
| * @param fallbackUrl The fallback URL to load if the intent cannot be handled by the embedder. |
| * @return The OverrideUrlLoadingResult for the action taken by the embedder. |
| */ |
| @OverrideUrlLoadingResult |
| int handleIncognitoIntentTargetingSelf(Intent intent, String referrerUrl, String fallbackUrl); |
| |
| /** |
| * Loads a URL as specified by |loadUrlParams| if possible. May fail in exceptional conditions |
| * (e.g., if there is no valid tab). |
| * @param loadUrlParams parameters of the URL to be loaded |
| */ |
| void loadUrlIfPossible(LoadUrlParams loadUrlParams); |
| |
| /** Adds a window id to the intent, if necessary. */ |
| void maybeSetWindowId(Intent intent); |
| |
| /** Records the pending referrer if desired. */ |
| void maybeSetPendingReferrer(Intent intent, @NonNull String referrerUrl); |
| |
| /** |
| * Adjusts any desired extras related to intents to instant apps based on the value of |
| * |insIntentToInstantApp}. |
| */ |
| void maybeAdjustInstantAppExtras(Intent intent, boolean isIntentToInstantApp); |
| |
| /** |
| * Invoked for intents with request metadata such as user gesture, whether request is renderer |
| * initiated and the initiator origin. Records the information if desired. |
| */ |
| void maybeSetRequestMetadata(Intent intent, boolean hasUserGesture, boolean isRendererInitiated, |
| @Nullable Origin initiatorOrigin); |
| |
| /** |
| * Records the pending incognito URL if desired. Called only if the |
| * navigation is occurring in the context of incognito mode. |
| */ |
| void maybeSetPendingIncognitoUrl(Intent intent); |
| |
| /** |
| * Determine if the application of the embedder is in the foreground. |
| */ |
| boolean isApplicationInForeground(); |
| |
| /** |
| * Check if the URL should be handled by an instant app, or kick off an async request for an |
| * instant app banner. |
| * @param url The current URL. |
| * @param referrerUrl The referrer URL. |
| * @param isIncomingRedirect Whether we are handling an incoming redirect to an instant app. |
| * @param isSerpReferrer whether the referrer is the SERP. |
| * @return Whether we launched an instant app. |
| */ |
| boolean maybeLaunchInstantApp( |
| String url, String referrerUrl, boolean isIncomingRedirect, boolean isSerpReferrer); |
| |
| /** |
| * @return The WindowAndroid instance associated with this delegate instance. |
| */ |
| WindowAndroid getWindowAndroid(); |
| |
| /** |
| * @return The WebContents instance associated with this delegate instance. |
| */ |
| WebContents getWebContents(); |
| |
| /** |
| * @return Whether this delegate has a valid tab available. |
| */ |
| boolean hasValidTab(); |
| |
| /** |
| * @return Whether it's possible to close the current tab on launching on an incognito intent. |
| * TODO(blundell): Investigate whether it would be feasible to change the //chrome |
| * implementation of this method to be identical to that of its implementation of |
| * ExternalNavigationDelegate#hasValidTab() and then eliminate this method in favor of |
| * ExternalNavigationHandler calling hasValidTab() if so. |
| */ |
| boolean canCloseTabOnIncognitoIntentLaunch(); |
| |
| /** |
| * @return whether this delegate supports creation of new tabs. If this method returns false, |
| * all URLs loaded by ExternalNavigationHandler will be loaded in the current tab and |
| * loadUrlInNewTab() will never be invoked. |
| */ |
| boolean supportsCreatingNewTabs(); |
| |
| /** |
| * Loads |url| in a new tab. |
| * @param url The URL to load. |
| * @param launchIncognito whether the new tab should be incognito. |
| */ |
| void loadUrlInNewTab(final String url, final boolean launchIncognito); |
| |
| /** |
| * @return whether it's possible to load a URL in the current tab. |
| */ |
| boolean canLoadUrlInCurrentTab(); |
| |
| /* Invoked when the tab associated with this delegate should be closed. */ |
| void closeTab(); |
| |
| /* Returns whether whether the tab associated with this delegate is incognito. */ |
| boolean isIncognito(); |
| |
| /** |
| * @param intent The intent to launch. |
| * @return Whether the Intent points to an app that we trust and that launched this app. |
| */ |
| boolean isIntentForTrustedCallingApp(Intent intent); |
| |
| /** |
| * @param intent The intent to launch. |
| * @return Whether the Intent points to an instant app. |
| */ |
| boolean isIntentToInstantApp(Intent intent); |
| |
| /** |
| * @param intent The intent to launch |
| * @return Whether the Intent points to Autofill Assistant |
| */ |
| boolean isIntentToAutofillAssistant(Intent intent); |
| |
| /** |
| * Gives the embedder a chance to handle the intent via the autofill assistant. |
| */ |
| boolean handleWithAutofillAssistant(ExternalNavigationParams params, Intent targetIntent, |
| String browserFallbackUrl, boolean isGoogleReferrer); |
| } |