Conversation
- Add ExcludedAppsScreen with searchable app list, icons, and checkboxes - Add getInstalledApps method channel to retrieve installed Android apps - Wire excludedApps through Site model (Dart + Kotlin) and config persistence - Apply disallowedApplication in NebulaVpnService for selected packages - Add Excluded Apps entry to Advanced Settings screen Add QUERY_ALL_PACKAGES permission for excluded apps feature Required on Android 11+ for getInstalledApplications() to return all user-installed apps, not just system apps and those matching the <queries> declaration. Improve excluded apps screen performance - Flutter: switch from Column+map to ListView.builder so only visible items are rendered (fixes scroll lag) - Flutter: cache decoded icon bytes in _AppInfo to avoid re-decoding base64 on every rebuild - Flutter: bypass FormPage/SingleChildScrollView to allow proper lazy list rendering; use SimplePage directly with scrollable=none - Flutter: add cacheWidth/cacheHeight hints to Image.memory - Kotlin: move icon encoding to background thread so it no longer blocks the main thread during initial load Two-phase app loading: show list immediately, icons fill in after - Split getInstalledApps into two methods: - android.getInstalledApps: returns names/packages only (fast) - android.getAppIcons: takes package names, returns icon map - Filter to apps with INTERNET permission via getPackagesHoldingPermissions, matching WireGuard and Tailscale's approach — eliminates system services, libraries, and background-only processes that can't be meaningfully excluded - Flutter phase 1: list appears as soon as names are loaded - Flutter phase 2: icons fetched in background, fill in with single setState - Icons stored in a separate iconCache map (no mutation of _AppInfo objects) Load icons progressively in batches of 20 Icons now fill in as each batch of 20 completes rather than all appearing at once after the full load, improving perceived performance. Implement Claude Code improvements Summary of changes 4 files modified across 5 improvements: 1. Icon resolution increased to 128x128 — MainActivity.kt now renders icons at 128x128 instead of 40x40, and excluded_apps_screen.dart uses cacheWidth: 128, cacheHeight: 128 to match. 2. Hard-coded exclusions surfaced in UI — NebulaVpnService.kt now has ALWAYS_EXCLUDED_APPS as a companion object constant (used by both startVpn() and the new channel handler). MainActivity.kt exposes android.getAlwaysExcludedApps via the method channel. The Flutter screen fetches this list and renders those apps as checked + disabled with 60% opacity and "(always excluded)" label. 3. Thread → coroutines migration — build.gradle.kts adds kotlinx-coroutines-android and lifecycle-runtime-ktx dependencies. Both getInstalledApps() and getAppIcons() in MainActivity.kt now use lifecycleScope.launch + withContext(Dispatchers.IO) instead of raw Thread + Handler.post. 4. Stale package filtering — _loadApps() in the Dart screen intersects selectedApps with the installed packages set, so uninstalled apps don't appear. The filtered list is what gets saved. 5. iconCache.addAll() instead of spread-copy — Avoids O(n) map copy per batch.
Add scrollable parameter to FormPage and use it in ExcludedAppsScreen to replace manual PopScope/SimplePage/save/cancel wiring. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of silently removing uninstalled packages from the selection, show them at the top of the list with an italic 'Not installed' label, subtle grey icon, and '(not installed)' subtitle. They remain toggleable so users can deselect them to clean up.
|
Would it make more sense to have the app exclusion at the app settings level instead of site specific to avoid having to block an app in multiple places? |
|
@nbrownus Yeah, I considered that too. I don't have a strong preference, but it could cause some confusion in the future if we allow admins to restrict exclusions for managed sites, and there may be other site-specific use cases for disallowed apps beyond "this app doesn't work because it's WiFi IoT." Your call - either way solves my issue. |
|
Yeah my immediate reaction was "I bet someone is gonna want to only filter some apps sometimes" |
|
I think for most folks having it on the site is going to be just fine and likely 100% more obvious than if it was hidden in the app settings screen. It's mostly just a bit of a bummer if you have more than 1 site. |
|
That and it's a bit more hidden and inconvenient for the majority of folks that likely have a single site. Site config seems like a fine place to put it, would like to resolve #358 first as there could be some impact to how config works. |
|
Ok, the config stuff has been reworked. We have two paths here.
|
Allows users to exclude apps from using the VPN - this is necessary for apps which need to speak to RFC 1918 space, such as IoT devices or cameras, despite the fact that the VPN does not advertise routes for this space.
Uses a 2-phase load for the app icons to avoid an observed slow load of the excluded apps page.
Uninstalled disabled apps are shown at the top, then installed & disabled, then forced disabled apps (the existing hardcoded apps), then all other apps.
Tested the behavior with an app that fails without disallowing it.