108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal/*
208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Copyright (C) 2015 The Android Open Source Project
308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal *
408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Licensed under the Apache License, Version 2.0 (the "License");
508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * you may not use this file except in compliance with the License.
608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * You may obtain a copy of the License at
708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal *
808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal *      http://www.apache.org/licenses/LICENSE-2.0
908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal *
1008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Unless required by applicable law or agreed to in writing, software
1108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * distributed under the License is distributed on an "AS IS" BASIS,
1208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * See the License for the specific language governing permissions and
1408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * limitations under the License.
1508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */
1608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
1708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalpackage android.support.customtabs;
1808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
1908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.app.Activity;
2008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.app.PendingIntent;
2197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lizeimport android.content.Context;
2208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.content.Intent;
2308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.graphics.Bitmap;
2408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.graphics.Color;
2508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.net.Uri;
2608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.os.Bundle;
2797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lizeimport android.support.annotation.AnimRes;
28e063d4d36883c9f7ca100036b9344b665ab6fd1eYusuf Ozuysalimport android.support.annotation.ColorInt;
29c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysalimport android.support.annotation.NonNull;
3097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lizeimport android.support.annotation.Nullable;
311b7158bbc0d0ba4569881f547d12f52e405e125eIan Lakeimport android.support.v4.app.ActivityOptionsCompat;
32c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysalimport android.support.v4.app.BundleCompat;
332109fdc5812946a98d8dd46b8b005277a2e10b00Alan Viveretteimport android.support.v4.content.ContextCompat;
34f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysalimport android.view.View;
35f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysalimport android.widget.RemoteViews;
3608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
3797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lizeimport java.util.ArrayList;
3808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
3908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal/**
4097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Class holding the {@link Intent} and start bundle for a Custom Tabs Activity.
4197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize *
4297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * <p>
4397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * <strong>Note:</strong> The constants below are public for the browser implementation's benefit.
4497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * You are strongly encouraged to use {@link CustomTabsIntent.Builder}.</p>
4508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */
4697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lizepublic final class CustomTabsIntent {
4708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
4808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
49821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * Indicates that the user explicitly opted out of Custom Tabs in the calling application.
50821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * <p>
51821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * If an application provides a mechanism for users to opt out of Custom Tabs, this extra should
52821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * be provided with {@link Intent#FLAG_ACTIVITY_NEW_TASK} to ensure the browser does not attempt
53821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * to trigger any Custom Tab-like experiences as a result of the VIEW intent.
54821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * <p>
55821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * If this extra is present with {@link Intent#FLAG_ACTIVITY_NEW_TASK}, all Custom Tabs
56821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * customizations will be ignored.
57821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     */
58821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal    private static final String EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS =
59821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal            "android.support.customtabs.extra.user_opt_out";
60821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal
61821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal    /**
6208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * Extra used to match the session. This has to be included in the intent to open in
6308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * a custom tab. This is the same IBinder that gets passed to ICustomTabsService#newSession.
6408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * Null if there is no need to match any service side sessions with the intent.
6508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
6608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public static final String EXTRA_SESSION = "android.support.customtabs.extra.SESSION";
6708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
6808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
6908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * Extra that changes the background color for the toolbar. colorRes is an int that specifies a
7008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * {@link Color}, not a resource id.
7108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
7208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public static final String EXTRA_TOOLBAR_COLOR =
7308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            "android.support.customtabs.extra.TOOLBAR_COLOR";
7408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
7508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
769440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal     * Boolean extra that enables the url bar to hide as the user scrolls down the page
779440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal     */
789440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal    public static final String EXTRA_ENABLE_URLBAR_HIDING =
799440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal            "android.support.customtabs.extra.ENABLE_URLBAR_HIDING";
809440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal
819440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal    /**
8297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     * Extra bitmap that specifies the icon of the back button on the toolbar. If the client chooses
8397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     * not to customize it, a default close button will be used.
8497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     */
8597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    public static final String EXTRA_CLOSE_BUTTON_ICON =
8697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            "android.support.customtabs.extra.CLOSE_BUTTON_ICON";
8797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
8897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    /**
8997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     * Extra (int) that specifies state for showing the page title. Default is {@link #NO_TITLE}.
9097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     */
9197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    public static final String EXTRA_TITLE_VISIBILITY_STATE =
9297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            "android.support.customtabs.extra.TITLE_VISIBILITY";
9397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
9497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    /**
9597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     * Don't show any title. Shows only the domain.
9697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     */
9797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    public static final int NO_TITLE = 0;
9897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
9997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    /**
10097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     * Shows the page title and the domain.
10197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     */
10297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    public static final int SHOW_PAGE_TITLE = 1;
10397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
10497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    /**
1058a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal     * Bundle used for adding a custom action button to the custom tab toolbar. The client should
1068a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal     * provide a description, an icon {@link Bitmap} and a {@link PendingIntent} for the button.
1078a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal     * All three keys must be present.
10808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
10908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public static final String EXTRA_ACTION_BUTTON_BUNDLE =
11008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";
11108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
11208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
11331d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal     * List<Bundle> used for adding items to the top and bottom toolbars. The client should
114179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal     * provide an ID, a description, an icon {@link Bitmap} for each item. They may also provide a
115179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal     * {@link PendingIntent} if the item is a button.
116179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal     */
11731d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal    public static final String EXTRA_TOOLBAR_ITEMS =
11831d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal            "android.support.customtabs.extra.TOOLBAR_ITEMS";
119179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal
120179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal    /**
12131d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal     * Extra that changes the background color for the secondary toolbar. The value should be an
12264694064caedb59afda4ef69b04feaee12c0a33fYusuf Ozuysal     * int that specifies a {@link Color}, not a resource id.
12364694064caedb59afda4ef69b04feaee12c0a33fYusuf Ozuysal     */
12431d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal    public static final String EXTRA_SECONDARY_TOOLBAR_COLOR =
12531d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal            "android.support.customtabs.extra.SECONDARY_TOOLBAR_COLOR";
12664694064caedb59afda4ef69b04feaee12c0a33fYusuf Ozuysal
12764694064caedb59afda4ef69b04feaee12c0a33fYusuf Ozuysal    /**
12808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * Key that specifies the {@link Bitmap} to be used as the image source for the action button.
1298a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal     *  The icon should't be more than 24dp in height (No padding needed. The button itself will be
1308a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal     *  48dp in height) and have a width/height ratio of less than 2.
13108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
13208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public static final String KEY_ICON = "android.support.customtabs.customaction.ICON";
13308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
13408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
1358a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal     * Key that specifies the content description for the custom action button.
1368a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal     */
1378a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal    public static final String KEY_DESCRIPTION =
1388a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal            "android.support.customtabs.customaction.DESCRIPTION";
1398a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal
1408a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal    /**
14108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * Key that specifies the PendingIntent to launch when the action button or menu item was
14208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * clicked. The custom tab will be calling {@link PendingIntent#send()} on clicks after adding
14308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * the url as data. The client app can call {@link Intent#getDataString()} to get the url.
14408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
14508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public static final String KEY_PENDING_INTENT =
14608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            "android.support.customtabs.customaction.PENDING_INTENT";
14708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
14808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
1499440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal     * Extra boolean that specifies whether the custom action button should be tinted. Default is
1509440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal     * false and the action button will not be tinted.
1519440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal     */
1529440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal    public static final String EXTRA_TINT_ACTION_BUTTON =
1539440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal            "android.support.customtabs.extra.TINT_ACTION_BUTTON";
1549440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal
1559440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal    /**
15608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * Use an {@code ArrayList<Bundle>} for specifying menu related params. There should be a
15708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * separate {@link Bundle} for each custom menu item.
15808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
15908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public static final String EXTRA_MENU_ITEMS = "android.support.customtabs.extra.MENU_ITEMS";
16008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
16108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
16208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * Key for specifying the title of a menu item.
16308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
16408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public static final String KEY_MENU_ITEM_TITLE =
16508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            "android.support.customtabs.customaction.MENU_ITEM_TITLE";
16608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
16708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
1681b7158bbc0d0ba4569881f547d12f52e405e125eIan Lake     * Bundle constructed out of {@link ActivityOptionsCompat} that will be running when the
16908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * {@link Activity} that holds the custom tab gets finished. A similar ActivityOptions
17008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * for creation should be constructed and given to the startActivity() call that
17108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * launches the custom tab.
17208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
17308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public static final String EXTRA_EXIT_ANIMATION_BUNDLE =
17408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            "android.support.customtabs.extra.EXIT_ANIMATION_BUNDLE";
17508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
17608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
1778b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal     * Boolean extra that specifies whether a default share button will be shown in the menu.
1788b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal     */
1798b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal    public static final String EXTRA_DEFAULT_SHARE_MENU_ITEM =
1808b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal            "android.support.customtabs.extra.SHARE_MENU_ITEM";
1818b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal
1828b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal    /**
183f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * Extra that specifies the {@link RemoteViews} showing on the secondary toolbar. If this extra
184f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * is set, the other secondary toolbar configurations will be overriden. The height of the
185f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * {@link RemoteViews} should not exceed 56dp.
186f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * @see CustomTabsIntent.Builder#setSecondaryToolbarViews(RemoteViews, int[], PendingIntent).
187f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     */
188f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal    public static final String EXTRA_REMOTEVIEWS =
189f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal            "android.support.customtabs.extra.EXTRA_REMOTEVIEWS";
190f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal
191f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal    /**
192f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * Extra that specifies an array of {@link View} ids. When these {@link View}s are clicked, a
193f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * {@link PendingIntent} will be sent, carrying the current url of the custom tab as data.
194f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * <p>
195f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * Note that Custom Tabs will override the default onClick behavior of the listed {@link View}s.
196f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * If you do not care about the current url, you can safely ignore this extra and use
197f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * {@link RemoteViews#setOnClickPendingIntent(int, PendingIntent)} instead.
198f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * @see CustomTabsIntent.Builder#setSecondaryToolbarViews(RemoteViews, int[], PendingIntent).
199f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     */
200f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal    public static final String EXTRA_REMOTEVIEWS_VIEW_IDS =
201f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal            "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_VIEW_IDS";
202f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal
203f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal    /**
204f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * Extra that specifies the {@link PendingIntent} to be sent when the user clicks on the
205d0f2cc4ee9ac45be16119a04433d4dd3ddf9e576Yusuf Ozuysal     * {@link View}s that is listed by {@link #EXTRA_REMOTEVIEWS_VIEW_IDS}.
206f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * <p>
207f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * Note when this {@link PendingIntent} is triggered, it will have the current url as data
208f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * field, also the id of the clicked {@link View}, specified by
209f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * {@link #EXTRA_REMOTEVIEWS_CLICKED_ID}.
210f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * @see CustomTabsIntent.Builder#setSecondaryToolbarViews(RemoteViews, int[], PendingIntent).
211f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     */
212f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal    public static final String EXTRA_REMOTEVIEWS_PENDINGINTENT =
213f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal            "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_PENDINGINTENT";
214f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal
215f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal    /**
216f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * Extra that specifies which {@link View} has been clicked. This extra will be put to the
217f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * {@link PendingIntent} sent from Custom Tabs when a view in the {@link RemoteViews} is clicked
218f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     * @see CustomTabsIntent.Builder#setSecondaryToolbarViews(RemoteViews, int[], PendingIntent).
219f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal     */
220f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal    public static final String EXTRA_REMOTEVIEWS_CLICKED_ID =
221f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal            "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_CLICKED_ID";
222f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal
2232c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen    /**
2242c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen     * Extra that specifies whether Instant Apps is enabled.
2252c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen     */
2262c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen    public static final String EXTRA_ENABLE_INSTANT_APPS =
2272c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen            "android.support.customtabs.extra.EXTRA_ENABLE_INSTANT_APPS";
228f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal
229f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal    /**
230179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal     * Key that specifies the unique ID for an action button. To make a button to show on the
231179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal     * toolbar, use {@link #TOOLBAR_ACTION_BUTTON_ID} as its ID.
232179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal     */
233179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal    public static final String KEY_ID = "android.support.customtabs.customaction.ID";
234179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal
235179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal    /**
236179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal     * The ID allocated to the custom action button that is shown on the toolbar.
237179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal     */
238179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal    public static final int TOOLBAR_ACTION_BUTTON_ID = 0;
239179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal
240179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal    /**
24131d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal     * The maximum allowed number of toolbar items.
242179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal     */
24331d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal    private static final int MAX_TOOLBAR_ITEMS = 5;
244179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal
245179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal    /**
24697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     * An {@link Intent} used to start the Custom Tabs Activity.
24797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     */
24897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    @NonNull public final Intent intent;
24997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
25097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    /**
25197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     * A {@link Bundle} containing the start animation for the Custom Tabs Activity.
25208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
25397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    @Nullable public final Bundle startAnimationBundle;
25497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
25597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    /**
25697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     * Convenience method to launch a Custom Tabs Activity.
2572109fdc5812946a98d8dd46b8b005277a2e10b00Alan Viverette     * @param context The source Context.
25897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     * @param url The URL to load in the Custom Tab.
25997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     */
2602109fdc5812946a98d8dd46b8b005277a2e10b00Alan Viverette    public void launchUrl(Context context, Uri url) {
26197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        intent.setData(url);
2622109fdc5812946a98d8dd46b8b005277a2e10b00Alan Viverette        ContextCompat.startActivity(context, intent, startAnimationBundle);
26397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    }
26497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
26597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    private CustomTabsIntent(Intent intent, Bundle startAnimationBundle) {
26697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        this.intent = intent;
26797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        this.startAnimationBundle = startAnimationBundle;
26808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    }
26908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
27008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
27197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     * Builder class for {@link CustomTabsIntent} objects.
27297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize     */
27397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize    public static final class Builder {
27497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        private final Intent mIntent = new Intent(Intent.ACTION_VIEW);
27597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        private ArrayList<Bundle> mMenuItems = null;
27697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        private Bundle mStartAnimationBundle = null;
277179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal        private ArrayList<Bundle> mActionButtons = null;
2782c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen        private boolean mInstantAppsEnabled = true;
27997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
28097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        /**
28197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * Creates a {@link CustomTabsIntent.Builder} object associated with no
28297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * {@link CustomTabsSession}.
28397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         */
28497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        public Builder() {
28597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            this(null);
28697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        }
28797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
28897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        /**
28997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * Creates a {@link CustomTabsIntent.Builder} object associated with a given
29097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * {@link CustomTabsSession}.
29197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         *
29297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * Guarantees that the {@link Intent} will be sent to the same component as the one the
29397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * session is associated with.
29497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         *
29597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param session The session to associate this Builder with.
29697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         */
29797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        public Builder(@Nullable CustomTabsSession session) {
29897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            if (session != null) mIntent.setPackage(session.getComponentName().getPackageName());
29997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            Bundle bundle = new Bundle();
300c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal            BundleCompat.putBinder(
301c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal                    bundle, EXTRA_SESSION, session == null ? null : session.getBinder());
30297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            mIntent.putExtras(bundle);
30397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        }
30497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
30597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        /**
30697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * Sets the toolbar color.
30797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         *
30897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param color {@link Color}
30997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         */
31097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        public Builder setToolbarColor(@ColorInt int color) {
31197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            mIntent.putExtra(EXTRA_TOOLBAR_COLOR, color);
31297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            return this;
31397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        }
31497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
31597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        /**
3169440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal         * Enables the url bar to hide as the user scrolls down on the page.
3179440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal         */
3189440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal        public Builder enableUrlBarHiding() {
3199440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal            mIntent.putExtra(EXTRA_ENABLE_URLBAR_HIDING, true);
3209440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal            return this;
3219440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal        }
3229440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal
3239440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal        /**
32497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * Sets the Close button icon for the custom tab.
32597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         *
32697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param icon The icon {@link Bitmap}
32797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         */
32897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        public Builder setCloseButtonIcon(@NonNull Bitmap icon) {
32997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            mIntent.putExtra(EXTRA_CLOSE_BUTTON_ICON, icon);
33097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            return this;
33197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        }
33297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
33397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        /**
33497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * Sets whether the title should be shown in the custom tab.
33597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         *
33697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param showTitle Whether the title should be shown.
33797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         */
33897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        public Builder setShowTitle(boolean showTitle) {
33997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            mIntent.putExtra(EXTRA_TITLE_VISIBILITY_STATE,
34097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize                    showTitle ? SHOW_PAGE_TITLE : NO_TITLE);
34197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            return this;
34297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        }
34397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
34497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        /**
34597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * Adds a menu item.
34697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         *
34797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param label Menu label.
34897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param pendingIntent Pending intent delivered when the menu item is clicked.
34997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         */
35097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        public Builder addMenuItem(@NonNull String label, @NonNull PendingIntent pendingIntent) {
35197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            if (mMenuItems == null) mMenuItems = new ArrayList<>();
35297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            Bundle bundle = new Bundle();
35397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            bundle.putString(KEY_MENU_ITEM_TITLE, label);
35497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            bundle.putParcelable(KEY_PENDING_INTENT, pendingIntent);
35597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            mMenuItems.add(bundle);
35697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            return this;
35797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        }
35897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
35997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        /**
3608b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal         * Adds a default share item to the menu.
3618b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal         */
3628b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal        public Builder addDefaultShareMenuItem() {
3638b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal            mIntent.putExtra(EXTRA_DEFAULT_SHARE_MENU_ITEM, true);
3648b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal            return this;
3658b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal        }
3668b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal
3678b26db5521378d84391e4ac4c932ca39d1ac83e1Yusuf Ozuysal        /**
368f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         * Sets the action button that is displayed in the Toolbar.
369179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * <p>
370179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * This is equivalent to calling
37131d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal         * {@link CustomTabsIntent.Builder#addToolbarItem(int, Bitmap, String, PendingIntent)}
372179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * with {@link #TOOLBAR_ACTION_BUTTON_ID} as id.
37397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         *
37497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param icon The icon.
3758a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal         * @param description The description for the button. To be used for accessibility.
37697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param pendingIntent pending intent delivered when the button is clicked.
3779440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal         * @param shouldTint Whether the action button should be tinted.
378179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         *
37931d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal         * @see CustomTabsIntent.Builder#addToolbarItem(int, Bitmap, String, PendingIntent)
38097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         */
3819440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal        public Builder setActionButton(@NonNull Bitmap icon, @NonNull String description,
3829440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal                @NonNull PendingIntent pendingIntent, boolean shouldTint) {
38397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            Bundle bundle = new Bundle();
384179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            bundle.putInt(KEY_ID, TOOLBAR_ACTION_BUTTON_ID);
38597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            bundle.putParcelable(KEY_ICON, icon);
3868a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal            bundle.putString(KEY_DESCRIPTION, description);
38797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            bundle.putParcelable(KEY_PENDING_INTENT, pendingIntent);
38897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            mIntent.putExtra(EXTRA_ACTION_BUTTON_BUNDLE, bundle);
3899440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal            mIntent.putExtra(EXTRA_TINT_ACTION_BUTTON, shouldTint);
39097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            return this;
39197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        }
39297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
39397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        /**
394179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * Sets the action button that is displayed in the Toolbar with default tinting behavior.
395179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         *
396179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * @see {@link CustomTabsIntent.Builder#setActionButton(
3979440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal         * Bitmap, String, PendingIntent, boolean)}
3989440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal         */
3999440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal        public Builder setActionButton(@NonNull Bitmap icon, @NonNull String description,
4009440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal                @NonNull PendingIntent pendingIntent) {
4019440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal            return setActionButton(icon, description, pendingIntent, false);
4029440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal        }
4039440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal
4049440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal        /**
405179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * Adds an action button to the custom tab. Multiple buttons can be added via this method.
406179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * If the given id equals {@link #TOOLBAR_ACTION_BUTTON_ID}, the button will be placed on
407179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * the toolbar; if the bitmap is too wide, it will be put to the bottom bar instead. If
40831d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal         * the id is not {@link #TOOLBAR_ACTION_BUTTON_ID}, it will be directly put on secondary
40931d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal         * toolbar. The maximum number of allowed toolbar items in a single intent is
41031d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal         * {@link CustomTabsIntent#getMaxToolbarItems()}. Throws an
41131d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal         * {@link IllegalStateException} when that number is exceeded per intent.
412179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         *
413179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * @param id The unique id of the action button. This should be non-negative.
414179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * @param icon The icon.
415179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * @param description The description for the button. To be used for accessibility.
416179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         * @param pendingIntent The pending intent delivered when the button is clicked.
417179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         *
41851c7c534e9fd93942aee5edce244f2e2a6e57f34Yusuf Ozuysal         * @see CustomTabsIntent#getMaxToolbarItems()
419f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         * @deprecated Use
420f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         * CustomTabsIntent.Builder#setSecondaryToolbarViews(RemoteViews, int[], PendingIntent).
421179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal         */
422f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal        @Deprecated
42331d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal        public Builder addToolbarItem(int id, @NonNull Bitmap icon, @NonNull String description,
424179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal                PendingIntent pendingIntent) throws IllegalStateException {
425179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            if (mActionButtons == null) {
426179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal                mActionButtons = new ArrayList<>();
427179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            }
42831d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal            if (mActionButtons.size() >= MAX_TOOLBAR_ITEMS) {
429179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal                throw new IllegalStateException(
43031d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal                        "Exceeded maximum toolbar item count of " + MAX_TOOLBAR_ITEMS);
431179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            }
432179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            Bundle bundle = new Bundle();
433179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            bundle.putInt(KEY_ID, id);
434179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            bundle.putParcelable(KEY_ICON, icon);
435179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            bundle.putString(KEY_DESCRIPTION, description);
436179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            bundle.putParcelable(KEY_PENDING_INTENT, pendingIntent);
437179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            mActionButtons.add(bundle);
438179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            return this;
439179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal        }
440179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal
441179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal        /**
44231d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal         * Sets the color of the secondary toolbar.
44331d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal         * @param color The color for the secondary toolbar.
44464694064caedb59afda4ef69b04feaee12c0a33fYusuf Ozuysal         */
44531d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal        public Builder setSecondaryToolbarColor(@ColorInt int color) {
44631d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal            mIntent.putExtra(EXTRA_SECONDARY_TOOLBAR_COLOR, color);
44764694064caedb59afda4ef69b04feaee12c0a33fYusuf Ozuysal            return this;
44864694064caedb59afda4ef69b04feaee12c0a33fYusuf Ozuysal        }
44964694064caedb59afda4ef69b04feaee12c0a33fYusuf Ozuysal
45064694064caedb59afda4ef69b04feaee12c0a33fYusuf Ozuysal        /**
451f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         * Sets the remote views displayed in the secondary toolbar in a custom tab.
452f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         *
453f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         * @param remoteViews   The {@link RemoteViews} that will be shown on the secondary toolbar.
454f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         * @param clickableIDs  The IDs of clickable views. The onClick event of these views will be
455f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         *                      handled by custom tabs.
456f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         * @param pendingIntent The {@link PendingIntent} that will be sent when the user clicks on
457f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         *                      one of the {@link View}s in clickableIDs. When the
458f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         *                      {@link PendingIntent} is sent, it will have the current URL as its
459f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         *                      intent data.
46051c7c534e9fd93942aee5edce244f2e2a6e57f34Yusuf Ozuysal         * @see CustomTabsIntent#EXTRA_REMOTEVIEWS
46151c7c534e9fd93942aee5edce244f2e2a6e57f34Yusuf Ozuysal         * @see CustomTabsIntent#EXTRA_REMOTEVIEWS_VIEW_IDS
46251c7c534e9fd93942aee5edce244f2e2a6e57f34Yusuf Ozuysal         * @see CustomTabsIntent#EXTRA_REMOTEVIEWS_PENDINGINTENT
46351c7c534e9fd93942aee5edce244f2e2a6e57f34Yusuf Ozuysal         * @see CustomTabsIntent#EXTRA_REMOTEVIEWS_CLICKED_ID
464f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         */
465f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal        public Builder setSecondaryToolbarViews(@NonNull RemoteViews remoteViews,
466f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal                @Nullable int[] clickableIDs, @Nullable PendingIntent pendingIntent) {
467f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal            mIntent.putExtra(EXTRA_REMOTEVIEWS, remoteViews);
468f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal            mIntent.putExtra(EXTRA_REMOTEVIEWS_VIEW_IDS, clickableIDs);
469f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal            mIntent.putExtra(EXTRA_REMOTEVIEWS_PENDINGINTENT, pendingIntent);
470f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal            return this;
471f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal        }
472f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal
473f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal        /**
4742c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen         * Sets whether Instant Apps is enabled for this Custom Tab.
4752c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen
4762c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen         * @param enabled Whether Instant Apps should be enabled.
4772c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen         */
4782c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen        public Builder setInstantAppsEnabled(boolean enabled) {
4792c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen            mInstantAppsEnabled = enabled;
4802c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen            return this;
4812c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen        }
4822c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen
4832c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen        /**
484f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         * Sets the start animations.
48597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         *
48697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param context Application context.
48797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param enterResId Resource ID of the "enter" animation for the browser.
48897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param exitResId Resource ID of the "exit" animation for the application.
48997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         */
49097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        public Builder setStartAnimations(
49197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize                @NonNull Context context, @AnimRes int enterResId, @AnimRes int exitResId) {
4921b7158bbc0d0ba4569881f547d12f52e405e125eIan Lake            mStartAnimationBundle = ActivityOptionsCompat.makeCustomAnimation(
4931b7158bbc0d0ba4569881f547d12f52e405e125eIan Lake                    context, enterResId, exitResId).toBundle();
49497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            return this;
49597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        }
49697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
49797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        /**
498f75fe23543be03eba16f915724caf3a15e036a7fYusuf Ozuysal         * Sets the exit animations.
49997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         *
50097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param context Application context.
50197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param enterResId Resource ID of the "enter" animation for the application.
50297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * @param exitResId Resource ID of the "exit" animation for the browser.
50397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         */
50497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        public Builder setExitAnimations(
50597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize                @NonNull Context context, @AnimRes int enterResId, @AnimRes int exitResId) {
5061b7158bbc0d0ba4569881f547d12f52e405e125eIan Lake            Bundle bundle = ActivityOptionsCompat.makeCustomAnimation(
5071b7158bbc0d0ba4569881f547d12f52e405e125eIan Lake                    context, enterResId, exitResId).toBundle();
50897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            mIntent.putExtra(EXTRA_EXIT_ANIMATION_BUNDLE, bundle);
50997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            return this;
51097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        }
51197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize
51297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        /**
51397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * Combines all the options that have been set and returns a new {@link CustomTabsIntent}
51497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         * object.
51597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize         */
51697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        public CustomTabsIntent build() {
51797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            if (mMenuItems != null) {
51897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize                mIntent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_MENU_ITEMS, mMenuItems);
51997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            }
520179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            if (mActionButtons != null) {
52131d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal                mIntent.putParcelableArrayListExtra(EXTRA_TOOLBAR_ITEMS, mActionButtons);
522179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal            }
5232c1994fe5a72dc1a6c320034f86598a168ce4527Ian Wen            mIntent.putExtra(EXTRA_ENABLE_INSTANT_APPS, mInstantAppsEnabled);
52497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize            return new CustomTabsIntent(mIntent, mStartAnimationBundle);
52597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize        }
52608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    }
527179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal
528179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal    /**
52931d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal     * @return The maximum number of allowed toolbar items for
53031d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal     * {@link CustomTabsIntent.Builder#addToolbarItem(int, Bitmap, String, PendingIntent)} and
53131d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal     * {@link CustomTabsIntent#EXTRA_TOOLBAR_ITEMS}.
532179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal     */
53331d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal    public static int getMaxToolbarItems() {
53431d3693ce923831667ce9e3c83d1bdd3f66742d8Yusuf Ozuysal        return MAX_TOOLBAR_ITEMS;
535179ab306d366df2ac610dd8c72bf19a5a8887970Yusuf Ozuysal    }
536821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal
537821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal    /**
538821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * Adds the necessary flags and extras to signal any browser supporting custom tabs to use the
539821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * browser UI at all times and avoid showing custom tab like UI. Calling this with an intent
540821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * will override any custom tabs related customizations.
541821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * @param intent The intent to modify for always showing browser UI.
542821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * @return The same intent with the necessary flags and extras added.
543821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     */
544821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal    public static Intent setAlwaysUseBrowserUI(Intent intent) {
545821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal        if (intent == null) intent = new Intent(Intent.ACTION_VIEW);
546821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
547821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal        intent.putExtra(EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS, true);
548821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal        return intent;
549821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal    }
550821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal
551821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal    /**
552821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * Whether a browser receiving the given intent should always use browser UI and avoid using any
553821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * custom tabs UI.
554821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     *
555821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * @param intent The intent to check for the required flags and extras.
556821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     * @return Whether the browser UI should be used exclusively.
557821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal     */
558821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal    public static boolean shouldAlwaysUseBrowserUI(Intent intent) {
559821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal        return intent.getBooleanExtra(EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS, false)
560821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal                && (intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0;
561821c3a5e31f43e186a240fa9a28ee4799937b861Yusuf Ozuysal    }
56208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal}
563