From 3b019b45d0dd055eb02deb27d14bdcf354715ca3 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 26 Sep 2026 22:41:40 -0400 Subject: [PATCH] fix(browser): the pill's site-settings line only told the truth after you opened page info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `sitePermissions` was filled in exactly one place — inside `showPageInfo`, from the answer the broker sends when the sheet is about to open. So a freshly opened window said "Nothing allowed yet" about a site it had already been granted the camera on, and only stopped saying it once you opened the sheet that made it ask. Page info itself was always right; the summary above it was not. The registry lives in the main process and does not call back, so the window has to ask. It now asks when the origin changes, which is when the answer can differ, and keeps the last origin so a same-site navigation is not a round trip per page. An edit made in the sheet also folds straight into the summary. The registry stays authoritative — this only stops the line behind the sheet disagreeing with the sheet in front of it until the next navigation. Found while testing "Open full screen": that window reported "Nothing allowed yet" for brainstorm.world while its own page info showed Camera = Allow. Verified on an SM-T220: the line now reads "Camera allowed" right after the edit, and again in a brand-new window without opening page info at all. Co-Authored-By: Claude Opus 5 (1M context) --- .../napplethost/NappletBrowserActivity.kt | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt index a32f8f27d1..4525300d1b 100644 --- a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt +++ b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt @@ -155,6 +155,9 @@ class NappletBrowserActivity : ComponentActivity() { // same address don't each trigger a round-trip. private var lastFavoriteQueryUrl: String? = null + /** The origin whose site permissions the pill is already showing. */ + private var lastSitePermissionOrigin: String? = null + // What Recents shows for this task: the page's title, favicon and theme colour. private var pageTitle: String? = null private var pageIcon: Bitmap? = null @@ -771,6 +774,20 @@ class NappletBrowserActivity : ComponentActivity() { copy(chrome = chrome.copy(url = url), title = if (newSite) BrowserChrome.displayHost(url) else title, isFavorite = false) } } + // The pill's "Site settings" line summarises this origin's camera/mic/location answers, and the + // registry that holds them lives in the main process. Until this was asked for on navigation, the + // only thing that ever filled it was opening page info — so a window said "Nothing allowed yet" + // about a site it had already been granted the camera on, and only stopped lying once you opened + // the sheet that made it ask. + BrowserChrome.originOf(url)?.let { origin -> + if (origin != lastSitePermissionOrigin) { + lastSitePermissionOrigin = origin + querySitePermissions(origin) { decisions -> + updateUi { copy(sitePermissions = decisions.filterValues { it != Decision.ASK }) } + } + } + } + if (url == lastFavoriteQueryUrl) return lastFavoriteQueryUrl = url val msg = @@ -1383,6 +1400,14 @@ class NappletBrowserActivity : ComponentActivity() { decision: Decision, ) { BrowserChrome.originOf(currentUrl())?.let { rememberSitePermission(it, permission, decision) } + // Keep the pill's summary in step with the sheet the change was made in. The registry + // is authoritative and lives in the other process, but it does not call back, so an + // edit made here would otherwise not show up until the next navigation. + updateUi { + val next = sitePermissions.toMutableMap() + if (decision == Decision.ASK) next.remove(permission) else next[permission] = decision + copy(sitePermissions = next) + } } override fun onClearSiteData() {