public final class

CustomTabsIntent

extends java.lang.Object

 java.lang.Object

↳androidx.browser.customtabs.CustomTabsIntent

Gradle dependencies

compile group: 'androidx.browser', name: 'browser', version: '1.4.0'

  • groupId: androidx.browser
  • artifactId: browser
  • version: 1.4.0

Artifact androidx.browser:browser:1.4.0 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.browser:browser com.android.support:customtabs

Androidx class mapping:

androidx.browser.customtabs.CustomTabsIntent android.support.customtabs.CustomTabsIntent

Overview

Class holding the and start bundle for a Custom Tabs Activity.

Note: The constants below are public for the browser implementation's benefit. You are strongly encouraged to use CustomTabsIntent.Builder.

Summary

Fields
public static final intCOLOR_SCHEME_DARK

Applies a dark color scheme to the user interface in the custom tab.

public static final intCOLOR_SCHEME_LIGHT

Applies a light color scheme to the user interface in the custom tab.

public static final intCOLOR_SCHEME_SYSTEM

Applies either a light or dark color scheme to the user interface in the custom tab depending on the user's system settings.

public static final java.lang.StringEXTRA_ACTION_BUTTON_BUNDLE

Bundle used for adding a custom action button to the custom tab toolbar.

public static final java.lang.StringEXTRA_CLOSE_BUTTON_ICON

Extra bitmap that specifies the icon of the back button on the toolbar.

public static final java.lang.StringEXTRA_COLOR_SCHEME

Extra (int) that specifies which color scheme should be applied to the custom tab.

public static final java.lang.StringEXTRA_COLOR_SCHEME_PARAMS

Extra that contains a SparseArray, mapping color schemes (except CustomTabsIntent.COLOR_SCHEME_SYSTEM) to representing CustomTabColorSchemeParams.

public static final java.lang.StringEXTRA_DEFAULT_SHARE_MENU_ITEM

Boolean extra that specifies whether a default share button will be shown in the menu.

public static final java.lang.StringEXTRA_ENABLE_INSTANT_APPS

Extra that specifies whether Instant Apps is enabled.

public static final java.lang.StringEXTRA_ENABLE_URLBAR_HIDING

Boolean extra that enables the url bar to hide as the user scrolls down the page

public static final java.lang.StringEXTRA_EXIT_ANIMATION_BUNDLE

Bundle constructed out of ActivityOptionsCompat that will be running when the that holds the custom tab gets finished.

public static final java.lang.StringEXTRA_MENU_ITEMS

Use an ArrayList for specifying menu related params.

public static final java.lang.StringEXTRA_NAVIGATION_BAR_COLOR

Extra that contains the color of the navigation bar.

public static final java.lang.StringEXTRA_NAVIGATION_BAR_DIVIDER_COLOR

Extra that contains the color of the navigation bar divider.

public static final java.lang.StringEXTRA_REMOTEVIEWS

Extra that specifies the showing on the secondary toolbar.

public static final java.lang.StringEXTRA_REMOTEVIEWS_CLICKED_ID

Extra that specifies which View has been clicked.

public static final java.lang.StringEXTRA_REMOTEVIEWS_PENDINGINTENT

Extra that specifies the PendingIntent to be sent when the user clicks on the Views that is listed by CustomTabsIntent.EXTRA_REMOTEVIEWS_VIEW_IDS.

public static final java.lang.StringEXTRA_REMOTEVIEWS_VIEW_IDS

Extra that specifies an array of View ids.

public static final java.lang.StringEXTRA_SECONDARY_TOOLBAR_COLOR

Extra that changes the background color for the secondary toolbar.

public static final java.lang.StringEXTRA_SESSION

Extra used to match the session.

public static final java.lang.StringEXTRA_SESSION_ID

Extra used to match the session ID.

public static final java.lang.StringEXTRA_SHARE_STATE

Extra (int) that specifies which share state should be applied to the custom tab.

public static final java.lang.StringEXTRA_TINT_ACTION_BUTTON

Extra boolean that specifies whether the custom action button should be tinted.

public static final java.lang.StringEXTRA_TITLE_VISIBILITY_STATE

Extra (int) that specifies state for showing the page title.

public static final java.lang.StringEXTRA_TOOLBAR_COLOR

Extra that changes the background color for the toolbar.

public static final java.lang.StringEXTRA_TOOLBAR_ITEMS

List used for adding items to the top and bottom toolbars.

public final Intentintent

An used to start the Custom Tabs Activity.

public static final java.lang.StringKEY_DESCRIPTION

Key that specifies the content description for the custom action button.

public static final java.lang.StringKEY_ICON

Key that specifies the Bitmap to be used as the image source for the action button.

public static final java.lang.StringKEY_ID

Key that specifies the unique ID for an action button.

public static final java.lang.StringKEY_MENU_ITEM_TITLE

Key for specifying the title of a menu item.

public static final java.lang.StringKEY_PENDING_INTENT

Key that specifies the PendingIntent to launch when the action button or menu item was clicked.

public static final intNO_TITLE

Don't show any title.

public static final intSHARE_STATE_DEFAULT

Applies the default share settings depending on the browser.

public static final intSHARE_STATE_OFF

Explicitly does not show a share option in the tab.

public static final intSHARE_STATE_ON

Shows a share option in the tab.

public static final intSHOW_PAGE_TITLE

Shows the page title and the domain.

public final BundlestartAnimationBundle

A containing the start animation for the Custom Tabs Activity.

public static final intTOOLBAR_ACTION_BUTTON_ID

The ID allocated to the custom action button that is shown on the toolbar.

Methods
public static CustomTabColorSchemeParamsgetColorSchemeParams(Intent intent, int colorScheme)

Retrieves the instance of CustomTabColorSchemeParams from an Intent for a given color scheme.

public static intgetMaxToolbarItems()

public voidlaunchUrl(Context context, Uri url)

Convenience method to launch a Custom Tabs Activity.

public static IntentsetAlwaysUseBrowserUI(Intent intent)

Adds the necessary flags and extras to signal any browser supporting custom tabs to use the browser UI at all times and avoid showing custom tab like UI.

public static booleanshouldAlwaysUseBrowserUI(Intent intent)

Whether a browser receiving the given intent should always use browser UI and avoid using any custom tabs UI.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Fields

public static final java.lang.String EXTRA_SESSION

Extra used to match the session. This has to be included in the intent to open in a custom tab. This is the same IBinder that gets passed to ICustomTabsService#newSession. Null if there is no need to match any service side sessions with the intent.

public static final java.lang.String EXTRA_SESSION_ID

Extra used to match the session ID. This is PendingIntent which is created with CustomTabsClient.createSessionId(Context, int).

public static final int COLOR_SCHEME_SYSTEM

Applies either a light or dark color scheme to the user interface in the custom tab depending on the user's system settings.

public static final int COLOR_SCHEME_LIGHT

Applies a light color scheme to the user interface in the custom tab.

public static final int COLOR_SCHEME_DARK

Applies a dark color scheme to the user interface in the custom tab. Colors set through CustomTabsIntent.EXTRA_TOOLBAR_COLOR may be darkened to match user expectations.

public static final java.lang.String EXTRA_COLOR_SCHEME

Extra (int) that specifies which color scheme should be applied to the custom tab. Default is CustomTabsIntent.COLOR_SCHEME_SYSTEM.

public static final java.lang.String EXTRA_TOOLBAR_COLOR

Extra that changes the background color for the toolbar. colorRes is an int that specifies a , not a resource id.

public static final java.lang.String EXTRA_ENABLE_URLBAR_HIDING

Boolean extra that enables the url bar to hide as the user scrolls down the page

public static final java.lang.String EXTRA_CLOSE_BUTTON_ICON

Extra bitmap that specifies the icon of the back button on the toolbar. If the client chooses not to customize it, a default close button will be used.

public static final java.lang.String EXTRA_TITLE_VISIBILITY_STATE

Extra (int) that specifies state for showing the page title. Default is CustomTabsIntent.NO_TITLE.

public static final int NO_TITLE

Don't show any title. Shows only the domain.

public static final int SHOW_PAGE_TITLE

Shows the page title and the domain.

public static final java.lang.String EXTRA_ACTION_BUTTON_BUNDLE

Bundle used for adding a custom action button to the custom tab toolbar. The client should provide a description, an icon Bitmap and a PendingIntent for the button. All three keys must be present.

public static final java.lang.String EXTRA_TOOLBAR_ITEMS

List used for adding items to the top and bottom toolbars. The client should provide an ID, a description, an icon Bitmap for each item. They may also provide a PendingIntent if the item is a button.

public static final java.lang.String EXTRA_SECONDARY_TOOLBAR_COLOR

Extra that changes the background color for the secondary toolbar. The value should be an int that specifies a , not a resource id.

public static final java.lang.String KEY_ICON

Key that specifies the Bitmap to be used as the image source for the action button. The icon should't be more than 24dp in height (No padding needed. The button itself will be 48dp in height) and have a width/height ratio of less than 2.

public static final java.lang.String KEY_DESCRIPTION

Key that specifies the content description for the custom action button.

public static final java.lang.String KEY_PENDING_INTENT

Key that specifies the PendingIntent to launch when the action button or menu item was clicked. The custom tab will be calling PendingIntent on clicks after adding the url as data. The client app can call to get the url.

public static final java.lang.String EXTRA_TINT_ACTION_BUTTON

Extra boolean that specifies whether the custom action button should be tinted. Default is false and the action button will not be tinted.

public static final java.lang.String EXTRA_MENU_ITEMS

Use an ArrayList for specifying menu related params. There should be a separate for each custom menu item.

public static final java.lang.String KEY_MENU_ITEM_TITLE

Key for specifying the title of a menu item.

public static final java.lang.String EXTRA_EXIT_ANIMATION_BUNDLE

Bundle constructed out of ActivityOptionsCompat that will be running when the that holds the custom tab gets finished. A similar ActivityOptions for creation should be constructed and given to the startActivity() call that launches the custom tab.

public static final int SHARE_STATE_DEFAULT

Applies the default share settings depending on the browser.

public static final int SHARE_STATE_ON

Shows a share option in the tab.

public static final int SHARE_STATE_OFF

Explicitly does not show a share option in the tab.

public static final java.lang.String EXTRA_SHARE_STATE

Extra (int) that specifies which share state should be applied to the custom tab. Default is CustomTabsIntent.SHARE_STATE_DEFAULT.

public static final java.lang.String EXTRA_DEFAULT_SHARE_MENU_ITEM

Deprecated: Use CustomTabsIntent.EXTRA_SHARE_STATE instead.

Boolean extra that specifies whether a default share button will be shown in the menu.

public static final java.lang.String EXTRA_REMOTEVIEWS

Extra that specifies the showing on the secondary toolbar. If this extra is set, the other secondary toolbar configurations will be overriden. The height of the should not exceed 56dp.

See also: CustomTabsIntent.Builder.setSecondaryToolbarViews(RemoteViews, int[], PendingIntent)

public static final java.lang.String EXTRA_REMOTEVIEWS_VIEW_IDS

Extra that specifies an array of View ids. When these Views are clicked, a PendingIntent will be sent, carrying the current url of the custom tab as data.

Note that Custom Tabs will override the default onClick behavior of the listed Views. If you do not care about the current url, you can safely ignore this extra and use instead.

See also: CustomTabsIntent.Builder.setSecondaryToolbarViews(RemoteViews, int[], PendingIntent)

public static final java.lang.String EXTRA_REMOTEVIEWS_PENDINGINTENT

Extra that specifies the PendingIntent to be sent when the user clicks on the Views that is listed by CustomTabsIntent.EXTRA_REMOTEVIEWS_VIEW_IDS.

Note when this PendingIntent is triggered, it will have the current url as data field, also the id of the clicked View, specified by CustomTabsIntent.EXTRA_REMOTEVIEWS_CLICKED_ID.

See also: CustomTabsIntent.Builder.setSecondaryToolbarViews(RemoteViews, int[], PendingIntent)

public static final java.lang.String EXTRA_REMOTEVIEWS_CLICKED_ID

Extra that specifies which View has been clicked. This extra will be put to the PendingIntent sent from Custom Tabs when a view in the is clicked

See also: CustomTabsIntent.Builder.setSecondaryToolbarViews(RemoteViews, int[], PendingIntent)

public static final java.lang.String EXTRA_ENABLE_INSTANT_APPS

Extra that specifies whether Instant Apps is enabled.

public static final java.lang.String EXTRA_COLOR_SCHEME_PARAMS

Extra that contains a SparseArray, mapping color schemes (except CustomTabsIntent.COLOR_SCHEME_SYSTEM) to representing CustomTabColorSchemeParams.

public static final java.lang.String EXTRA_NAVIGATION_BAR_COLOR

Extra that contains the color of the navigation bar. See CustomTabsIntent.Builder.setNavigationBarColor(int).

public static final java.lang.String EXTRA_NAVIGATION_BAR_DIVIDER_COLOR

Extra that contains the color of the navigation bar divider. See CustomTabsIntent.Builder.setNavigationBarDividerColor(int).

public static final java.lang.String KEY_ID

Key that specifies the unique ID for an action button. To make a button to show on the toolbar, use CustomTabsIntent.TOOLBAR_ACTION_BUTTON_ID as its ID.

public static final int TOOLBAR_ACTION_BUTTON_ID

The ID allocated to the custom action button that is shown on the toolbar.

public final Intent intent

An used to start the Custom Tabs Activity.

public final Bundle startAnimationBundle

A containing the start animation for the Custom Tabs Activity.

Methods

public void launchUrl(Context context, Uri url)

Convenience method to launch a Custom Tabs Activity.

Parameters:

context: The source Context.
url: The URL to load in the Custom Tab.

public static int getMaxToolbarItems()

Returns:

The maximum number of allowed toolbar items for CustomTabsIntent.Builder.addToolbarItem(int, Bitmap, String, PendingIntent) and CustomTabsIntent.EXTRA_TOOLBAR_ITEMS.

public static Intent setAlwaysUseBrowserUI(Intent intent)

Adds the necessary flags and extras to signal any browser supporting custom tabs to use the browser UI at all times and avoid showing custom tab like UI. Calling this with an intent will override any custom tabs related customizations.

Parameters:

intent: The intent to modify for always showing browser UI.

Returns:

The same intent with the necessary flags and extras added.

public static boolean shouldAlwaysUseBrowserUI(Intent intent)

Whether a browser receiving the given intent should always use browser UI and avoid using any custom tabs UI.

Parameters:

intent: The intent to check for the required flags and extras.

Returns:

Whether the browser UI should be used exclusively.

public static CustomTabColorSchemeParams getColorSchemeParams(Intent intent, int colorScheme)

Retrieves the instance of CustomTabColorSchemeParams from an Intent for a given color scheme. Uses values passed directly into CustomTabsIntent.Builder (e.g. via CustomTabsIntent.Builder.setToolbarColor(int)) as defaults.

Parameters:

intent: Intent to retrieve the color scheme parameters from.
colorScheme: A constant representing a color scheme. Should not be CustomTabsIntent.COLOR_SCHEME_SYSTEM.

Returns:

An instance of CustomTabColorSchemeParams with retrieved parameters.

Source

/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.browser.customtabs;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.util.SparseArray;
import android.view.View;
import android.widget.RemoteViews;

import androidx.annotation.AnimRes;
import androidx.annotation.ColorInt;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.app.BundleCompat;
import androidx.core.content.ContextCompat;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;

/**
 * Class holding the {@link Intent} and start bundle for a Custom Tabs Activity.
 *
 * <p>
 * <strong>Note:</strong> The constants below are public for the browser implementation's benefit.
 * You are strongly encouraged to use {@link CustomTabsIntent.Builder}.</p>
 */
public final class CustomTabsIntent {

    /**
     * Indicates that the user explicitly opted out of Custom Tabs in the calling application.
     * <p>
     * If an application provides a mechanism for users to opt out of Custom Tabs, this extra should
     * be provided with {@link Intent#FLAG_ACTIVITY_NEW_TASK} to ensure the browser does not attempt
     * to trigger any Custom Tab-like experiences as a result of the VIEW intent.
     * <p>
     * If this extra is present with {@link Intent#FLAG_ACTIVITY_NEW_TASK}, all Custom Tabs
     * customizations will be ignored.
     */
    private static final String EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS =
            "android.support.customtabs.extra.user_opt_out";

    /**
     * Extra used to match the session. This has to be included in the intent to open in
     * a custom tab. This is the same IBinder that gets passed to ICustomTabsService#newSession.
     * Null if there is no need to match any service side sessions with the intent.
     */
    public static final String EXTRA_SESSION = "android.support.customtabs.extra.SESSION";

    /**
     * Extra used to match the session ID. This is PendingIntent which is created with
     * {@link CustomTabsClient#createSessionId}.
     *
     * @hide
     */
    @RestrictTo(RestrictTo.Scope.LIBRARY)
    public static final String EXTRA_SESSION_ID = "android.support.customtabs.extra.SESSION_ID";

    /**
     * @hide
     */
    @RestrictTo(RestrictTo.Scope.LIBRARY)
    @IntDef({COLOR_SCHEME_SYSTEM, COLOR_SCHEME_LIGHT, COLOR_SCHEME_DARK})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ColorScheme {
    }

    /**
     * Applies either a light or dark color scheme to the user interface in the custom tab depending
     * on the user's system settings.
     */
    public static final int COLOR_SCHEME_SYSTEM = 0;

    /**
     * Applies a light color scheme to the user interface in the custom tab.
     */
    public static final int COLOR_SCHEME_LIGHT = 1;

    /**
     * Applies a dark color scheme to the user interface in the custom tab. Colors set through
     * {@link #EXTRA_TOOLBAR_COLOR} may be darkened to match user expectations.
     */
    public static final int COLOR_SCHEME_DARK = 2;

    /**
     * Maximum value for the COLOR_SCHEME_* configuration options. For validation purposes only.
     */
    private static final int COLOR_SCHEME_MAX = 2;

    /**
     * Extra (int) that specifies which color scheme should be applied to the custom tab. Default is
     * {@link #COLOR_SCHEME_SYSTEM}.
     */
    public static final String EXTRA_COLOR_SCHEME =
            "androidx.browser.customtabs.extra.COLOR_SCHEME";

    /**
     * Extra that changes the background color for the toolbar. colorRes is an int that specifies a
     * {@link Color}, not a resource id.
     */
    public static final String EXTRA_TOOLBAR_COLOR =
            "android.support.customtabs.extra.TOOLBAR_COLOR";

    /**
     * Boolean extra that enables the url bar to hide as the user scrolls down the page
     */
    public static final String EXTRA_ENABLE_URLBAR_HIDING =
            "android.support.customtabs.extra.ENABLE_URLBAR_HIDING";

    /**
     * Extra bitmap that specifies the icon of the back button on the toolbar. If the client chooses
     * not to customize it, a default close button will be used.
     */
    public static final String EXTRA_CLOSE_BUTTON_ICON =
            "android.support.customtabs.extra.CLOSE_BUTTON_ICON";

    /**
     * Extra (int) that specifies state for showing the page title. Default is {@link #NO_TITLE}.
     */
    public static final String EXTRA_TITLE_VISIBILITY_STATE =
            "android.support.customtabs.extra.TITLE_VISIBILITY";

    /**
     * Don't show any title. Shows only the domain.
     */
    public static final int NO_TITLE = 0;

    /**
     * Shows the page title and the domain.
     */
    public static final int SHOW_PAGE_TITLE = 1;

    /**
     * Bundle used for adding a custom action button to the custom tab toolbar. The client should
     * provide a description, an icon {@link Bitmap} and a {@link PendingIntent} for the button.
     * All three keys must be present.
     */
    public static final String EXTRA_ACTION_BUTTON_BUNDLE =
            "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";

    /**
     * List<Bundle> used for adding items to the top and bottom toolbars. The client should
     * provide an ID, a description, an icon {@link Bitmap} for each item. They may also provide a
     * {@link PendingIntent} if the item is a button.
     */
    public static final String EXTRA_TOOLBAR_ITEMS =
            "android.support.customtabs.extra.TOOLBAR_ITEMS";

    /**
     * Extra that changes the background color for the secondary toolbar. The value should be an
     * int that specifies a {@link Color}, not a resource id.
     */
    public static final String EXTRA_SECONDARY_TOOLBAR_COLOR =
            "android.support.customtabs.extra.SECONDARY_TOOLBAR_COLOR";

    /**
     * Key that specifies the {@link Bitmap} to be used as the image source for the action button.
     *  The icon should't be more than 24dp in height (No padding needed. The button itself will be
     *  48dp in height) and have a width/height ratio of less than 2.
     */
    public static final String KEY_ICON = "android.support.customtabs.customaction.ICON";

    /**
     * Key that specifies the content description for the custom action button.
     */
    public static final String KEY_DESCRIPTION =
            "android.support.customtabs.customaction.DESCRIPTION";

    /**
     * Key that specifies the PendingIntent to launch when the action button or menu item was
     * clicked. The custom tab will be calling {@link PendingIntent#send()} on clicks after adding
     * the url as data. The client app can call {@link Intent#getDataString()} to get the url.
     */
    public static final String KEY_PENDING_INTENT =
            "android.support.customtabs.customaction.PENDING_INTENT";

    /**
     * Extra boolean that specifies whether the custom action button should be tinted. Default is
     * false and the action button will not be tinted.
     */
    public static final String EXTRA_TINT_ACTION_BUTTON =
            "android.support.customtabs.extra.TINT_ACTION_BUTTON";

    /**
     * Use an {@code ArrayList<Bundle>} for specifying menu related params. There should be a
     * separate {@link Bundle} for each custom menu item.
     */
    public static final String EXTRA_MENU_ITEMS = "android.support.customtabs.extra.MENU_ITEMS";

    /**
     * Key for specifying the title of a menu item.
     */
    public static final String KEY_MENU_ITEM_TITLE =
            "android.support.customtabs.customaction.MENU_ITEM_TITLE";

    /**
     * Bundle constructed out of {@link ActivityOptionsCompat} that will be running when the
     * {@link Activity} that holds the custom tab gets finished. A similar ActivityOptions
     * for creation should be constructed and given to the startActivity() call that
     * launches the custom tab.
     */
    public static final String EXTRA_EXIT_ANIMATION_BUNDLE =
            "android.support.customtabs.extra.EXIT_ANIMATION_BUNDLE";

    /**
     * @hide
     */
    @RestrictTo(RestrictTo.Scope.LIBRARY)
    @IntDef({SHARE_STATE_DEFAULT, SHARE_STATE_ON, SHARE_STATE_OFF})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ShareState {
    }

    /**
     * Applies the default share settings depending on the browser.
     */
    public static final int SHARE_STATE_DEFAULT = 0;

    /**
     * Shows a share option in the tab.
     */
    public static final int SHARE_STATE_ON = 1;

    /**
     * Explicitly does not show a share option in the tab.
     */
    public static final int SHARE_STATE_OFF = 2;

    /**
     * Maximum value for the SHARE_STATE_* configuration options. For validation purposes only.
     */
    private static final int SHARE_STATE_MAX = 2;

    /**
     * Extra (int) that specifies which share state should be applied to the custom tab. Default is
     * {@link CustomTabsIntent#SHARE_STATE_DEFAULT}.
     */
    public static final String EXTRA_SHARE_STATE = "androidx.browser.customtabs.extra.SHARE_STATE";

    /**
     * Boolean extra that specifies whether a default share button will be shown in the menu.
     *
     * @deprecated Use {@link CustomTabsIntent#EXTRA_SHARE_STATE} instead.
     */
    @Deprecated
    public static final String EXTRA_DEFAULT_SHARE_MENU_ITEM =
            "android.support.customtabs.extra.SHARE_MENU_ITEM";

    /**
     * Extra that specifies the {@link RemoteViews} showing on the secondary toolbar. If this extra
     * is set, the other secondary toolbar configurations will be overriden. The height of the
     * {@link RemoteViews} should not exceed 56dp.
     * @see CustomTabsIntent.Builder#setSecondaryToolbarViews(RemoteViews, int[], PendingIntent).
     */
    public static final String EXTRA_REMOTEVIEWS =
            "android.support.customtabs.extra.EXTRA_REMOTEVIEWS";

    /**
     * Extra that specifies an array of {@link View} ids. When these {@link View}s are clicked, a
     * {@link PendingIntent} will be sent, carrying the current url of the custom tab as data.
     * <p>
     * Note that Custom Tabs will override the default onClick behavior of the listed {@link View}s.
     * If you do not care about the current url, you can safely ignore this extra and use
     * {@link RemoteViews#setOnClickPendingIntent(int, PendingIntent)} instead.
     * @see CustomTabsIntent.Builder#setSecondaryToolbarViews(RemoteViews, int[], PendingIntent).
     */
    public static final String EXTRA_REMOTEVIEWS_VIEW_IDS =
            "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_VIEW_IDS";

    /**
     * Extra that specifies the {@link PendingIntent} to be sent when the user clicks on the
     * {@link View}s that is listed by {@link #EXTRA_REMOTEVIEWS_VIEW_IDS}.
     * <p>
     * Note when this {@link PendingIntent} is triggered, it will have the current url as data
     * field, also the id of the clicked {@link View}, specified by
     * {@link #EXTRA_REMOTEVIEWS_CLICKED_ID}.
     * @see CustomTabsIntent.Builder#setSecondaryToolbarViews(RemoteViews, int[], PendingIntent).
     */
    public static final String EXTRA_REMOTEVIEWS_PENDINGINTENT =
            "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_PENDINGINTENT";

    /**
     * Extra that specifies which {@link View} has been clicked. This extra will be put to the
     * {@link PendingIntent} sent from Custom Tabs when a view in the {@link RemoteViews} is clicked
     * @see CustomTabsIntent.Builder#setSecondaryToolbarViews(RemoteViews, int[], PendingIntent).
     */
    public static final String EXTRA_REMOTEVIEWS_CLICKED_ID =
            "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_CLICKED_ID";

    /**
     * Extra that specifies whether Instant Apps is enabled.
     */
    public static final String EXTRA_ENABLE_INSTANT_APPS =
            "android.support.customtabs.extra.EXTRA_ENABLE_INSTANT_APPS";

    /**
     * Extra that contains a SparseArray, mapping color schemes (except
     * {@link CustomTabsIntent#COLOR_SCHEME_SYSTEM}) to {@link Bundle} representing
     * {@link CustomTabColorSchemeParams}.
     */
    public static final String EXTRA_COLOR_SCHEME_PARAMS =
            "androidx.browser.customtabs.extra.COLOR_SCHEME_PARAMS";

    /**
     * Extra that contains the color of the navigation bar.
     * See {@link Builder#setNavigationBarColor}.
     */
    public static final String EXTRA_NAVIGATION_BAR_COLOR =
            "androidx.browser.customtabs.extra.NAVIGATION_BAR_COLOR";

    /**
     * Extra that contains the color of the navigation bar divider.
     * See {@link Builder#setNavigationBarDividerColor}.
     */
    public static final String EXTRA_NAVIGATION_BAR_DIVIDER_COLOR =
            "androidx.browser.customtabs.extra.NAVIGATION_BAR_DIVIDER_COLOR";

    /**
     * Key that specifies the unique ID for an action button. To make a button to show on the
     * toolbar, use {@link #TOOLBAR_ACTION_BUTTON_ID} as its ID.
     */
    public static final String KEY_ID = "android.support.customtabs.customaction.ID";

    /**
     * The ID allocated to the custom action button that is shown on the toolbar.
     */
    public static final int TOOLBAR_ACTION_BUTTON_ID = 0;

    /**
     * The maximum allowed number of toolbar items.
     */
    private static final int MAX_TOOLBAR_ITEMS = 5;

    /**
     * An {@link Intent} used to start the Custom Tabs Activity.
     */
    @NonNull public final Intent intent;

    /**
     * A {@link Bundle} containing the start animation for the Custom Tabs Activity.
     */
    @Nullable public final Bundle startAnimationBundle;

    /**
     * Convenience method to launch a Custom Tabs Activity.
     * @param context The source Context.
     * @param url The URL to load in the Custom Tab.
     */
    public void launchUrl(@NonNull Context context, @NonNull Uri url) {
        intent.setData(url);
        ContextCompat.startActivity(context, intent, startAnimationBundle);
    }

    @SuppressWarnings("WeakerAccess") /* synthetic access */
    CustomTabsIntent(@NonNull Intent intent, @Nullable Bundle startAnimationBundle) {
        this.intent = intent;
        this.startAnimationBundle = startAnimationBundle;
    }

    /**
     * Builder class for {@link CustomTabsIntent} objects.
     */
    public static final class Builder {
        private final Intent mIntent = new Intent(Intent.ACTION_VIEW);
        private final CustomTabColorSchemeParams.Builder mDefaultColorSchemeBuilder =
                new CustomTabColorSchemeParams.Builder();
        @Nullable private ArrayList<Bundle> mMenuItems;
        @Nullable private Bundle mStartAnimationBundle;
        @Nullable private ArrayList<Bundle> mActionButtons;
        @Nullable private SparseArray<Bundle> mColorSchemeParamBundles;
        @Nullable private Bundle mDefaultColorSchemeBundle;
        @ShareState private int mShareState = SHARE_STATE_DEFAULT;
        private boolean mInstantAppsEnabled = true;

        /**
         * Creates a {@link CustomTabsIntent.Builder} object associated with no
         * {@link CustomTabsSession}.
         */
        public Builder() {}

        /**
         * Creates a {@link CustomTabsIntent.Builder} object associated with a given
         * {@link CustomTabsSession}.
         *
         * Guarantees that the {@link Intent} will be sent to the same component as the one the
         * session is associated with.
         *
         * @param session The session to associate this Builder with.
         */
        public Builder(@Nullable CustomTabsSession session) {
            if (session != null) {
                setSession(session);
            }
        }

        /**
         * Associates the {@link Intent} with the given {@link CustomTabsSession}.
         *
         * Guarantees that the {@link Intent} will be sent to the same component as the one the
         * session is associated with.
         */
        @NonNull
        public Builder setSession(@NonNull CustomTabsSession session) {
            mIntent.setPackage(session.getComponentName().getPackageName());
            setSessionParameters(session.getBinder(), session.getId());
            return this;
        }

        /**
         * Associates the {@link Intent} with the given {@link CustomTabsSession.PendingSession}.
         * Overrides the effect of {@link #setSession}.
         *
         * @hide
         */
        @RestrictTo(RestrictTo.Scope.LIBRARY)
        @NonNull
        public Builder setPendingSession(@NonNull CustomTabsSession.PendingSession session) {
            setSessionParameters(null, session.getId());
            return this;
        }

        private void setSessionParameters(@Nullable IBinder binder,
                @Nullable PendingIntent sessionId) {
            Bundle bundle = new Bundle();
            BundleCompat.putBinder(bundle, EXTRA_SESSION, binder);
            if (sessionId != null) {
                bundle.putParcelable(EXTRA_SESSION_ID, sessionId);
            }

            mIntent.putExtras(bundle);
        }

        /**
         * Sets the toolbar color.
         *
         * On Android L and above, this color is also applied to the status bar. To ensure good
         * contrast between status bar icons and the background, Custom Tab implementations may use
         * {@link View#SYSTEM_UI_FLAG_LIGHT_STATUS_BAR} on Android M and above, and use a darkened
         * color for the status bar on Android L.
         *
         * Can be overridden for particular color schemes, see {@link #setColorSchemeParams}.
         *
         * @param color {@link Color}
         *
         * @deprecated Use {@link #setDefaultColorSchemeParams} instead.
         */
        @Deprecated
        @NonNull
        public Builder setToolbarColor(@ColorInt int color) {
            mDefaultColorSchemeBuilder.setToolbarColor(color);
            return this;
        }

        /**
         * Enables the url bar to hide as the user scrolls down on the page.
         * @deprecated Use {@link #setUrlBarHidingEnabled(boolean)} instead.
         */
        @Deprecated
        @NonNull
        public Builder enableUrlBarHiding() {
            mIntent.putExtra(EXTRA_ENABLE_URLBAR_HIDING, true);
            return this;
        }

        /**
         * Set whether the url bar should hide as the user scrolls down on the page.
         *
         * @param enabled Whether url bar hiding is enabled.
         */
        @NonNull
        public Builder setUrlBarHidingEnabled(boolean enabled) {
            mIntent.putExtra(EXTRA_ENABLE_URLBAR_HIDING, enabled);
            return this;
        }

        /**
         * Sets the Close button icon for the custom tab.
         *
         * @param icon The icon {@link Bitmap}
         */
        @NonNull
        public Builder setCloseButtonIcon(@NonNull Bitmap icon) {
            mIntent.putExtra(EXTRA_CLOSE_BUTTON_ICON, icon);
            return this;
        }

        /**
         * Sets whether the title should be shown in the custom tab.
         *
         * @param showTitle Whether the title should be shown.
         */
        @NonNull
        public Builder setShowTitle(boolean showTitle) {
            mIntent.putExtra(EXTRA_TITLE_VISIBILITY_STATE,
                    showTitle ? SHOW_PAGE_TITLE : NO_TITLE);
            return this;
        }

        /**
         * Adds a menu item.
         *
         * @param label Menu label.
         * @param pendingIntent Pending intent delivered when the menu item is clicked.
         */
        @NonNull
        public Builder addMenuItem(@NonNull String label, @NonNull PendingIntent pendingIntent) {
            if (mMenuItems == null) mMenuItems = new ArrayList<>();
            Bundle bundle = new Bundle();
            bundle.putString(KEY_MENU_ITEM_TITLE, label);
            bundle.putParcelable(KEY_PENDING_INTENT, pendingIntent);
            mMenuItems.add(bundle);
            return this;
        }

        /**
         * Adds a default share item to the menu.
         * @deprecated Use {@link #setShareState(int)} instead. This will set the share state to
         * {@link CustomTabsIntent#SHARE_STATE_ON}.
         */
        @Deprecated
        @NonNull
        public Builder addDefaultShareMenuItem() {
            setShareState(SHARE_STATE_ON);
            return this;
        }

        /**
         * Set whether a default share item is added to the menu.
         *
         * @param enabled Whether default share item is added.
         * @deprecated Use {@link #setShareState(int)} instead. This will set the share state to
         * {@link CustomTabsIntent#SHARE_STATE_ON} or {@link CustomTabsIntent#SHARE_STATE_OFF}
         * based on {@code enabled}.
         */
        @Deprecated
        @NonNull
        public Builder setDefaultShareMenuItemEnabled(boolean enabled) {
            if (enabled) {
                setShareState(SHARE_STATE_ON);
            } else {
                setShareState(SHARE_STATE_OFF);
            }
            return this;
        }

        /**
         * Sets the share state that should be applied to the custom tab.
         *
         * @param shareState Desired share state.
         *
         * @see CustomTabsIntent#SHARE_STATE_DEFAULT
         * @see CustomTabsIntent#SHARE_STATE_ON
         * @see CustomTabsIntent#SHARE_STATE_OFF
         */
        @NonNull
        public Builder setShareState(@ShareState int shareState) {
            if (shareState < 0 || shareState > SHARE_STATE_MAX) {
                throw new IllegalArgumentException("Invalid value for the shareState argument");
            }
            mShareState = shareState;
            // Add share menu item extra for backwards compatibility with {@link
            // #addDefaultShareMenuItem} and {@link #setDefaultShareMenuItemEnabled}.
            if (shareState == SHARE_STATE_ON) {
                mIntent.putExtra(EXTRA_DEFAULT_SHARE_MENU_ITEM, true);
            } else if (shareState == SHARE_STATE_OFF) {
                mIntent.putExtra(EXTRA_DEFAULT_SHARE_MENU_ITEM, false);
            } else {
                mIntent.removeExtra(EXTRA_DEFAULT_SHARE_MENU_ITEM);
            }
            return this;
        }

        /**
         * Sets the action button that is displayed in the Toolbar.
         * <p>
         * This is equivalent to calling
         * {@link CustomTabsIntent.Builder#addToolbarItem(int, Bitmap, String, PendingIntent)}
         * with {@link #TOOLBAR_ACTION_BUTTON_ID} as id.
         *
         * @param icon The icon.
         * @param description The description for the button. To be used for accessibility.
         * @param pendingIntent pending intent delivered when the button is clicked.
         * @param shouldTint Whether the action button should be tinted..
         *
         * @see CustomTabsIntent.Builder#addToolbarItem(int, Bitmap, String, PendingIntent)
         */
        @NonNull
        public Builder setActionButton(@NonNull Bitmap icon, @NonNull String description,
                @NonNull PendingIntent pendingIntent, boolean shouldTint) {
            Bundle bundle = new Bundle();
            bundle.putInt(KEY_ID, TOOLBAR_ACTION_BUTTON_ID);
            bundle.putParcelable(KEY_ICON, icon);
            bundle.putString(KEY_DESCRIPTION, description);
            bundle.putParcelable(KEY_PENDING_INTENT, pendingIntent);
            mIntent.putExtra(EXTRA_ACTION_BUTTON_BUNDLE, bundle);
            mIntent.putExtra(EXTRA_TINT_ACTION_BUTTON, shouldTint);
            return this;
        }

        /**
         * Sets the action button that is displayed in the Toolbar with default tinting behavior.
         *
         * @see CustomTabsIntent.Builder#setActionButton(
         * Bitmap, String, PendingIntent, boolean)
         */
        @NonNull
        public Builder setActionButton(@NonNull Bitmap icon, @NonNull String description,
                @NonNull PendingIntent pendingIntent) {
            return setActionButton(icon, description, pendingIntent, false);
        }

        /**
         * Adds an action button to the custom tab. Multiple buttons can be added via this method.
         * If the given id equals {@link #TOOLBAR_ACTION_BUTTON_ID}, the button will be placed on
         * the toolbar; if the bitmap is too wide, it will be put to the bottom bar instead. If
         * the id is not {@link #TOOLBAR_ACTION_BUTTON_ID}, it will be directly put on secondary
         * toolbar. The maximum number of allowed toolbar items in a single intent is
         * {@link CustomTabsIntent#getMaxToolbarItems()}. Throws an
         * {@link IllegalStateException} when that number is exceeded per intent.
         *
         * @param id The unique id of the action button. This should be non-negative.
         * @param icon The icon.
         * @param description The description for the button. To be used for accessibility.
         * @param pendingIntent The pending intent delivered when the button is clicked.
         *
         * @see CustomTabsIntent#getMaxToolbarItems()
         * @deprecated Use
         * CustomTabsIntent.Builder#setSecondaryToolbarViews(RemoteViews, int[], PendingIntent).
         */
        @Deprecated
        @NonNull
        public Builder addToolbarItem(int id, @NonNull Bitmap icon, @NonNull String description,
                @NonNull PendingIntent pendingIntent) throws IllegalStateException {
            if (mActionButtons == null) {
                mActionButtons = new ArrayList<>();
            }
            if (mActionButtons.size() >= MAX_TOOLBAR_ITEMS) {
                throw new IllegalStateException(
                        "Exceeded maximum toolbar item count of " + MAX_TOOLBAR_ITEMS);
            }
            Bundle bundle = new Bundle();
            bundle.putInt(KEY_ID, id);
            bundle.putParcelable(KEY_ICON, icon);
            bundle.putString(KEY_DESCRIPTION, description);
            bundle.putParcelable(KEY_PENDING_INTENT, pendingIntent);
            mActionButtons.add(bundle);
            return this;
        }

        /**
         * Sets the color of the secondary toolbar.
         * Can be overridden for particular color schemes, see {@link #setColorSchemeParams}.
         *
         * @param color The color for the secondary toolbar.
         *
         * @deprecated Use {@link #setDefaultColorSchemeParams} instead.
         */
        @Deprecated
        @NonNull
        public Builder setSecondaryToolbarColor(@ColorInt int color) {
            mDefaultColorSchemeBuilder.setSecondaryToolbarColor(color);
            return this;
        }

        /**
         * Sets the navigation bar color. Has no effect on API versions below L.
         *
         * To ensure good contrast between navigation bar icons and the background, Custom Tab
         * implementations may use {@link View#SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR} on Android O and
         * above, and darken the provided color on Android L-N.
         *
         * Can be overridden for particular color schemes, see {@link #setColorSchemeParams}.
         *
         * @param color The color for the navigation bar.
         *
         * @deprecated Use {@link #setDefaultColorSchemeParams} instead.
         */
        @Deprecated
        @NonNull
        public Builder setNavigationBarColor(@ColorInt int color) {
            mDefaultColorSchemeBuilder.setNavigationBarColor(color);
            return this;
        }

        /**
         * Sets the navigation bar divider color. Has no effect on API versions below P.
         *
         * Can be overridden for particular color schemes, see {@link #setColorSchemeParams}.
         *
         * @param color The color for the navigation bar divider.
         *
         * @deprecated Use {@link #setDefaultColorSchemeParams} instead.
         */
        @Deprecated
        @NonNull
        public Builder setNavigationBarDividerColor(@ColorInt int color) {
            mDefaultColorSchemeBuilder.setNavigationBarDividerColor(color);
            return this;
        }

        /**
         * Sets the remote views displayed in the secondary toolbar in a custom tab.
         *
         * @param remoteViews   The {@link RemoteViews} that will be shown on the secondary toolbar.
         * @param clickableIDs  The IDs of clickable views. The onClick event of these views will be
         *                      handled by custom tabs.
         * @param pendingIntent The {@link PendingIntent} that will be sent when the user clicks on
         *                      one of the {@link View}s in clickableIDs. When the
         *                      {@link PendingIntent} is sent, it will have the current URL as its
         *                      intent data.
         * @see CustomTabsIntent#EXTRA_REMOTEVIEWS
         * @see CustomTabsIntent#EXTRA_REMOTEVIEWS_VIEW_IDS
         * @see CustomTabsIntent#EXTRA_REMOTEVIEWS_PENDINGINTENT
         * @see CustomTabsIntent#EXTRA_REMOTEVIEWS_CLICKED_ID
         */
        @NonNull
        public Builder setSecondaryToolbarViews(@NonNull RemoteViews remoteViews,
                @Nullable int[] clickableIDs, @Nullable PendingIntent pendingIntent) {
            mIntent.putExtra(EXTRA_REMOTEVIEWS, remoteViews);
            mIntent.putExtra(EXTRA_REMOTEVIEWS_VIEW_IDS, clickableIDs);
            mIntent.putExtra(EXTRA_REMOTEVIEWS_PENDINGINTENT, pendingIntent);
            return this;
        }

        /**
         * Sets whether Instant Apps is enabled for this Custom Tab.

         * @param enabled Whether Instant Apps should be enabled.
         */
        @NonNull
        public Builder setInstantAppsEnabled(boolean enabled) {
            mInstantAppsEnabled = enabled;
            return this;
        }

        /**
         * Sets the start animations.
         *
         * @param context Application context.
         * @param enterResId Resource ID of the "enter" animation for the browser.
         * @param exitResId Resource ID of the "exit" animation for the application.
         */
        @NonNull
        @SuppressWarnings("NullAway") // TODO: b/141869399
        public Builder setStartAnimations(
                @NonNull Context context, @AnimRes int enterResId, @AnimRes int exitResId) {
            mStartAnimationBundle = ActivityOptionsCompat.makeCustomAnimation(
                    context, enterResId, exitResId).toBundle();
            return this;
        }

        /**
         * Sets the exit animations.
         *
         * @param context Application context.
         * @param enterResId Resource ID of the "enter" animation for the application.
         * @param exitResId Resource ID of the "exit" animation for the browser.
         */
        @NonNull
        public Builder setExitAnimations(
                @NonNull Context context, @AnimRes int enterResId, @AnimRes int exitResId) {
            Bundle bundle = ActivityOptionsCompat.makeCustomAnimation(
                    context, enterResId, exitResId).toBundle();
            mIntent.putExtra(EXTRA_EXIT_ANIMATION_BUNDLE, bundle);
            return this;
        }

        /**
         * Sets the color scheme that should be applied to the user interface in the custom tab.
         *
         * @param colorScheme Desired color scheme.
         * @see CustomTabsIntent#COLOR_SCHEME_SYSTEM
         * @see CustomTabsIntent#COLOR_SCHEME_LIGHT
         * @see CustomTabsIntent#COLOR_SCHEME_DARK
         */
        @NonNull
        public Builder setColorScheme(@ColorScheme int colorScheme) {
            if (colorScheme < 0 || colorScheme > COLOR_SCHEME_MAX) {
                throw new IllegalArgumentException("Invalid value for the colorScheme argument");
            }
            mIntent.putExtra(EXTRA_COLOR_SCHEME, colorScheme);
            return this;
        }

        /**
         * Sets {@link CustomTabColorSchemeParams} for the given color scheme.
         *
         * This allows specifying two different toolbar colors for light and dark schemes.
         * It can be useful if {@link CustomTabsIntent#COLOR_SCHEME_SYSTEM} is set: Custom Tabs
         * will follow the system settings and apply the corresponding
         * {@link CustomTabColorSchemeParams} "on the fly" when the settings change.
         *
         * If there is no {@link CustomTabColorSchemeParams} for the current scheme, or a particular
         * field of it is null, Custom Tabs will fall back to the defaults provided via
         * {@link #setDefaultColorSchemeParams}.
         *
         * Example:
         * <pre><code>
         *     CustomTabColorSchemeParams darkParams = new CustomTabColorSchemeParams.Builder()
         *             .setToolbarColor(darkColor)
         *             .build();
         *     CustomTabColorSchemeParams otherParams = new CustomTabColorSchemeParams.Builder()
         *             .setNavigationBarColor(otherColor)
         *             .build();
         *     CustomTabIntent intent = new CustomTabIntent.Builder()
         *             .setColorScheme(COLOR_SCHEME_SYSTEM)
         *             .setColorSchemeParams(COLOR_SCHEME_DARK, darkParams)
         *             .setDefaultColorSchemeParams(otherParams)
         *             .build();
         * </code></pre>
         *
         * @param colorScheme A constant representing a color scheme (see {@link #setColorScheme}).
         *                    It should not be {@link #COLOR_SCHEME_SYSTEM}, because that represents
         *                    a behavior rather than a particular color scheme.
         * @param params An instance of {@link CustomTabColorSchemeParams}.
         */
        @NonNull
        public Builder setColorSchemeParams(@ColorScheme int colorScheme,
                @NonNull CustomTabColorSchemeParams params) {
            if (colorScheme < 0 || colorScheme > COLOR_SCHEME_MAX
                    || colorScheme == COLOR_SCHEME_SYSTEM) {
                throw new IllegalArgumentException("Invalid colorScheme: " + colorScheme);
            }
            if (mColorSchemeParamBundles == null) {
                mColorSchemeParamBundles = new SparseArray<>();
            }
            mColorSchemeParamBundles.put(colorScheme, params.toBundle());
            return this;
        }


        /**
         * Sets the default {@link CustomTabColorSchemeParams}.
         *
         * This will set a default color scheme that applies when no CustomTabColorSchemeParams
         * specified for current color scheme via {@link #setColorSchemeParams}.
         *
         * @param params An instance of {@link CustomTabColorSchemeParams}.
         */
        @NonNull
        public Builder setDefaultColorSchemeParams(@NonNull CustomTabColorSchemeParams params) {
            mDefaultColorSchemeBundle = params.toBundle();
            return this;
        }

        /**
         * Combines all the options that have been set and returns a new {@link CustomTabsIntent}
         * object.
         */
        @NonNull
        public CustomTabsIntent build() {
            if (!mIntent.hasExtra(EXTRA_SESSION)) {
                // The intent must have EXTRA_SESSION, even if it is null.
                setSessionParameters(null, null);
            }
            if (mMenuItems != null) {
                mIntent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_MENU_ITEMS, mMenuItems);
            }
            if (mActionButtons != null) {
                mIntent.putParcelableArrayListExtra(EXTRA_TOOLBAR_ITEMS, mActionButtons);
            }
            mIntent.putExtra(EXTRA_ENABLE_INSTANT_APPS, mInstantAppsEnabled);

            mIntent.putExtras(mDefaultColorSchemeBuilder.build().toBundle());
            if (mDefaultColorSchemeBundle != null) {
                mIntent.putExtras(mDefaultColorSchemeBundle);
            }

            if (mColorSchemeParamBundles != null) {
                Bundle bundle = new Bundle();
                bundle.putSparseParcelableArray(EXTRA_COLOR_SCHEME_PARAMS,
                        mColorSchemeParamBundles);
                mIntent.putExtras(bundle);
            }
            mIntent.putExtra(EXTRA_SHARE_STATE, mShareState);

            return new CustomTabsIntent(mIntent, mStartAnimationBundle);
        }
    }

    /**
     * @return The maximum number of allowed toolbar items for
     * {@link CustomTabsIntent.Builder#addToolbarItem(int, Bitmap, String, PendingIntent)} and
     * {@link CustomTabsIntent#EXTRA_TOOLBAR_ITEMS}.
     */
    public static int getMaxToolbarItems() {
        return MAX_TOOLBAR_ITEMS;
    }

    /**
     * Adds the necessary flags and extras to signal any browser supporting custom tabs to use the
     * browser UI at all times and avoid showing custom tab like UI. Calling this with an intent
     * will override any custom tabs related customizations.
     * @param intent The intent to modify for always showing browser UI.
     * @return The same intent with the necessary flags and extras added.
     */
    @NonNull
    public static Intent setAlwaysUseBrowserUI(@Nullable Intent intent) {
        if (intent == null) intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS, true);
        return intent;
    }

    /**
     * Whether a browser receiving the given intent should always use browser UI and avoid using any
     * custom tabs UI.
     *
     * @param intent The intent to check for the required flags and extras.
     * @return Whether the browser UI should be used exclusively.
     */
    public static boolean shouldAlwaysUseBrowserUI(@NonNull Intent intent) {
        return intent.getBooleanExtra(EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS, false)
                && (intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0;
    }

    /**
     * Retrieves the instance of {@link CustomTabColorSchemeParams} from an Intent for a given
     * color scheme. Uses values passed directly into {@link CustomTabsIntent.Builder} (e.g. via
     * {@link Builder#setToolbarColor}) as defaults.
     *
     * @param intent Intent to retrieve the color scheme parameters from.
     * @param colorScheme A constant representing a color scheme. Should not be
     *                    {@link #COLOR_SCHEME_SYSTEM}.
     * @return An instance of {@link CustomTabColorSchemeParams} with retrieved parameters.
     */
    @NonNull
    public static CustomTabColorSchemeParams getColorSchemeParams(@NonNull Intent intent,
            @ColorScheme int colorScheme) {
        if (colorScheme < 0 || colorScheme > COLOR_SCHEME_MAX
                || colorScheme == COLOR_SCHEME_SYSTEM) {
            throw new IllegalArgumentException("Invalid colorScheme: " + colorScheme);
        }

        Bundle extras = intent.getExtras();
        if (extras == null) {
            return CustomTabColorSchemeParams.fromBundle(null);
        }

        CustomTabColorSchemeParams defaults = CustomTabColorSchemeParams.fromBundle(extras);
        SparseArray<Bundle> paramBundles = extras.getSparseParcelableArray(
                EXTRA_COLOR_SCHEME_PARAMS);
        if (paramBundles != null) {
            Bundle bundleForScheme = paramBundles.get(colorScheme);
            if (bundleForScheme != null) {
                return CustomTabColorSchemeParams.fromBundle(bundleForScheme)
                        .withDefaults(defaults);
            }
        }
        return defaults;
    }
}