Skip to content

Commit 4e54073

Browse files
Merge pull request #137 from doxo/master
Add API to use a specific Custom Tabs implementation
2 parents f464728 + b9bed6f commit 4e54073

File tree

4 files changed

+82
-23
lines changed

4 files changed

+82
-23
lines changed

src/android/ChromeCustomTabPlugin.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33

44
import android.app.Activity;
5+
import android.content.Context;
56
import android.content.Intent;
67
import android.graphics.Color;
78
import android.net.Uri;
@@ -43,6 +44,7 @@ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
4344

4445
@Override
4546
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
47+
final Context context = this.cordova.getContext();
4648

4749
switch (action) {
4850
case "isAvailable":
@@ -87,6 +89,33 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo
8789
callbackContext.sendPluginResult(pluginResult);
8890
return true;
8991
}
92+
case "getViewHandlerPackages": {
93+
PluginResult pluginResult;
94+
final JSONObject result = new JSONObject();
95+
result.put("defaultHandler", CustomTabsHelper.getDefaultViewHandlerPackageName(context));
96+
result.put("customTabsImplementations", new JSONArray(CustomTabsHelper.getPackagesSupportingCustomTabs(context)));
97+
pluginResult = new PluginResult(PluginResult.Status.OK, result);
98+
callbackContext.sendPluginResult(pluginResult);
99+
return true;
100+
}
101+
case "useCustomTabsImplementation": {
102+
PluginResult pluginResult;
103+
JSONObject result = new JSONObject();
104+
final String packageName = args.optString(0);
105+
if(TextUtils.isEmpty(packageName)) {
106+
result.put("error", "expected argument 'packageName' to be non empty string.");
107+
pluginResult = new PluginResult(PluginResult.Status.ERROR, result);
108+
} else {
109+
try {
110+
mCustomTabPluginHelper.setPackageNameToBind(packageName, context);
111+
pluginResult = new PluginResult(PluginResult.Status.OK, true);
112+
} catch (CustomTabsHelper.InvalidPackageException e) {
113+
pluginResult = new PluginResult(PluginResult.Status.ERROR, "Invalid package: "+packageName);
114+
}
115+
}
116+
callbackContext.sendPluginResult(pluginResult);
117+
return true;
118+
}
90119
case "connectToService": {
91120
if (bindCustomTabsService())
92121
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, true));
@@ -126,10 +155,10 @@ private void show(String url, @ColorInt int toolbarColor, boolean showDefaultSha
126155
builder.addDefaultShareMenuItem();
127156
if(!TextUtils.isEmpty(transition))
128157
addTransition(builder, transition);
129-
158+
130159

131160
CustomTabsIntent customTabsIntent = builder.build();
132-
161+
133162
String packageName = CustomTabsHelper.getPackageNameToUse(cordova.getActivity());
134163
if ( packageName != null ) {
135164
customTabsIntent.intent.setPackage(packageName);

src/android/helpers/CustomTabServiceHelper.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*/
2525
public class CustomTabServiceHelper implements ServiceConnectionCallback {
2626

27-
private final String mPackageNameToBind;
27+
private String mPackageNameToBind;
2828
private CustomTabsSession mCustomTabsSession;
2929
private CustomTabsClient mClient;
3030
private CustomTabsServiceConnection mConnection;
@@ -38,6 +38,11 @@ public boolean isAvailable(){
3838
return !TextUtils.isEmpty(mPackageNameToBind);
3939
}
4040

41+
public void setPackageNameToBind(String packageName, Context context) throws CustomTabsHelper.InvalidPackageException {
42+
CustomTabsHelper.setPackageNameToUse(packageName, context);
43+
mPackageNameToBind = packageName;
44+
}
45+
4146
/**
4247
* Unbinds the Activity from the Custom Tabs Service.
4348
* @param activity the activity that is connected to the service.

src/android/helpers/CustomTabsHelper.java

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public class CustomTabsHelper {
3939
"android.support.customtabs.extra.KEEP_ALIVE";
4040
private static final String ACTION_CUSTOM_TABS_CONNECTION =
4141
"android.support.customtabs.action.CustomTabsService";
42-
42+
private static final Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));
4343
private static String sPackageNameToUse;
4444

4545
private CustomTabsHelper() {}
@@ -64,25 +64,8 @@ public static String getPackageNameToUse(Context context) {
6464
if (sPackageNameToUse != null) return sPackageNameToUse;
6565

6666
PackageManager pm = context.getPackageManager();
67-
// Get default VIEW intent handler.
68-
Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));
69-
ResolveInfo defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0);
70-
String defaultViewHandlerPackageName = null;
71-
if (defaultViewHandlerInfo != null) {
72-
defaultViewHandlerPackageName = defaultViewHandlerInfo.activityInfo.packageName;
73-
}
74-
75-
// Get all apps that can handle VIEW intents.
76-
List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, PackageManager.MATCH_ALL);
77-
List<String> packagesSupportingCustomTabs = new ArrayList<>();
78-
for (ResolveInfo info : resolvedActivityList) {
79-
Intent serviceIntent = new Intent();
80-
serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION);
81-
serviceIntent.setPackage(info.activityInfo.packageName);
82-
if (pm.resolveService(serviceIntent, 0) != null) {
83-
packagesSupportingCustomTabs.add(info.activityInfo.packageName);
84-
}
85-
}
67+
final String defaultViewHandlerPackageName = getDefaultViewHandlerPackageName(context);
68+
List<String> packagesSupportingCustomTabs = getPackagesSupportingCustomTabs(context);
8669

8770
// Now packagesSupportingCustomTabs contains all apps that can handle both VIEW intents
8871
// and service calls.
@@ -106,6 +89,28 @@ public static String getPackageNameToUse(Context context) {
10689
return sPackageNameToUse;
10790
}
10891

92+
public static String getDefaultViewHandlerPackageName(Context context) {
93+
PackageManager pm = context.getPackageManager();
94+
// Get default VIEW intent handler.
95+
ResolveInfo defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0);
96+
return defaultViewHandlerInfo == null ? null : defaultViewHandlerInfo.activityInfo.packageName;
97+
}
98+
99+
public static List<String> getPackagesSupportingCustomTabs(Context context) {
100+
PackageManager pm = context.getPackageManager();
101+
List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, PackageManager.MATCH_ALL);
102+
List<String> packagesSupportingCustomTabs = new ArrayList<>();
103+
for (ResolveInfo info : resolvedActivityList) {
104+
Intent serviceIntent = new Intent();
105+
serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION);
106+
serviceIntent.setPackage(info.activityInfo.packageName);
107+
if (pm.resolveService(serviceIntent, 0) != null) {
108+
packagesSupportingCustomTabs.add(info.activityInfo.packageName);
109+
}
110+
}
111+
return packagesSupportingCustomTabs;
112+
}
113+
109114
/**
110115
* Used to check whether there is a specialized handler for a given intent.
111116
* @param intent The intent to check with.
@@ -139,4 +144,18 @@ private static boolean hasSpecializedHandlerIntents(Context context, Intent inte
139144
public static String[] getPackages() {
140145
return new String[]{"", STABLE_PACKAGE, BETA_PACKAGE, DEV_PACKAGE, LOCAL_PACKAGE};
141146
}
147+
148+
public static void setPackageNameToUse(String packageName, Context context) throws InvalidPackageException{
149+
if (getPackagesSupportingCustomTabs(context).contains(packageName)) {
150+
sPackageNameToUse = packageName;
151+
} else {
152+
throw new InvalidPackageException(packageName);
153+
}
154+
}
155+
156+
public static class InvalidPackageException extends Exception {
157+
public InvalidPackageException(String packageName) {
158+
super(packageName + " has no Custom Tabs support.");
159+
}
160+
}
142161
}

www/SafariViewController.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ module.exports = {
1919
hide: function (onSuccess, onError) {
2020
exec(onSuccess, onError, "SafariViewController", "hide", []);
2121
},
22+
getViewHandlerPackages: function (onSuccess, onError) {
23+
exec(onSuccess, onError, "SafariViewController", "getViewHandlerPackages", []);
24+
},
25+
useCustomTabsImplementation: function (packageName, onSuccess, onError) {
26+
exec(onSuccess, onError, "SafariViewController", "useCustomTabsImplementation", [packageName]);
27+
},
2228
connectToService: function (onSuccess, onError) {
2329
exec(onSuccess, onError, "SafariViewController", "connectToService", []);
2430
},

0 commit comments

Comments
 (0)