CustomTabsIntent.java revision 9440f0b000fc2740382eb4ae5f1afec58c245c2c
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.ActivityOptions; 2108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.app.PendingIntent; 2297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lizeimport android.content.Context; 2308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.content.Intent; 2408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.graphics.Bitmap; 2508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.graphics.Color; 2608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.net.Uri; 2708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.os.Build; 2808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.os.Bundle; 2908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.os.IBinder; 3097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lizeimport android.support.annotation.AnimRes; 3197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lizeimport android.support.annotation.NonNull; 3297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lizeimport android.support.annotation.ColorInt; 3397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lizeimport android.support.annotation.Nullable; 3408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 3508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport java.lang.reflect.InvocationTargetException; 3608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport java.lang.reflect.Method; 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 /** 4908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Extra used to match the session. This has to be included in the intent to open in 5008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * a custom tab. This is the same IBinder that gets passed to ICustomTabsService#newSession. 5108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Null if there is no need to match any service side sessions with the intent. 5208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 5308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public static final String EXTRA_SESSION = "android.support.customtabs.extra.SESSION"; 5408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 5508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal /** 5608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Extra that changes the background color for the toolbar. colorRes is an int that specifies a 5708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * {@link Color}, not a resource id. 5808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 5908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public static final String EXTRA_TOOLBAR_COLOR = 6008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal "android.support.customtabs.extra.TOOLBAR_COLOR"; 6108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 6208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal /** 639440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal * Boolean extra that enables the url bar to hide as the user scrolls down the page 649440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal */ 659440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal public static final String EXTRA_ENABLE_URLBAR_HIDING = 669440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal "android.support.customtabs.extra.ENABLE_URLBAR_HIDING"; 679440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal 689440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal /** 6997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Extra bitmap that specifies the icon of the back button on the toolbar. If the client chooses 7097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * not to customize it, a default close button will be used. 7197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 7297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public static final String EXTRA_CLOSE_BUTTON_ICON = 7397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize "android.support.customtabs.extra.CLOSE_BUTTON_ICON"; 7497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 7597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 7697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Extra (int) that specifies state for showing the page title. Default is {@link #NO_TITLE}. 7797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 7897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public static final String EXTRA_TITLE_VISIBILITY_STATE = 7997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize "android.support.customtabs.extra.TITLE_VISIBILITY"; 8097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 8197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 8297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Don't show any title. Shows only the domain. 8397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 8497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public static final int NO_TITLE = 0; 8597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 8697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 8797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Shows the page title and the domain. 8897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 8997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public static final int SHOW_PAGE_TITLE = 1; 9097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 9197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 928a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal * Bundle used for adding a custom action button to the custom tab toolbar. The client should 938a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal * provide a description, an icon {@link Bitmap} and a {@link PendingIntent} for the button. 948a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal * All three keys must be present. 9508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 9608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public static final String EXTRA_ACTION_BUTTON_BUNDLE = 9708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE"; 9808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 9908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal /** 10008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Key that specifies the {@link Bitmap} to be used as the image source for the action button. 1018a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal * The icon should't be more than 24dp in height (No padding needed. The button itself will be 1028a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal * 48dp in height) and have a width/height ratio of less than 2. 10308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 10408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public static final String KEY_ICON = "android.support.customtabs.customaction.ICON"; 10508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 10608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal /** 1078a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal * Key that specifies the content description for the custom action button. 1088a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal */ 1098a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal public static final String KEY_DESCRIPTION = 1108a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal "android.support.customtabs.customaction.DESCRIPTION"; 1118a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal 1128a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal /** 11308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Key that specifies the PendingIntent to launch when the action button or menu item was 11408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * clicked. The custom tab will be calling {@link PendingIntent#send()} on clicks after adding 11508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * the url as data. The client app can call {@link Intent#getDataString()} to get the url. 11608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 11708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public static final String KEY_PENDING_INTENT = 11808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal "android.support.customtabs.customaction.PENDING_INTENT"; 11908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 12008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal /** 1219440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal * Extra boolean that specifies whether the custom action button should be tinted. Default is 1229440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal * false and the action button will not be tinted. 1239440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal */ 1249440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal public static final String EXTRA_TINT_ACTION_BUTTON = 1259440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal "android.support.customtabs.extra.TINT_ACTION_BUTTON"; 1269440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal 1279440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal /** 12808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Use an {@code ArrayList<Bundle>} for specifying menu related params. There should be a 12908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * separate {@link Bundle} for each custom menu item. 13008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 13108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public static final String EXTRA_MENU_ITEMS = "android.support.customtabs.extra.MENU_ITEMS"; 13208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 13308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal /** 13408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Key for specifying the title of a menu item. 13508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 13608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public static final String KEY_MENU_ITEM_TITLE = 13708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal "android.support.customtabs.customaction.MENU_ITEM_TITLE"; 13808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 13908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal /** 14008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Bundle constructed out of {@link ActivityOptions} that will be running when the 14108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * {@link Activity} that holds the custom tab gets finished. A similar ActivityOptions 14208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * for creation should be constructed and given to the startActivity() call that 14308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * launches the custom tab. 14408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 14508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public static final String EXTRA_EXIT_ANIMATION_BUNDLE = 14608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal "android.support.customtabs.extra.EXIT_ANIMATION_BUNDLE"; 14708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 14808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal /** 14997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * An {@link Intent} used to start the Custom Tabs Activity. 15097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 15197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize @NonNull public final Intent intent; 15297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 15397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 15497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * A {@link Bundle} containing the start animation for the Custom Tabs Activity. 15508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 15697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize @Nullable public final Bundle startAnimationBundle; 15797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 15897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 15997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Convenience method to launch a Custom Tabs Activity. 16097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param context The source Activity. 16197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param url The URL to load in the Custom Tab. 16297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 16397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public void launchUrl(Activity context, Uri url) { 16497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize intent.setData(url); 16597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize if (startAnimationBundle != null){ 16697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize context.startActivity(intent, startAnimationBundle); 16797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } else { 16897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize context.startActivity(intent); 16997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 17097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 17197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 17297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize private CustomTabsIntent(Intent intent, Bundle startAnimationBundle) { 17397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize this.intent = intent; 17497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize this.startAnimationBundle = startAnimationBundle; 17508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } 17608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 17708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal /** 17897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Builder class for {@link CustomTabsIntent} objects. 17997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 18097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public static final class Builder { 18197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize private final Intent mIntent = new Intent(Intent.ACTION_VIEW); 18297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize private ArrayList<Bundle> mMenuItems = null; 18397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize private Bundle mStartAnimationBundle = null; 18497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 18597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 18697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Creates a {@link CustomTabsIntent.Builder} object associated with no 18797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * {@link CustomTabsSession}. 18897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 18997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public Builder() { 19097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize this(null); 19197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 19297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 19397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 19497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Creates a {@link CustomTabsIntent.Builder} object associated with a given 19597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * {@link CustomTabsSession}. 19697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * 19797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Guarantees that the {@link Intent} will be sent to the same component as the one the 19897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * session is associated with. 19997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * 20097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param session The session to associate this Builder with. 20197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 20297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public Builder(@Nullable CustomTabsSession session) { 20397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize if (session != null) mIntent.setPackage(session.getComponentName().getPackageName()); 20497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize Bundle bundle = new Bundle(); 20597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize safePutBinder(bundle, EXTRA_SESSION, session == null ? null : session.getBinder()); 20697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize mIntent.putExtras(bundle); 20797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 20897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 20997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 21097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Sets the toolbar color. 21197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * 21297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param color {@link Color} 21397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 21497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public Builder setToolbarColor(@ColorInt int color) { 21597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize mIntent.putExtra(EXTRA_TOOLBAR_COLOR, color); 21697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return this; 21797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 21897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 21997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 2209440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal * Enables the url bar to hide as the user scrolls down on the page. 2219440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal */ 2229440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal public Builder enableUrlBarHiding() { 2239440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal mIntent.putExtra(EXTRA_ENABLE_URLBAR_HIDING, true); 2249440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal return this; 2259440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal } 2269440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal 2279440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal /** 22897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Sets the Close button icon for the custom tab. 22997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * 23097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param icon The icon {@link Bitmap} 23197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 23297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public Builder setCloseButtonIcon(@NonNull Bitmap icon) { 23397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize mIntent.putExtra(EXTRA_CLOSE_BUTTON_ICON, icon); 23497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return this; 23597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 23697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 23797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 23897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Sets whether the title should be shown in the custom tab. 23997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * 24097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param showTitle Whether the title should be shown. 24197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 24297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public Builder setShowTitle(boolean showTitle) { 24397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize mIntent.putExtra(EXTRA_TITLE_VISIBILITY_STATE, 24497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize showTitle ? SHOW_PAGE_TITLE : NO_TITLE); 24597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return this; 24697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 24797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 24897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 24997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Adds a menu item. 25097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * 25197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param label Menu label. 25297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param pendingIntent Pending intent delivered when the menu item is clicked. 25397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 25497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public Builder addMenuItem(@NonNull String label, @NonNull PendingIntent pendingIntent) { 25597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize if (mMenuItems == null) mMenuItems = new ArrayList<>(); 25697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize Bundle bundle = new Bundle(); 25797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize bundle.putString(KEY_MENU_ITEM_TITLE, label); 25897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize bundle.putParcelable(KEY_PENDING_INTENT, pendingIntent); 25997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize mMenuItems.add(bundle); 26097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return this; 26197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 26297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 26397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 26497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Set the action button. 26597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * 26697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param icon The icon. 2678a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal * @param description The description for the button. To be used for accessibility. 26897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param pendingIntent pending intent delivered when the button is clicked. 2699440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal * @param shouldTint Whether the action button should be tinted. 27097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 2719440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal public Builder setActionButton(@NonNull Bitmap icon, @NonNull String description, 2729440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal @NonNull PendingIntent pendingIntent, boolean shouldTint) { 27397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize Bundle bundle = new Bundle(); 27497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize bundle.putParcelable(KEY_ICON, icon); 2758a1ccd14081000d6501622de72a16da67c33030cYusuf Ozuysal bundle.putString(KEY_DESCRIPTION, description); 27697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize bundle.putParcelable(KEY_PENDING_INTENT, pendingIntent); 27797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize mIntent.putExtra(EXTRA_ACTION_BUTTON_BUNDLE, bundle); 2789440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal mIntent.putExtra(EXTRA_TINT_ACTION_BUTTON, shouldTint); 27997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return this; 28097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 28197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 28297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 2839440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal * See {@link CustomTabsIntent.Builder#setActionButton( 2849440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal * Bitmap, String, PendingIntent, boolean)} 2859440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal */ 2869440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal public Builder setActionButton(@NonNull Bitmap icon, @NonNull String description, 2879440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal @NonNull PendingIntent pendingIntent) { 2889440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal return setActionButton(icon, description, pendingIntent, false); 2899440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal } 2909440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal 2919440f0b000fc2740382eb4ae5f1afec58c245c2cYusuf Ozuysal /** 29297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Sets the start animations, 29397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * 29497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param context Application context. 29597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param enterResId Resource ID of the "enter" animation for the browser. 29697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param exitResId Resource ID of the "exit" animation for the application. 29797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 29897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public Builder setStartAnimations( 29997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize @NonNull Context context, @AnimRes int enterResId, @AnimRes int exitResId) { 30097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize mStartAnimationBundle = 30197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize ActivityOptions.makeCustomAnimation(context, enterResId, exitResId).toBundle(); 30297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return this; 30397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 30497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 30597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 30697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Sets the exit animations, 30797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * 30897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param context Application context. 30997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param enterResId Resource ID of the "enter" animation for the application. 31097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param exitResId Resource ID of the "exit" animation for the browser. 31197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 31297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public Builder setExitAnimations( 31397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize @NonNull Context context, @AnimRes int enterResId, @AnimRes int exitResId) { 31497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize Bundle bundle = 31597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize ActivityOptions.makeCustomAnimation(context, enterResId, exitResId).toBundle(); 31697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize mIntent.putExtra(EXTRA_EXIT_ANIMATION_BUNDLE, bundle); 31797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return this; 31897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 31997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 32097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 32197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Combines all the options that have been set and returns a new {@link CustomTabsIntent} 32297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * object. 32397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 32497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public CustomTabsIntent build() { 32597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize if (mMenuItems != null) { 32697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize mIntent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_MENU_ITEMS, mMenuItems); 32797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 32897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return new CustomTabsIntent(mIntent, mStartAnimationBundle); 32997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 33097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 33197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize /** 33297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * A convenience method to handle putting an {@link IBinder} inside a {@link Bundle} for all 33397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * Android version. 33497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param bundle The bundle to insert the {@link IBinder}. 33597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param key The key to use while putting the {@link IBinder}. 33697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @param binder The {@link IBinder} to put. 33797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize * @return Whether the operation was successful. 33897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize */ 33997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize private boolean safePutBinder(Bundle bundle, String key, IBinder binder) { 34097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize try { 34197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize // {@link Bundle#putBinder} exists since JB MR2, but we have 34297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize // {@link Bundle#putIBinder} which is the same method since the dawn of time. Use 34397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize // reflection when necessary to call it. 34497ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { 34597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize bundle.putBinder(key, binder); 34697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } else { 34797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize Method putBinderMethod = 34897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize Bundle.class.getMethod("putIBinder", String.class, IBinder.class); 34997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize putBinderMethod.invoke(bundle, key, binder); 35097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 35197ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } catch (InvocationTargetException | IllegalAccessException 35297ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize | IllegalArgumentException | NoSuchMethodException e) { 35397ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return false; 35408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } 35597ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return true; 35608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } 35708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } 35808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal} 359