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
198e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
208e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
2108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.content.ComponentName;
2208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.content.Context;
2308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.content.Intent;
2408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.content.ServiceConnection;
254382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lizeimport android.content.pm.PackageManager;
264382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lizeimport android.content.pm.ResolveInfo;
2708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.net.Uri;
2808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.os.Bundle;
29914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.os.Handler;
30914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.os.Looper;
3108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.os.RemoteException;
324382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lizeimport android.support.annotation.Nullable;
33c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo;
3408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.text.TextUtils;
3508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
364382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lizeimport java.util.ArrayList;
3708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport java.util.List;
3808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
3908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal/**
4008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Class to communicate with a {@link CustomTabsService} and create
4108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * {@link CustomTabsSession} from it.
4208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */
4308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalpublic class CustomTabsClient {
4408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    private final ICustomTabsService mService;
4508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    private final ComponentName mServiceComponentName;
4608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
4708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**@hide*/
488e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas    @RestrictTo(LIBRARY_GROUP)
4908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    CustomTabsClient(ICustomTabsService service, ComponentName componentName) {
5008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        mService = service;
5108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        mServiceComponentName = componentName;
5208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    }
5308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
5408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
5508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * Bind to a {@link CustomTabsService} using the given package name and
5608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * {@link ServiceConnection}.
5708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * @param context     {@link Context} to use while calling
5808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     *                    {@link Context#bindService(Intent, ServiceConnection, int)}
5908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * @param packageName Package name to set on the {@link Intent} for binding.
6008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * @param connection  {@link CustomTabsServiceConnection} to use when binding. This will
6108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     *                    return a {@link CustomTabsClient} on
6208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     *                    {@link CustomTabsServiceConnection
6308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     *                    #onCustomTabsServiceConnected(ComponentName, CustomTabsClient)}
6408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * @return Whether the binding was successful.
6508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
6608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public static boolean bindCustomTabsService(Context context,
6708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            String packageName, CustomTabsServiceConnection connection) {
6808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        Intent intent = new Intent(CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION);
6908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        if (!TextUtils.isEmpty(packageName)) intent.setPackage(packageName);
7008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        return context.bindService(intent, connection,
7108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal                Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY);
7208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    }
7308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
7408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
754382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * Returns the preferred package to use for Custom Tabs, preferring the default VIEW handler.
764382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     *
77377357a8c26c8c54ba8cb876ae775265635a8448Elliot Waite     * @see #getPackageName(Context, List<String>, boolean)
784382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     */
794382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize    public static String getPackageName(Context context, @Nullable List<String> packages) {
804382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        return getPackageName(context, packages, false);
814382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize    }
824382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize
834382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize    /**
844382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * Returns the preferred package to use for Custom Tabs.
854382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     *
8651c7c534e9fd93942aee5edce244f2e2a6e57f34Yusuf Ozuysal     * The preferred package name is the default VIEW intent handler as long as it supports Custom
8751c7c534e9fd93942aee5edce244f2e2a6e57f34Yusuf Ozuysal     * Tabs. To modify this preferred behavior, set <code>ignoreDefault</code> to true and give a
8851c7c534e9fd93942aee5edce244f2e2a6e57f34Yusuf Ozuysal     * non empty list of package names in <code>packages</code>.
894382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     *
904382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * @param context       {@link Context} to use for querying the packages.
914382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * @param packages      Ordered list of packages to test for Custom Tabs support, in
924382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     *                      decreasing order of priority.
9351c7c534e9fd93942aee5edce244f2e2a6e57f34Yusuf Ozuysal     * @param ignoreDefault If set, the default VIEW handler won't get priority over other browsers.
944382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * @return The preferred package name for handling Custom Tabs, or <code>null</code>.
954382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     */
964382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize    public static String getPackageName(
974382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        Context context, @Nullable List<String> packages, boolean ignoreDefault) {
984382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        PackageManager pm = context.getPackageManager();
994382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize
1004382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        List<String> packageNames = packages == null ? new ArrayList<String>() : packages;
1014382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"));
1024382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize
1034382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        if (!ignoreDefault) {
1044382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize            ResolveInfo defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0);
1054382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize            if (defaultViewHandlerInfo != null) {
1064382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize                String packageName = defaultViewHandlerInfo.activityInfo.packageName;
1074382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize                packageNames = new ArrayList<String>(packageNames.size() + 1);
1084382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize                packageNames.add(packageName);
1094382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize                if (packages != null) packageNames.addAll(packages);
1104382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize            }
1114382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        }
1124382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize
1134382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        Intent serviceIntent = new Intent(CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION);
1144382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        for (String packageName : packageNames) {
1154382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize            serviceIntent.setPackage(packageName);
1164382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize            if (pm.resolveService(serviceIntent, 0) != null) return packageName;
1174382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        }
1184382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        return null;
1194382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize    }
1204382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize
1214382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize    /**
1224382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * Connects to the Custom Tabs warmup service, and initializes the browser.
1234382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     *
1244382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * This convenience method connects to the service, and immediately warms up the Custom Tabs
1254382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * implementation. Since service connection is asynchronous, the return code is not the return
1264382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * code of warmup.
1274382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * This call is optional, and clients are encouraged to connect to the service, call
1284382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * <code>warmup()</code> and create a session. In this case, calling this method is not
1294382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * necessary.
1304382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     *
1314382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * @param context     {@link Context} to use to connect to the remote service.
13234a9ce0584e6c0b64515cef6cc237f9e061518dfAurimas Liutikas     * @param packageName Package name of the target implementation.
1334382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * @return Whether the binding was successful.
1344382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     */
1354382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize    public static boolean connectAndInitialize(Context context, String packageName) {
1364382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        if (packageName == null) return false;
1374382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        final Context applicationContext = context.getApplicationContext();
1384382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
1394382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize            @Override
1404382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize            public final void onCustomTabsServiceConnected(
1414382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize                    ComponentName name, CustomTabsClient client) {
1424382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize                client.warmup(0);
1434382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize                // Unbinding immediately makes the target process "Empty", provided that it is
1444382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize                // not used by anyone else, and doesn't contain any Activity. This makes it
1454382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize                // likely to get killed, but is preferable to keeping the connection around.
1464382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize                applicationContext.unbindService(this);
1474382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize            }
1484382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize
1494382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize           @Override
1504382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize           public final void onServiceDisconnected(ComponentName componentName) { }
1514382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        };
1524382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        try {
1534382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize            return bindCustomTabsService(applicationContext, packageName, connection);
1544382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        } catch (SecurityException e) {
1554382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize            return false;
1564382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize        }
1574382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize    }
1584382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize
1594382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize    /**
16008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * Warm up the browser process.
1614382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     *
1624382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * Allows the browser application to pre-initialize itself in the background. Significantly
1634382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     * speeds up URL opening in the browser. This is asynchronous and can be called several times.
1644382b18230d2d6d400dd58eaca53a42ff0d8e387Benoit Lize     *
16508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * @param flags Reserved for future use.
16608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * @return      Whether the warmup was successful.
16708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
16808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public boolean warmup(long flags) {
16908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        try {
17008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            return mService.warmup(flags);
17108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        } catch (RemoteException e) {
17208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            return false;
17308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        }
17408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    }
17508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
17608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    /**
17708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * Creates a new session through an ICustomTabsService with the optional callback. This session
17808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * can be used to associate any related communication through the service with an intent and
17908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * then later with a Custom Tab. The client can then send later service calls or intents to
18008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * through same session-intent-Custom Tab association.
18108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * @param callback The callback through which the client will receive updates about the created
182914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal     *                 session. Can be null. All the callbacks will be received on the UI thread.
18308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     * @return The session object that was created as a result of the transaction. The client can
184914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal     *         use this to relay session specific calls.
18508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     *         Null on error.
18608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal     */
18708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    public CustomTabsSession newSession(final CustomTabsCallback callback) {
18808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        ICustomTabsCallback.Stub wrapper = new ICustomTabsCallback.Stub() {
189914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            private Handler mHandler = new Handler(Looper.getMainLooper());
190914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
191914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
192914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public void onNavigationEvent(final int navigationEvent, final Bundle extras) {
193914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                if (callback == null) return;
194914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                mHandler.post(new Runnable() {
195914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    @Override
196914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    public void run() {
197914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                        callback.onNavigationEvent(navigationEvent, extras);
198914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    }
199914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                });
200914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
201914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
202914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
203914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public void extraCallback(final String callbackName, final Bundle args)
204914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    throws RemoteException {
205914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                if (callback == null) return;
206914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                mHandler.post(new Runnable() {
207914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    @Override
208914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    public void run() {
209914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                        callback.extraCallback(callbackName, args);
210914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    }
211914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                });
212914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
213914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
21408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            @Override
215914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public void onMessageChannelReady(final Bundle extras)
216914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    throws RemoteException {
217914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                if (callback == null) return;
218914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                mHandler.post(new Runnable() {
219914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    @Override
220914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    public void run() {
221914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                        callback.onMessageChannelReady(extras);
222914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    }
223914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                });
22408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            }
225689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize
226689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize            @Override
227914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public void onPostMessage(final String message, final Bundle extras)
228914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    throws RemoteException {
229914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                if (callback == null) return;
230914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                mHandler.post(new Runnable() {
231914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    @Override
232914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    public void run() {
233914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                        callback.onPostMessage(message, extras);
234914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    }
235914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                });
236689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize            }
23708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        };
23808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal
23908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        try {
24008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            if (!mService.newSession(wrapper)) return null;
24108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        } catch (RemoteException e) {
24208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal            return null;
24308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        }
24408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal        return new CustomTabsSession(mService, wrapper, mServiceComponentName);
24508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal    }
246689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize
247689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize    public Bundle extraCommand(String commandName, Bundle args) {
248689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize        try {
249689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize            return mService.extraCommand(commandName, args);
250689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize        } catch (RemoteException e) {
251689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize            return null;
252689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize        }
253689e91d33a4c181f0fe529adcf765930ea8907e0Benoit Lize    }
25408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal}
255