Expose CustomTabsSession on TwaLauncher and LauncherActivity - #584
Expose CustomTabsSession on TwaLauncher and LauncherActivity#584dnikolaev wants to merge 1 commit into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
@googlebot I've signed CLA. |
|
Hi Dima, thanks for submitting this! I have two comments:
Thanks! |
|
Would really love to see this merged if possible, it would simplify the initialisation code in our app quite a bit! |
|
@dnikolaev is this something you are wanting to finish off yourself? |
Adds two @nullable read-only accessors over fields that already exist: - TwaLauncher#getSession() (public) - LauncherActivity#getCustomTabsSession() (protected) This unblocks PostMessage in apps that subclass LauncherActivity (e.g. Bubblewrap-generated TWAs). Since Chrome 115 enabled postMessage in TWAs, the active CustomTabsSession is the only entry point to requestPostMessageChannel / postMessage, but the high-level launcher held it privately with no accessor. The session is established asynchronously in onCustomTabsServiceConnected and cleared in onServiceDisconnected / destroy(); both getters are @nullable and document the lifecycle. No behavior change for callers that don't use them. No new fields, threads, lifecycle changes, or dependencies. No change to session creation timing. Closes GoogleChrome#472 Closes GoogleChrome#510 Refs GoogleChromeLabs/bubblewrap#954
ed5829e to
febadb4
Compare
|
@gstepniewski-google Thanks for the review, and apologies for the slow follow-up — both points are now addressed or actionable: 1. CLA — fixed. The check was failing on a 2. The observable question. You're right that the async lifecycle is the sharp edge — and it got sharper with #549 (LauncherActivity now finishes after launch), so I'd rather converge on a shape you'd accept than defend the minimal getter. Why I started with plain accessors:
That said, if you'd prefer a callback, I'm happy to add one in this PR — two shapes that stay small: a) a protected hook Tell me which (either, both, or getter-only) and I'll push it right away. One scoping note: the channel-reliability problems around postMessage (#510's timing flakiness, the Chrome 150 regression in #602) are Chromium-side and orthogonal — this change is only about reaching the session that already exists. @raffij yes — finishing this myself; today's rebase + CLA fix are that, and I'll turn the API decision around as soon as there's a signal. @sergio-veed thanks for the support — hoping this gets us over the line. |
|
Hi Dima, thanks for working on this! I agree that the full observable pattern is a bit of an overkill here and we should try to make keep this change smaller. Thanks! |
Summary
Adds two
@Nullableread-only accessors over fields that already exist:TwaLauncher#getSession()(public)LauncherActivity#getCustomTabsSession()(protected)No behavior change for callers that don't use them.
Motivation
Apps that subclass
LauncherActivity(e.g. anything generated by Bubblewrap) can't reach theCustomTabsSessionthatTwaLauncherconstructs internally. Since Chrome 115 enabledpostMessagein TWAs, that session is the only entry point torequestPostMessageChannel/postMessage, so the high-level launcher is currently incompatible with PostMessage.The
demos/twa-post-messagesample added in #429 builds its own session and does not extendLauncherActivity, so it doesn't translate to the Bubblewrap launcher path. In the wild this is worked around with reflection onmSessionor by spinning up a parallelCustomTabsServiceConnectionand relaunching the TWA — both fragile.Lifecycle
The session is established asynchronously in
onCustomTabsServiceConnectedand cleared inonServiceDisconnected/destroy(). Both getters are@Nullableand the Javadoc tells callers to guard.Usage
With this in place, a subclass can wire PostMessage on the existing
getCustomTabsCallback()hook:Verified end-to-end in a Bubblewrap-generated production app.
Scope
postMessagehelpers or callback wrappers — those belong inandroidx.browser.customtabs.DEFAULT_SESSION_ID.Closes #472. Closes #510. Refs GoogleChromeLabs/bubblewrap#954.
🤖 Generated with Claude Code