-
-
Save MaTriXy/5775cb0ff98216b2a99d to your computer and use it in GitHub Desktop.
CustomTabsHelper is here to help verify if there is support for the Chrome Custom tab service.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.elkriefy.android.apps.chubbytabby; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.content.IntentFilter; | |
import android.content.pm.PackageManager; | |
import android.content.pm.ResolveInfo; | |
import android.net.Uri; | |
import android.support.customtabs.CustomTabsService; | |
import android.util.Log; | |
import java.util.ArrayList; | |
import java.util.List; | |
/** | |
* Helper class for Custom Tabs. | |
*/ | |
public class CustomTabsHelper { | |
static final String STABLE_PACKAGE = "com.android.chrome"; | |
static final String BETA_PACKAGE = "com.chrome.beta"; | |
static final String DEV_PACKAGE = "com.chrome.dev"; | |
static final String LOCAL_PACKAGE = "com.google.android.apps.chrome"; | |
private static final String TAG = "CustomTabsHelper"; | |
private static String sPackageNameToUse; | |
private CustomTabsHelper() { | |
} | |
/** | |
* Goes through all apps that handle VIEW intents and have a warmup service. Picks the one | |
* chosen by the user if there is one, otherwise makes a best effort to return a valid package | |
* name. | |
* | |
* This is <strong>not</strong> threadsafe. | |
* | |
* @param context {@link Context} to use for accessing {@link PackageManager}. | |
* @return The package name recommended to use for connecting to custom tabs related components. | |
*/ | |
public static String getPackageNameToUse(Context context) { | |
if (sPackageNameToUse != null) return sPackageNameToUse; | |
PackageManager pm = context.getPackageManager(); | |
// Get default VIEW intent handler. | |
Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.packtpub.com")); | |
ResolveInfo defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0); | |
String defaultViewHandlerPackageName = null; | |
if (defaultViewHandlerInfo != null) { | |
defaultViewHandlerPackageName = defaultViewHandlerInfo.activityInfo.packageName; | |
} | |
// Get all apps that can handle VIEW intents. | |
List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, 0); | |
List<String> packagesSupportingCustomTabs = new ArrayList<>(); | |
for (ResolveInfo info : resolvedActivityList) { | |
Intent serviceIntent = new Intent(); | |
serviceIntent.setAction(CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION); | |
serviceIntent.setPackage(info.activityInfo.packageName); | |
if (pm.resolveService(serviceIntent, 0) != null) { | |
packagesSupportingCustomTabs.add(info.activityInfo.packageName); | |
} | |
} | |
// Now packagesSupportingCustomTabs contains all apps that can handle both VIEW intents | |
// and service calls. | |
if (packagesSupportingCustomTabs.isEmpty()) { | |
sPackageNameToUse = null; | |
} else if (packagesSupportingCustomTabs.size() == 1) { | |
sPackageNameToUse = packagesSupportingCustomTabs.get(0); | |
} else if (!android.text.TextUtils.isEmpty(defaultViewHandlerPackageName) | |
&& !hasSpecializedHandlerIntents(context, activityIntent) | |
&& packagesSupportingCustomTabs.contains(defaultViewHandlerPackageName)) { | |
sPackageNameToUse = defaultViewHandlerPackageName; | |
} else if (packagesSupportingCustomTabs.contains(STABLE_PACKAGE)) { | |
sPackageNameToUse = STABLE_PACKAGE; | |
} else if (packagesSupportingCustomTabs.contains(BETA_PACKAGE)) { | |
sPackageNameToUse = BETA_PACKAGE; | |
} else if (packagesSupportingCustomTabs.contains(DEV_PACKAGE)) { | |
sPackageNameToUse = DEV_PACKAGE; | |
} else if (packagesSupportingCustomTabs.contains(LOCAL_PACKAGE)) { | |
sPackageNameToUse = LOCAL_PACKAGE; | |
} | |
return sPackageNameToUse; | |
} | |
/** | |
* Used to check whether there is a specialized handler for a given intent. | |
* | |
* @param intent The intent to check with. | |
* @return Whether there is a specialized handler for the given intent. | |
*/ | |
private static boolean hasSpecializedHandlerIntents(Context context, Intent intent) { | |
try { | |
PackageManager pm = context.getPackageManager(); | |
List<ResolveInfo> handlers = pm.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER); | |
if (handlers == null || handlers.size() == 0) { | |
return false; | |
} | |
for (ResolveInfo resolveInfo : handlers) { | |
IntentFilter filter = resolveInfo.filter; | |
if (filter == null) | |
continue; | |
if (filter.countDataAuthorities() == 0 || filter.countDataPaths() == 0) | |
continue; | |
if (resolveInfo.activityInfo == null) | |
continue; | |
return true; | |
} | |
} catch (RuntimeException e) { | |
Log.e(TAG, "Runtime exception while getting specialized handlers"); | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment