public static Action pickProvider(PackageManager pm) {
        // TODO(peconn): Should we use "https://" instead?
        Intent queryBrowsersIntent = new Intent()
                .setAction(Intent.ACTION_VIEW)
                .addCategory(Intent.CATEGORY_BROWSABLE)
                .setData(Uri.parse("http://"));

        if (sPackageNameForTesting != null) {
            queryBrowsersIntent.setPackage(sPackageNameForTesting);
        }

        String bestCctProvider = null;
        String bestBrowserProvider = null;

        // These packages will be in order of Android's preference.
        List<ResolveInfo> possibleProviders
                = pm.queryIntentActivities(queryBrowsersIntent, PackageManager.MATCH_DEFAULT_ONLY);

        // According to the documentation, the flag we want to use above is MATCH_DEFAULT_ONLY.
        // This would match all the browsers installed on the user's system whose intent handler
        // contains the category Intent.CATEGORY_DEFAULT. However, in Android M the behavior of
        // the PackageManager changed to only return the default browser unless the MATCH_ALL is
        // passed (this is specific to querying browsers - if you query for any other type of
        // package, MATCH_DEFAULT_ONLY will work as documented). This flag did not exist on Android
        // versions before M, so we only use it in that case.
        //
        // Additionally we add the result of the call with MATCH_ALL onto the end of the result of
        // MATCH_DEFAULT_ONLY (instead of calling queryIntentActivities just once, with MATCH_ALL)
        // because (again, as opposed to the documentation) when MATCH_ALL is used the results are
        // not returned in order of Android's preference.
        //
        // This will result in the user's default browser being in the list twice, however that
        // shouldn't affect the correctness of the following code.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            possibleProviders.addAll(pm.queryIntentActivities(queryBrowsersIntent,
                    PackageManager.MATCH_ALL));
        }

        Map<String, Integer> customTabsServices = getLaunchModesForCustomTabsServices(pm);

        for (ResolveInfo possibleProvider : possibleProviders) {
            String providerName = possibleProvider.activityInfo.packageName;

            @LaunchMode int launchMode = customTabsServices.containsKey(providerName)
                    ? customTabsServices.get(providerName) : LaunchMode.BROWSER;

            switch (launchMode) {
                case LaunchMode.TRUSTED_WEB_ACTIVITY:
                    Log.d(TAG, "Found TWA provider, finishing search: " + providerName);
                    return new Action(LaunchMode.TRUSTED_WEB_ACTIVITY, providerName);
                case LaunchMode.CUSTOM_TAB:
                    Log.d(TAG, "Found Custom Tabs provider: " + providerName);
                    if (bestCctProvider == null) bestCctProvider = providerName;
                    break;
                case LaunchMode.BROWSER:
                    Log.d(TAG, "Found browser: " + providerName);
                    if (bestBrowserProvider == null) bestBrowserProvider = providerName;
                    break;
            }
        }

        if (bestCctProvider != null) {
            Log.d(TAG, "Found no TWA providers, using first Custom Tabs provider: "
                    + bestCctProvider);
            return new Action(LaunchMode.CUSTOM_TAB, bestCctProvider);
        }

        Log.d(TAG, "Found no TWA providers, using first browser: " + bestBrowserProvider);
        return new Action(LaunchMode.BROWSER, bestBrowserProvider);
    }
Chooses an appropriate provider (see class description) and the launch mode that browser
supports.
customtabs/src/android/support/customtabs/trusted/TwaProviderPicker.java