## Summary
This pull request introduces custom screen transition animations to
enhance the overall user experience during navigation.
The key change is the implementation of a custom slide/fade effect for
navigating from main screens (i.e., screens hosted in the bottom
navigation bar) to detail screens. Transitions between the bottom
navigation bar tabs themselves retain a simple, clean cross-fade effect
to ensure a fast and smooth user interaction.
This PR also addresses the root cause of an issue where custom
animations were being overridden by the navigation library's defaults.
## Root Cause
During implementation, it was discovered that custom transition
animations defined in the `defaultTransitions` parameter of the
`DestinationsNavHost` in `MainActivity` were not being applied. Instead,
a default fade-in/fade-out animation was always present.
The root cause was traced to the `compose-destinations` KSP (Kotlin
Symbol Processing) code generator. By default, the generator creates a
`NavGraphSpec` (e.g., `RootNavGraph.kt`) that includes its own
`defaultTransitions` property. This property, defined at compile-time
within the generated graph object, has a higher precedence than the
`defaultTransitions` parameter supplied to the `DestinationsNavHost`
composable at runtime.
As a result, our intended custom animations were being ignored and
overridden by the generated default.
## Solution
To resolve this precedence issue permanently, this PR adopts the
official configuration method recommended by the `compose-destinations`
library.
- The following KSP argument has been added to the
`app/build.gradle.kts` file:
```kotlin
ksp {
arg("compose-destinations.defaultTransitions", "none")
}
```
- This argument instructs the code generator to omit the
`defaultTransitions` property from the generated `NavGraphSpec`.
- By removing the higher-priority, generated default, the
`defaultTransitions` parameter on `DestinationsNavHost` now functions as
the effective default, allowing our custom animation logic to execute as
intended.
## Animation Logic Details
The new animation logic is conditional and defined within
`MainActivity`. It distinguishes between two primary navigation types:
- Main Screen → Detail Screen:
- Enter: The new detail screen slides in from the right.
- Exit: The old main screen slides out to the left while fading out.
- Detail Screen → Main Screen (on Pop):
- Pop Enter: The main screen slides back in from the left while fading
in.
- Pop Exit: The detail screen slides out to the right.
- Between Bottom Navigation Tabs:
- A simple cross-fade (`fadeIn`/`fadeOut`) is maintained for these
transitions to provide a quick and non-disruptive experience when
switching between primary sections of the app.
When kernel is compiled with CONFIG_DEBUG_ATOMIC_SLEEP enabled, it
prints the following splat in dmesg during post boot:
[ 6.739169] init: Opening SELinux policy
[ 6.751520] init: Loading SELinux policy
[ 6.894684] SELinux: policy capability network_peer_controls=1 [
6.894688] SELinux: policy capability open_perms=1 [ 6.894690] SELinux:
policy capability extended_socket_class=1 [ 6.894691] SELinux: policy
capability always_check_network=0 [ 6.894693] SELinux: policy capability
cgroup_seclabel=0 [ 6.894695] SELinux: policy capability
nnp_nosuid_transition=1 [ 7.214323] selinux: SELinux: Loaded file
context from: [ 7.214332] selinux:
/system/etc/selinux/plat_file_contexts [ 7.214339] selinux:
/system_ext/etc/selinux/system_ext_file_contexts [ 7.214345] selinux:
/product/etc/selinux/product_file_contexts [ 7.214350] selinux:
/vendor/etc/selinux/vendor_file_contexts [ 7.214356] selinux:
/odm/etc/selinux/odm_file_contexts [ 7.216398] KernelSU:
/system/bin/init argc: 2
[ 7.216401] KernelSU: /system/bin/init first arg: second_stage [
7.216403] KernelSU: /system/bin/init second_stage executed [ 7.216506]
BUG: sleeping function called from invalid context at
security/selinux/ss/hashtab.c:47 [ 7.216512] in_atomic(): 0,
irqs_disabled(): 0, non_block: 0, pid: 1, name: init [ 7.216516]
preempt_count: 0, expected: 0
[ 7.216518] RCU nest depth: 1, expected: 0
[ 7.216524] CPU: 6 PID: 1 Comm: init Not tainted
5.4.289-Scarlet-v2.0-beta3 #1 [ 7.216526] Hardware name: redwood based
Qualcomm Technologies, Inc. SM7325 (DT) [ 7.216528] Call trace:
[ 7.216536] dump_backtrace+0x0/0x210
[ 7.216539] show_stack+0x14/0x20
[ 7.216544] dump_stack+0x9c/0xec
[ 7.216548] __might_resched+0x1f0/0x210
[ 7.216552] hashtab_insert+0x38/0x230
[ 7.216557] add_type+0xd4/0x2e0
[ 7.216559] ksu_type+0x24/0x60
[ 7.216562] apply_kernelsu_rules+0xa8/0x650
[ 7.216565] ksu_handle_execveat_ksud+0x2a8/0x460
[ 7.216568] ksu_handle_execveat+0x2c/0x60
[ 7.216571] __arm64_sys_execve+0xe8/0xf0
[ 7.216574] el0_svc_common+0xf4/0x1a0
[ 7.216577] do_el0_svc+0x2c/0x40
[ 7.216579] el0_sync_handler+0x18c/0x200
[ 7.216582] el0_sync+0x140/0x180
This is because apply_kernelsu_rules() uses rcu_read_lock() to protect
SELinux policy modifications. However, cond_resched() from
hashtab_insert() at security/selinux/ss/hashtab.c is internally called
and it sleeps which is illegal under an RCU read-side critical section.
While replacing it with a spinlock would suppress the warning, this is
fundamentally incorrect because sleeping is illegal while holding a
spinlock and spinlock would turn off preemption which isn't an ideal
solution since it intentionally turns off rescheduling, and can lead to
deadlocks.
Instead, replace the RCU lock with a mutex lock. Mutex lock allows
sleeping when necessary, which is appropriate here because
apply_kernelsu_rules() runs in process context, not in atomic or
interrupt context. As apply_kernelsu_rules() is invoked only once during
post boot (SYSTEM_RUNNING), the mutex lock does not introduce any major
runtime performance regression and provides correct synchronization.
Fixes: https://github.com/tiann/KernelSU/issues/2637
Signed-off-by: Tashfin Shakeer Rhythm <tashfinshakeerrhythm@gmail.com>
Bumps the maven group with 7 updates in the /manager directory:
| Package | From | To |
| --- | --- | --- |
| androidx.compose:compose-bom | `2025.05.01` | `2025.06.00` |
| androidx.lifecycle:lifecycle-runtime-ktx | `2.9.0` | `2.9.1` |
| androidx.lifecycle:lifecycle-runtime-compose | `2.9.0` | `2.9.1` |
| androidx.lifecycle:lifecycle-viewmodel-compose | `2.9.0` | `2.9.1` |
| androidx.webkit:webkit | `1.13.0` | `1.14.0` |
| [org.lsposed.libcxx:libcxx](https://github.com/LSPosed/prefab-libcxx)
| `27.0.12077973` | `28.1.13356709` |
| [com.google.devtools.ksp](https://github.com/google/ksp) |
`2.1.21-2.0.1` | `2.1.21-2.0.2` |
Updates `androidx.compose:compose-bom` from 2025.05.01 to 2025.06.00
Updates `androidx.lifecycle:lifecycle-runtime-ktx` from 2.9.0 to 2.9.1
Updates `androidx.lifecycle:lifecycle-runtime-compose` from 2.9.0 to
2.9.1
Updates `androidx.lifecycle:lifecycle-viewmodel-compose` from 2.9.0 to
2.9.1
Updates `androidx.lifecycle:lifecycle-runtime-compose` from 2.9.0 to
2.9.1
Updates `androidx.lifecycle:lifecycle-viewmodel-compose` from 2.9.0 to
2.9.1
Updates `androidx.webkit:webkit` from 1.13.0 to 1.14.0
Updates `org.lsposed.libcxx:libcxx` from 27.0.12077973 to 28.1.13356709
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1e95c38b8a"><code>1e95c38</code></a>
28.1.13356709</li>
<li><a
href="9d672dd836"><code>9d672dd</code></a>
27.0.12077973-1</li>
<li>See full diff in <a
href="https://github.com/LSPosed/prefab-libcxx/compare/27.0.12077973...28.1.13356709">compare
view</a></li>
</ul>
</details>
<br />
Updates `com.google.devtools.ksp` from 2.1.21-2.0.1 to 2.1.21-2.0.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/google/ksp/releases">com.google.devtools.ksp's
releases</a>.</em></p>
<blockquote>
<h2>2.1.21-2.0.2</h2>
<h2>What's Changed</h2>
<p>KSP1: use new mangling scheme for inline classes <a
href="https://redirect.github.com/google/ksp/issues/2446">#2446</a>
KSP task (non-)registration happens too soon <a
href="https://redirect.github.com/google/ksp/issues/1789">#1789</a>
[ksp2] Resolver.getJvmName wrong for properties starts with is <a
href="https://redirect.github.com/google/ksp/issues/2275">#2275</a>
Inlined JVM name is not correct <a
href="https://redirect.github.com/google/ksp/issues/1493">#1493</a>
[KSP2] Annotation values of inner annotations shouldn't be marked as
default <a
href="https://redirect.github.com/google/ksp/issues/2437">#2437</a>
Properly support <a href="https://github.com/all"><code>@all</code></a>
annotation use site target <a
href="https://redirect.github.com/google/ksp/issues/2438">#2438</a></p>
<h2>Contributors</h2>
<p>Thanks to everyone who reported bugs and participated in
discussions!</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/google/ksp/compare/2.1.21-2.0.1...2.1.21-2.0.2">https://github.com/google/ksp/compare/2.1.21-2.0.1...2.1.21-2.0.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e9efa37e8c"><code>e9efa37</code></a>
Handle a weird case from Analysis API</li>
<li><a
href="0f5ff31fe7"><code>0f5ff31</code></a>
Add clarification to possible value types of KSValueArgument.value</li>
<li><a
href="2ac9a4ccd4"><code>2ac9a4c</code></a>
UPDATE_KOTLIN_VERSION: 2.1.21</li>
<li><a
href="68d41f7c71"><code>68d41f7</code></a>
Ignore .kotlin/</li>
<li><a
href="529403acb8"><code>529403a</code></a>
Support friend modules</li>
<li><a
href="9fc3e74724"><code>9fc3e74</code></a>
Cleanup: remove CompilerConfiguration</li>
<li><a
href="9323eccdde"><code>9323ecc</code></a>
Small grammatical fix, otherwised -> otherwise</li>
<li><a
href="c48c1e891d"><code>c48c1e8</code></a>
Upgrade to the latest lint-gradle checks</li>
<li><a
href="084b3e8396"><code>084b3e8</code></a>
Better naming of variables</li>
<li><a
href="12bbdfdd0a"><code>12bbdfd</code></a>
Fix origin of arguments of synthetic annotations</li>
<li>Additional commits viewable in <a
href="https://github.com/google/ksp/compare/2.1.21-2.0.1...2.1.21-2.0.2">compare
view</a></li>
</ul>
</details>
<br />
<details>
<summary>Most Recent Ignore Conditions Applied to This Pull
Request</summary>
| Dependency Name | Ignore Conditions |
| --- | --- |
| com.google.devtools.ksp | [< 1.10, > 1.9.23-1.0.20] |
</details>
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>