mirror of
https://github.com/gsantner/dandelion
synced 2024-06-18 01:25:03 +02:00
149 lines
6.4 KiB
Java
149 lines
6.4 KiB
Java
/*
|
|
This file is part of the dandelion*.
|
|
|
|
dandelion* is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
dandelion* is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with the dandelion*.
|
|
|
|
If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package com.github.dfa.diaspora_android.web.custom_tab;
|
|
|
|
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.text.TextUtils;
|
|
|
|
import com.github.dfa.diaspora_android.util.AppLog;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Helper class for Custom Tabs. Adapted from https://medium.com/ribot-labs/exploring-chrome-customs-tabs-on-android-ef427effe2f4
|
|
*/
|
|
public class CustomTabsHelper {
|
|
private static final String TAG = "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";
|
|
static final String CHROMIUM = "org.chromium.chrome";
|
|
static final String FENNEC = "org.mozilla.fennec_fdroid";
|
|
private static final String EXTRA_CUSTOM_TABS_KEEP_ALIVE =
|
|
"android.support.customtabs.extra.KEEP_ALIVE";
|
|
|
|
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.
|
|
* <p>
|
|
* 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("http://www.example.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 (!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;
|
|
} else if (packagesSupportingCustomTabs.contains(CHROMIUM)) {
|
|
sPackageNameToUse = CHROMIUM;
|
|
} else if (packagesSupportingCustomTabs.contains(FENNEC)) {
|
|
sPackageNameToUse = FENNEC;
|
|
}
|
|
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) {
|
|
AppLog.e(TAG, "Runtime exception while getting specialized handlers");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @return All possible chrome package names that provide custom tabs feature.
|
|
*/
|
|
public static String[] getPackages() {
|
|
return new String[]{"", STABLE_PACKAGE, BETA_PACKAGE, DEV_PACKAGE, LOCAL_PACKAGE, CHROMIUM, FENNEC};
|
|
}
|
|
}
|