Skip to content

Land own-task deep links on their full back stack - #3358

Merged
StylianosGakis merged 5 commits into
developfrom
refactor/eager-deep-link-synthetic-stack
Nov 11, 2026
Merged

StylianosGakis merged 5 commits into
developfrom
refactor/eager-deep-link-synthetic-stack

Conversation

@StylianosGakis

@StylianosGakis StylianosGakis commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

I kicked off this work after watching https://www.youtube.com/watch?v=cgmY14gf4zg and trying out if any of the new APIs etc fit our needs. As far as I can tell at least, the recipes they show etc are still way too simplistic due to not handling the combination of logged in and logged out states, and deep links especially having to defer handling them after the login has happened.
However from that exploration there were some slight improvements that we can do, as described in the table below regarding the behavior before and after merging this.

How the user arrives Before After
Notification tap, app closed Screen alone, no nav bar. Back leaves the app. Screen with nav bar. Back goes to its parent, then Home, then leaves.
Notification tap, app already open Screen alone. Back returns straight to where they were. Back goes to the parent, then Home, then to where they were.
Link from an app that opens us in a new task Same as a notification tap Same as a notification tap
Link from an app that hosts us in its own task, like Keep Alone, Back returns to that app Unchanged
Any of the above while logged out After login, alone everywhere Own task gets the full stack. Other app’s task is unchanged.
Link tapped inside the app, launcher icon, recents Not affected Not affected
🤖 AI description

Changes what an external deep link lands on when it opens in our own task, to follow the navigation principles. Links hosted in another app's task behave as before.

Under the hood: "are we in our own task" used to be live state, refreshed on every resume. Now the task is checked once, when the link lands. A stack that does not start at Home or Login is the foreign-task case, and a link held while logged out stores that one fact with it.

The "app already open" row is not new stacking: a notification tap already opened a second MainActivity over the first on develop. There are now more screens above it.

Checked on the Pixel from a Keep note, via am start and from notification taps (app open and closed): logged in, through BankID logins, and across a process death during login.

An external or notification deep link used to land as a lone key, with
the ancestry rebuilt only when Up was pressed. That needed the Activity
to classify which task hosts it, an escape that relaunched the app in a
new task with the parent stack serialized into the intent, a three-way
chrome mode to hide the nav bar while the stack was a lone key, and a
retained isOwnTask value refreshed on every onResume.

Now a deep link reseeds the stack with syntheticStackFor(key) up front,
whether it arrives logged in or lands after login as the pending link.
Home is at index 0 from the first frame, so the runs model and nav bar
need no special case, Back walks the ancestry to Home before leaving,
and Up is a plain pop that is a no-op at the root. The change-payment-
method affordance loses its lone-stack branch for the same reason.

A link tapped in another app now walks through Home before returning to
that app, instead of exiting on the first Back. NavUpBarScene and its
equality test go with the chrome mode; NavSuiteScene keeps the same
key-based equals but no longer has a test proxy.
Landing every external link on its synthetic ancestry made Back from a
link opened inside another app's task walk through our screens before
returning there, and left Up inside that task. The navigation
principles want the opposite: Back returns straight to the caller and
Up moves the member into our own task.

The task is now consulted once, when the link lands. In our own task
the link gets the full ancestry as before. In another app's task it
lands alone. After that the stack shape is the record: a stack not
rooted at Home or Login can only be a foreign-hosted deep link, so Up
escapes to our own task and the nav-bar chrome hides on that shape
alone. That brings back the escape relaunch, LoneDeepLinkChrome and
NavUpBarScene unchanged, without the observable isOwnTask state, its
onResume refresh or the foreign-hosted lone Home case.

A pending link landed after login still gets its full ancestry even in
another app's task.
@StylianosGakis StylianosGakis changed the title Land external deep links on an eager synthetic back stack Land own-task deep links on their synthetic stack, derive the foreign-task case from stack shape Nov 10, 2026
A link that arrived logged out in another app's task landed on its full
synthetic stack once the member logged in, so Back walked Home before
returning to the calling app. The held link now remembers which task
hosted it, and login lands it by the same rule as a logged-in arrival.
The old name described the stack's shape. The new one says what that
shape means, with the polarity flipped to match.
@StylianosGakis StylianosGakis changed the title Land own-task deep links on their synthetic stack, derive the foreign-task case from stack shape Land own-task deep links on their full back stack Nov 10, 2026
@StylianosGakis
StylianosGakis marked this pull request as ready for review November 11, 2026 09:07
@StylianosGakis
StylianosGakis requested a review from a team as a code owner November 11, 2026 09:07
@StylianosGakis
StylianosGakis merged commit 962f894 into develop Nov 11, 2026
4 checks passed
@StylianosGakis
StylianosGakis deleted the refactor/eager-deep-link-synthetic-stack branch November 11, 2026 10:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants