Skip to content

Preserve per-site desktop mode preferences#8877

Open
0nko wants to merge 14 commits into
developfrom
feature/ondrej/remember-desktop-mode
Open

Preserve per-site desktop mode preferences#8877
0nko wants to merge 14 commits into
developfrom
feature/ondrej/remember-desktop-mode

Conversation

@0nko

@0nko 0nko commented Jun 15, 2026

Copy link
Copy Markdown
Member

Task/Issue URL: https://app.asana.com/1/137249556945/project/1214749231578703/task/1212541545715038?focus=true

Description

This PR adds a per-site desktop mode preference persistence using eTLD+1 as a key (or "localhost" or an IP address). When a desktop mode is enabled on a site, it will be always used until it's either disabled or the site is cleared using the Fire button.

Steps to test this PR

  • Load some URL
  • Enable the Desktop mode
  • Notice the site is reloaded in a desktop mode
  • Open a new tab and load the same site
  • Notice it loads using the desktop mode
  • Use the fire button and delete this tab
  • On a NTP, load the same site
  • Notice it now loads in a mobile mode

Note

Medium Risk
Changes main-frame user-agent selection and tab UI state for desktop mode, plus new persistent data that must stay aligned with fire-button and fireproof semantics.

Overview
Adds a site-preferences module that stores “desktop site” choices in Room (keyed by eTLD+1, or raw host for localhost/IPs), with an in-memory cache primed at startup and a rememberDesktopMode remote feature toggle to fall back to session-only behavior when off.

When the feature is on, BrowserTabViewModel writes preferences on menu toggle, applies remembered mode on navigation (so desktop mode does not leak across sites), and answers isDesktopSiteEnabled(url) from storage so WebViewRequestInterceptor picks the correct user agent on first load. Fire / burn / domain clear paths now clear desktop preferences via SitePreferencesDataClearer, respecting fireproofed domains like other per-site stores.

Reviewed by Cursor Bugbot for commit c9180f6. Bugbot is set up for automated code reviews on this repo. Configure here.

0nko and others added 4 commits June 15, 2026 12:18
RealSitePreferencesRepository now implements two interfaces (SitePreferencesRepository
and MainProcessLifecycleObserver), so @ContributesBinding can no longer infer the bound
type. Specify it explicitly to fix the DI codegen failure in both AnvilDagger and Metro
builds (kaptGenerateStubs / Metro compile).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@landomen landomen self-assigned this Jun 16, 2026

@landomen landomen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@0nko It happened multiple times that I had to force refresh the site to re-render in desktop mode after opening it. See video:

Screen_recording_20260616_103558.mp4

Comment on lines +3338 to +3341
// Persist the choice per-site. uri.host is the pre-rewrite host (e.g. m.example.com), whose eTLD+1
// (example.com) matches the key the desktop-rewritten URL produces; hosts without a registrable
// domain (IPs, localhost) fall back to the raw host. The optimistic cache update means the reload
// triggered below already sees the new value.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd recommend shorter comments or even skip them if code is clear

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll let Claude know.. 😁

Entity::class,
Relation::class,
DefaultBrowserPromptsAppUsageEntity::class,
SitePreferencesEntity::class,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you maybe considered creating a new module for site-preferences and a separate database? ;)

Asking because this relates to our Modularization AOI and adding new features that use AppDatabase will make it harder later to remove them. I'm not saying you need to do the new module now, just something to keep in mind.
(cc @aibrahim- )

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need a room DB for this? it seems a simple preferences store should be enough, e.g. androidx.datastore or even a SharedPreferences

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aibrahim- It seemed like a natural choice, since the settings is per-domain, which can grow indefinitely. Plus, this would allow to store other prefs per-domain in the future. But I supposed storing it as a list of domains in a DataStore would work if the list was reasonable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@landomen Yeah, I suppose it could be a separate module. I can refactor it.

0nko and others added 6 commits June 18, 2026 10:51
# Conflicts:
#	app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt
#	app/src/test/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt
…ore the site-preferences cache is primed

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ntracts

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… remember-desktop-mode flag

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ase to version 61

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sktop-mode read

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@0nko 0nko requested a review from landomen June 18, 2026 20:29
@0nko

0nko commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

@landomen @aibrahim- I moved the site preferences to a separate module and tried to address the issue you noticed. It is now better but a site set to desktop mode occasionally still renders mobile because the desktop-UA reload is served from the HTTP cache, which can return a previously-fetched mobile copy (a forced refresh fixes it). This is a pre-existing limitation not introduced here, it is just easier to surface now that desktop mode is applied automatically on every initial load of a remembered site.

…rTest so the mocked listener returns false instead of a null Boolean

@landomen landomen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@0nko Thanks for moving this to new module. I like the new API but just to follow the process, I think we need an official API proposal for this 😅

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.

3 participants