38
38
39
39
import org .json .JSONException ;
40
40
41
+ import java .util .Collections ;
42
+ import java .util .Map ;
43
+ import java .util .Objects ;
44
+
41
45
/**
42
46
* A convenience class to make using Trusted Web Activities easier. You can extend this class for
43
47
* basic modifications to the behaviour.
@@ -200,8 +204,9 @@ protected void launchTwa() {
200
204
getColorCompat (mMetadata .navigationBarDividerColorDarkId ))
201
205
.build ();
202
206
207
+ LaunchUrlBundle launchUrlBundle = getLaunchUrlBundle ();
203
208
TrustedWebActivityIntentBuilder twaBuilder =
204
- new TrustedWebActivityIntentBuilder (getLaunchingUrl ())
209
+ new TrustedWebActivityIntentBuilder (launchUrlBundle . getResolvedUrl ())
205
210
.setToolbarColor (getColorCompat (mMetadata .statusBarColorId ))
206
211
.setNavigationBarColor (getColorCompat (mMetadata .navigationBarColorId ))
207
212
.setNavigationBarDividerColor (
@@ -212,6 +217,9 @@ protected void launchTwa() {
212
217
.setDisplayMode (getDisplayMode ())
213
218
.setScreenOrientation (mMetadata .screenOrientation );
214
219
220
+ // TODO When available
221
+ // twaBuilder.setOriginalLaunchUrl(launchUrlBundle.getOriginalUrl());
222
+
215
223
if (mMetadata .additionalTrustedOrigins != null ) {
216
224
twaBuilder .setAdditionalTrustedOrigins (mMetadata .additionalTrustedOrigins );
217
225
}
@@ -339,26 +347,54 @@ public void onEnterAnimationComplete() {
339
347
}
340
348
341
349
/**
342
- * Returns the URL that the Trusted Web Activity should be launched to. By default this
343
- * implementation checks to see if the Activity was launched with an Intent with data, if so
344
- * attempt to launch to that URL. If not, read the
350
+ * Override this to enable Protocol Handler support.
351
+ * Keys of this map are data schemes, e.g. "bitcoin", "irc", "xmpp", "web+coffee", and values
352
+ * are templates that will be used to construct the full URL. The template must contain a "%s"
353
+ * token and be an absolute location with http/https scheme and the same origin as the TWA.
354
+ *
355
+ * An example valid entry in the map would be:
356
+ * ["web+coffee"] -> ["https://coffee.com/?type=%s"]
357
+ * This would result in a link "web+coffee://latte" being converted to
358
+ * "https://coffee.com/?type=latte".
359
+ *
360
+ * {@see https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Manifest/Reference/protocol_handlers}
361
+ */
362
+ protected Map <String , Uri > getProtocolHandlers () {
363
+ return Collections .emptyMap ();
364
+ }
365
+
366
+ /**
367
+ * Returns the {@link LaunchUrlBundle} that the Trusted Web Activity should be launched to.
368
+ * By default this implementation starts by checking if the Activity was launched with an Intent
369
+ * with data. If so, check if that URL is a Protocol Handler custom scheme and if so, convert
370
+ * it to an appropriate http/https location (keeping the original custom scheme URL in the
371
+ * bundle). Otherwise, read the
345
372
* "android.support.customtabs.trusted.DEFAULT_URL" metadata from the manifest.
346
373
*
347
374
* Override this for special handling (such as ignoring or sanitising data from the Intent).
348
375
*/
349
- protected Uri getLaunchingUrl () {
350
- Uri uri = getIntent ().getData ();
351
- if (uri != null ) {
352
- Log .d (TAG , "Using URL from Intent (" + uri + ")." );
353
- return uri ;
354
- }
355
-
356
- if (mMetadata .defaultUrl != null ) {
357
- Log .d (TAG , "Using URL from Manifest (" + mMetadata .defaultUrl + ")." );
358
- return Uri .parse (mMetadata .defaultUrl );
376
+ protected LaunchUrlBundle getLaunchUrlBundle () {
377
+ Uri baseUrl = Uri .parse (mMetadata .defaultUrl );
378
+
379
+ Uri intentUrl = getIntent ().getData ();
380
+
381
+ if (intentUrl != null ) {
382
+ Map <String , Uri > protocolHandlers = getProtocolHandlers ();
383
+ String scheme = intentUrl .getScheme ();
384
+ if (protocolHandlers .containsKey (scheme )) {
385
+ String format = Objects .requireNonNull (protocolHandlers .get (scheme )).toString ();
386
+ String target = intentUrl .toString ().replace (scheme + "://" , "" );
387
+ Uri targetUrl = Uri .parse (String .format (format , target ));
388
+ Log .d (TAG , "Using protocol handler url: " + targetUrl );
389
+ return new LaunchUrlBundle (targetUrl , intentUrl );
390
+ }
391
+
392
+ Log .d (TAG , "Using url from Intent: " + intentUrl );
393
+ return new LaunchUrlBundle (intentUrl , null );
359
394
}
360
395
361
- return Uri .parse ("https://www.example.com/" );
396
+ Log .d (TAG , "Using url from Manifest: " + baseUrl );
397
+ return new LaunchUrlBundle (baseUrl , null );
362
398
}
363
399
364
400
/**
0 commit comments