tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 39bc83bb8632d54d70542dc5d98c046a317ec99d
parent 8a883112b1d656c1335e2f5599f77b59bd40cb60
Author: Mugurell <Mugurell@users.noreply.github.com>
Date:   Thu,  4 Dec 2025 11:37:32 +0000

Bug 2000617 - part 2 - Show a globe icon for the security indicator if security is unknown r=android-reviewers,nalexander

This should only be shown for a brief moment - until the webpage
connection details are loaded in a new tab.

Differential Revision: https://phabricator.services.mozilla.com/D274291

Diffstat:
Mmobile/android/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/CustomTabSessionState.kt | 2++
Mmobile/android/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TabSessionState.kt | 2++
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt | 11++++++++++-
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddleware.kt | 13++++++++++++-
Mmobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddlewareTest.kt | 34+++++++++++++++++++++++++++-------
Mmobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddlewareTest.kt | 29+++++++++++++++++++++++++++++
6 files changed, 82 insertions(+), 9 deletions(-)

diff --git a/mobile/android/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/CustomTabSessionState.kt b/mobile/android/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/CustomTabSessionState.kt @@ -81,6 +81,7 @@ fun createCustomTab( initialLoadFlags: EngineSession.LoadUrlFlags = EngineSession.LoadUrlFlags.none(), desktopMode: Boolean = false, trackingProtection: TrackingProtectionState = TrackingProtectionState(), + securityInfo: SecurityInfo = SecurityInfo.Unknown, ): CustomTabSessionState { return CustomTabSessionState( id = id, @@ -89,6 +90,7 @@ fun createCustomTab( url = url, title = title, private = private, + securityInfo = securityInfo, webAppManifest = webAppManifest, desktopMode = desktopMode, ), diff --git a/mobile/android/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TabSessionState.kt b/mobile/android/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TabSessionState.kt @@ -112,6 +112,7 @@ fun createTab( originalInput: String? = null, initialTextDirectiveUserActivation: Boolean = false, trackingProtection: TrackingProtectionState = TrackingProtectionState(), + securityInfo: SecurityInfo = SecurityInfo.Unknown, ): TabSessionState { return TabSessionState( id = id, @@ -119,6 +120,7 @@ fun createTab( url, private, title = title, + securityInfo = securityInfo, webAppManifest = webAppManifest, searchTerms = searchTerms, desktopMode = desktopMode, diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt @@ -23,6 +23,7 @@ import mozilla.components.browser.state.action.ShareResourceAction import mozilla.components.browser.state.search.SearchEngine import mozilla.components.browser.state.selector.getNormalOrPrivateTabs import mozilla.components.browser.state.selector.selectedTab +import mozilla.components.browser.state.state.SecurityInfo import mozilla.components.browser.state.state.content.ShareResourceState import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import mozilla.components.browser.state.store.BrowserStore @@ -1228,8 +1229,16 @@ class BrowserToolbarMiddleware( highlighted = highlight, onClick = StartPageActions.SiteInfoClicked, ) + } else if (selectedTab?.content?.securityInfo == null || + selectedTab.content.securityInfo == SecurityInfo.Unknown + ) { + ActionButtonRes( + drawableResId = iconsR.drawable.mozac_ic_globe_24, + contentDescription = toolbarR.string.mozac_browser_toolbar_content_description_site_info, + onClick = object : BrowserToolbarEvent {}, + ) } else if ( - selectedTab?.content?.securityInfo?.isSecure == true && + selectedTab.content.securityInfo.isSecure && selectedTab.trackingProtection.enabled && !selectedTab.trackingProtection.ignoredOnTrackingProtection ) { diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddleware.kt @@ -22,6 +22,7 @@ import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.launch import mozilla.components.browser.state.selector.findCustomTab import mozilla.components.browser.state.state.CustomTabSessionState +import mozilla.components.browser.state.state.SecurityInfo import mozilla.components.browser.state.store.BrowserStore import mozilla.components.compose.browser.toolbar.concept.Action import mozilla.components.compose.browser.toolbar.concept.Action.ActionButton @@ -420,8 +421,18 @@ class CustomTabBrowserToolbarMiddleware( onClick = SiteInfoClicked, ), ) + } else if (customTab?.content?.securityInfo == null || + customTab.content.securityInfo == SecurityInfo.Unknown + ) { + add( + ActionButtonRes( + drawableResId = iconsR.drawable.mozac_ic_globe_24, + contentDescription = toolbarR.string.mozac_browser_toolbar_content_description_site_info, + onClick = object : BrowserToolbarEvent {}, + ), + ) } else if ( - customTab?.content?.securityInfo?.isSecure == true && + customTab.content.securityInfo.isSecure && customTab.trackingProtection.enabled && !customTab.trackingProtection.ignoredOnTrackingProtection ) { diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddlewareTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddlewareTest.kt @@ -1819,16 +1819,18 @@ class BrowserToolbarMiddlewareTest { } @Test - fun `GIVEN the website is insecure WHEN initializing the toolbar THEN add an appropriate security indicator`() = runTest { + fun `GIVEN the website is unknown WHEN initializing the toolbar THEN add an appropriate security indicator`() = runTest { val middleware = buildMiddleware( browserStore = browserStore, useCases = useCases, ) - every { tab.content.securityInfo } returns SecurityInfo.Insecure() + every { tab.content.securityInfo } returns SecurityInfo.Unknown val expectedSecurityIndicator = ActionButtonRes( - drawableResId = iconsR.drawable.mozac_ic_shield_slash_24, + drawableResId = iconsR.drawable.mozac_ic_globe_24, contentDescription = toolbarR.string.mozac_browser_toolbar_content_description_site_info, - onClick = StartPageActions.SiteInfoClicked, + state = ActionButton.State.DEFAULT, + highlighted = false, + onClick = object : BrowserToolbarEvent {}, ) val toolbarStore = buildStore( @@ -1838,7 +1840,12 @@ class BrowserToolbarMiddlewareTest { val toolbarPageActions = toolbarStore.state.displayState.pageActionsStart assertEquals(1, toolbarPageActions.size) val securityIndicator = toolbarPageActions[0] as ActionButtonRes - assertEquals(expectedSecurityIndicator, securityIndicator) + assertEquals(expectedSecurityIndicator.drawableResId, securityIndicator.drawableResId) + assertEquals(expectedSecurityIndicator.contentDescription, securityIndicator.contentDescription) + assertEquals(expectedSecurityIndicator.state, securityIndicator.state) + assertEquals(expectedSecurityIndicator.highlighted, securityIndicator.highlighted) + assertFalse(securityIndicator.onClick is StartPageActions.SiteInfoClicked) + assertNull(securityIndicator.onLongClick) } @Test @@ -1851,6 +1858,7 @@ class BrowserToolbarMiddlewareTest { enabled = true, ignoredOnTrackingProtection = false, ), + securityInfo = SecurityInfo.Insecure(), ) val browserStore = BrowserStore( BrowserState( @@ -1899,6 +1907,7 @@ class BrowserToolbarMiddlewareTest { enabled = false, ignoredOnTrackingProtection = false, ), + securityInfo = SecurityInfo.Insecure(), ) val browserStore = BrowserStore( BrowserState( @@ -2033,7 +2042,11 @@ class BrowserToolbarMiddlewareTest { every { browserScreenState.readerModeStatus } returns readerModeStatus - val tab = createTab(url = "URL", id = tabId) + val tab = createTab( + url = "URL", + id = tabId, + securityInfo = SecurityInfo.Insecure(), + ) val browserScreenStore = buildBrowserScreenStore() @@ -2536,7 +2549,11 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN site permissions different than default WHEN observing THEN SiteInfo button is highlighted`() = runTest { - val currentTab = createTab("example.com", private = false) + val currentTab = createTab( + url = "example.com", + private = false, + securityInfo = SecurityInfo.Secure(), + ) val browserStore = BrowserStore( BrowserState(tabs = listOf(currentTab), selectedTabId = currentTab.id), ) @@ -2586,6 +2603,7 @@ class BrowserToolbarMiddlewareTest { enabled = true, ignoredOnTrackingProtection = true, ), + securityInfo = SecurityInfo.Secure(), ) val browserStore = BrowserStore( BrowserState(tabs = listOf(currentTab), selectedTabId = currentTab.id), @@ -2609,6 +2627,7 @@ class BrowserToolbarMiddlewareTest { enabled = true, ignoredOnTrackingProtection = false, ), + securityInfo = SecurityInfo.Secure(), ) val browserStore = BrowserStore( BrowserState(tabs = listOf(currentTab), selectedTabId = currentTab.id), @@ -2643,6 +2662,7 @@ class BrowserToolbarMiddlewareTest { enabled = true, ignoredOnTrackingProtection = true, ), + securityInfo = SecurityInfo.Secure(), ) val browserStore = BrowserStore( BrowserState(tabs = listOf(currentTab), selectedTabId = currentTab.id), diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddlewareTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddlewareTest.kt @@ -36,6 +36,7 @@ import mozilla.components.compose.browser.toolbar.concept.Action.ActionButtonRes import mozilla.components.compose.browser.toolbar.concept.PageOrigin import mozilla.components.compose.browser.toolbar.concept.PageOrigin.Companion.ContextualMenuOption import mozilla.components.compose.browser.toolbar.concept.PageOrigin.Companion.PageOriginContextualMenuInteractions.CopyToClipboardClicked +import mozilla.components.compose.browser.toolbar.store.BrowserToolbarInteraction.BrowserToolbarEvent import mozilla.components.compose.browser.toolbar.store.BrowserToolbarStore import mozilla.components.compose.browser.toolbar.store.ProgressBarConfig import mozilla.components.concept.engine.cookiehandling.CookieBannersStorage @@ -50,6 +51,7 @@ import mozilla.components.support.utils.ClipboardHandler import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test @@ -256,6 +258,32 @@ class CustomTabBrowserToolbarMiddlewareTest { } @Test + fun `GIVEN the website's security is unknown WHEN initializing the toolbar THEN add an appropriate security indicator`() { + every { customTab.content.securityInfo } returns SecurityInfo.Unknown + every { customTab.trackingProtection.enabled } returns true + every { customTab.trackingProtection.ignoredOnTrackingProtection } returns false + val expectedSecurityIndicator = ActionButtonRes( + drawableResId = iconsR.drawable.mozac_ic_globe_24, + contentDescription = toolbarR.string.mozac_browser_toolbar_content_description_site_info, + state = ActionButton.State.DEFAULT, + highlighted = false, + onClick = object : BrowserToolbarEvent {}, + ) + + val toolbarStore = buildStore() + + val toolbarPageActions = toolbarStore.state.displayState.pageActionsStart + assertEquals(1, toolbarPageActions.size) + val securityIndicator = toolbarPageActions[0] as ActionButtonRes + assertEquals(expectedSecurityIndicator.drawableResId, securityIndicator.drawableResId) + assertEquals(expectedSecurityIndicator.contentDescription, securityIndicator.contentDescription) + assertEquals(expectedSecurityIndicator.state, securityIndicator.state) + assertEquals(expectedSecurityIndicator.highlighted, securityIndicator.highlighted) + assertFalse(securityIndicator.onClick is StartPageActions.SiteInfoClicked) + assertNull(securityIndicator.onLongClick) + } + + @Test fun `GIVEN the website is secure WHEN initializing the toolbar THEN add an appropriate security indicator`() { every { customTab.content.securityInfo } returns SecurityInfo.Secure() every { customTab.trackingProtection.enabled } returns true @@ -300,6 +328,7 @@ class CustomTabBrowserToolbarMiddlewareTest { enabled = true, ignoredOnTrackingProtection = false, ), + securityInfo = SecurityInfo.Insecure(), ) val browserStore = BrowserStore( BrowserState(customTabs = listOf(customTab)),