diff --git a/build/patches/Add-a-flag-to-always-view-desktop-site-for-all-websites.patch b/build/patches/Add-a-flag-to-always-view-desktop-site-for-all-websites.patch index 5d78669d..5933a15f 100644 --- a/build/patches/Add-a-flag-to-always-view-desktop-site-for-all-websites.patch +++ b/build/patches/Add-a-flag-to-always-view-desktop-site-for-all-websites.patch @@ -1,157 +1,348 @@ From: uazo -Date: Sat, 24 Oct 2020 19:40:04 +0000 -Subject: Add a flag to always view the desktop site for all websites +Date: Mon, 26 Oct 2020 11:55:40 +0000 +Subject: Add flag to always view the desktop site for all websites --- - .../java/res/xml/homepage_preferences.xml | 5 +++++ - .../chrome/browser/WebContentsFactory.java | 18 ++++++++++++++++-- - .../homepage/settings/HomepageSettings.java | 16 ++++++++++++++++ - .../ChromeSiteSettingsClient.java | 14 ++++++++++++++ - .../preferences/ChromePreferenceKeys.java | 5 ++++- - .../java/res/xml/site_settings_preferences.xml | 4 ++++ - .../browser_ui/site_settings/SiteSettings.java | 14 ++++++++++++++ - .../site_settings/SiteSettingsClient.java | 3 +++ - .../strings/android/browser_ui_strings.grd | 4 ++++ - .../navigation_controller_android.cc | 7 +++++++ - .../frame_host/navigation_controller_android.h | 4 ++++ - .../frame_host/navigation_controller_impl.cc | 6 ++++++ - .../frame_host/navigation_controller_impl.h | 4 ++++ - .../framehost/NavigationControllerImpl.java | 11 +++++++++++ - .../browser/NavigationController.java | 2 ++ - 15 files changed, 114 insertions(+), 3 deletions(-) + chrome/android/chrome_java_resources.gni | 1 + + chrome/android/chrome_java_sources.gni | 1 + + .../android/java/res/xml/main_preferences.xml | 5 ++ + .../java/res/xml/useragent_preferences.xml | 30 ++++++++++ + .../chrome/browser/app/ChromeActivity.java | 15 ++++- + .../settings/UserAgentPreferences.java | 56 +++++++++++++++++++ + .../chromium/chrome/browser/tab/TabImpl.java | 47 +++++++++++++++- + .../browser/tabmodel/TabWindowManager.java | 20 +++++++ + chrome/browser/android/tab_android.cc | 5 +- + chrome/browser/android/tab_android.h | 3 +- + .../preferences/ChromePreferenceKeys.java | 5 +- + .../org/chromium/chrome/browser/tab/Tab.java | 2 + + .../strings/android_chrome_strings.grd | 14 +++++ + .../navigation_controller_android.cc | 6 +- + .../navigation_controller_android.h | 3 +- + .../framehost/NavigationControllerImpl.java | 6 +- + 16 files changed, 207 insertions(+), 12 deletions(-) + create mode 100644 chrome/android/java/res/xml/useragent_preferences.xml + create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/settings/UserAgentPreferences.java -diff --git a/chrome/android/java/res/xml/homepage_preferences.xml b/chrome/android/java/res/xml/homepage_preferences.xml ---- a/chrome/android/java/res/xml/homepage_preferences.xml -+++ b/chrome/android/java/res/xml/homepage_preferences.xml -@@ -12,6 +12,11 @@ - android:summaryOn="@string/text_on" - android:summaryOff="@string/text_off" /> - -+ -+ +diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni +--- a/chrome/android/chrome_java_resources.gni ++++ b/chrome/android/chrome_java_resources.gni +@@ -1130,4 +1130,5 @@ chrome_java_resources = [ + "java/res/xml/sync_and_services_preferences.xml", + "java/res/xml/theme_preferences.xml", + "java/res/xml/tracing_preferences.xml", ++ "java/res/xml/useragent_preferences.xml", + ] +diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni +--- a/chrome/android/chrome_java_sources.gni ++++ b/chrome/android/chrome_java_sources.gni +@@ -1309,6 +1309,7 @@ chrome_java_sources = [ + "java/src/org/chromium/chrome/browser/photo_picker/DecoderServiceHost.java", + "java/src/org/chromium/chrome/browser/settings/AdBlockEditor.java", + "java/src/org/chromium/chrome/browser/settings/AdBlockPreferences.java", ++ "java/src/org/chromium/chrome/browser/settings/UserAgentPreferences.java", + "java/src/org/chromium/chrome/browser/photo_picker/FileEnumWorkerTask.java", + "java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java", + "java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java", +diff --git a/chrome/android/java/res/xml/main_preferences.xml b/chrome/android/java/res/xml/main_preferences.xml +--- a/chrome/android/java/res/xml/main_preferences.xml ++++ b/chrome/android/java/res/xml/main_preferences.xml +@@ -104,6 +104,11 @@ + android:key="content_settings" + android:order="20" + android:title="@string/prefs_site_settings"/> ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java ++++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +@@ -202,6 +202,9 @@ import org.chromium.ui.modaldialog.ModalDialogManager; + import org.chromium.ui.widget.Toast; + import org.chromium.url.Origin; + import org.chromium.webapk.lib.client.WebApkNavigationClient; ++import org.chromium.chrome.browser.tabmodel.TabWindowManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; - import javax.inject.Inject; + import java.util.ArrayList; + import java.util.List; +@@ -1987,11 +1990,17 @@ public abstract class ChromeActivity + } else if (id == R.id.view_source_id) { + currentTab.getWebContents().getNavigationController().loadUrl(new LoadUrlParams("view-source:"+currentTab.getUrlString())); + } else if (id == R.id.request_desktop_site_id || id == R.id.request_desktop_site_check_id) { +- final boolean reloadOnChange = !currentTab.isNativePage(); + final boolean usingDesktopUserAgent = + currentTab.getWebContents().getNavigationController().getUseDesktopUserAgent(); +- currentTab.getWebContents().getNavigationController().setUseDesktopUserAgent( +- !usingDesktopUserAgent, reloadOnChange); ++ ++ final boolean alwaysDesktopModeEnabled = SharedPreferencesManager.getInstance().readBoolean( ++ ChromePreferenceKeys.USERAGENT_STICKY_DESKTOP_MODE, false); ++ if (alwaysDesktopModeEnabled) { ++ TabWindowManager.getInstance().SetOverrideUserAgentForAllTabs(!usingDesktopUserAgent); ++ } ++ else { ++ currentTab.SetOverrideUserAgent(!usingDesktopUserAgent); ++ } + RecordUserAction.record("MobileMenuRequestDesktopSite"); + } else if (id == R.id.reader_mode_prefs_id) { + DomDistillerUIUtils.openSettings(currentTab.getWebContents()); +diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/UserAgentPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/UserAgentPreferences.java +new file mode 100644 +--- /dev/null ++++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/UserAgentPreferences.java +@@ -0,0 +1,56 @@ ++/* ++ This file is part of Bromite. ++ ++ Bromite is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ ++ Bromite is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with Bromite. If not, see . ++*/ ++ ++package org.chromium.chrome.browser.settings; ++ ++import android.os.Bundle; ++import androidx.preference.Preference; ++import androidx.preference.PreferenceFragmentCompat; ++import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; ++ ++import org.chromium.components.browser_ui.settings.SettingsUtils; ++import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; ++import org.chromium.chrome.browser.preferences.SharedPreferencesManager; ++import org.chromium.chrome.browser.tabmodel.TabWindowManager; ++import org.chromium.chrome.R; ++ ++/** ++ * Fragment that allows the user to configure User Agent related preferences. ++ */ ++public class UserAgentPreferences extends PreferenceFragmentCompat { ++ private static final String PREF_STICK_DESKTOP_MODE_SWITCH = "desktop_mode_switch"; ++ ++ @Override ++ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { ++ getActivity().setTitle(R.string.useragent_settings_title); ++ SettingsUtils.addPreferencesFromResource(this, R.xml.useragent_preferences); ++ ++ ChromeSwitchPreference alwaysDesktopModeSwitch = ++ (ChromeSwitchPreference) findPreference(PREF_STICK_DESKTOP_MODE_SWITCH); ++ if (alwaysDesktopModeSwitch != null) { ++ boolean enabled = SharedPreferencesManager.getInstance().readBoolean( ++ ChromePreferenceKeys.USERAGENT_STICKY_DESKTOP_MODE, false); ++ alwaysDesktopModeSwitch.setChecked(enabled); ++ alwaysDesktopModeSwitch.setOnPreferenceChangeListener((preference, newValue) -> { ++ SharedPreferencesManager.getInstance().writeBoolean( ++ ChromePreferenceKeys.USERAGENT_STICKY_DESKTOP_MODE, (boolean) newValue); ++ TabWindowManager.getInstance().SetOverrideUserAgentForAllTabs((boolean) newValue); ++ return true; ++ }); ++ } ++ } ++} +diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java ++++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +@@ -57,6 +57,10 @@ import org.chromium.ui.base.WindowAndroid; + import org.chromium.ui.util.ColorUtils; + import org.chromium.url.GURL; + import org.chromium.url.Origin; ++import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; ++import org.chromium.chrome.browser.preferences.SharedPreferencesManager; ++import org.chromium.content_public.browser.navigation_controller.UserAgentOverrideOption; ++import org.chromium.content_public.browser.NavigationController; -@@ -44,14 +46,18 @@ public class WebContentsFactory { - */ - // TODO(https://crbug.com/1099138): Remove static for unit-testability. - public static WebContents createWebContents(Profile profile, boolean initiallyHidden) { -- return WebContentsFactoryJni.get().createWebContents(profile, initiallyHidden, false); -+ WebContents webContents = WebContentsFactoryJni.get().createWebContents(profile, initiallyHidden, false); -+ setUseDesktopUserAgent(webContents); -+ return webContents; + /** + * Implementation of the interface {@link Tab}. Contains and manages a {@link ContentView}. +@@ -446,6 +450,14 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer { + throw new RuntimeException("Tab.loadUrl called when no native side exists"); + } + ++ if (params.getUserAgentOverrideOption() == (int)UserAgentOverrideOption.INHERIT) { ++ final boolean alwaysDesktopModeEnabled = SharedPreferencesManager.getInstance().readBoolean( ++ ChromePreferenceKeys.USERAGENT_STICKY_DESKTOP_MODE, false); ++ if (alwaysDesktopModeEnabled) { ++ params.setOverrideUserAgent((int)UserAgentOverrideOption.TRUE); ++ } ++ } ++ + // We load the URL from the tab rather than directly from the ContentView so the tab has + // a chance of using a prerenderer page is any. + int loadType = TabImplJni.get().loadUrl(mNativeTabAndroid, TabImpl.this, +@@ -458,7 +470,8 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer { + params.getReferrer() != null ? params.getReferrer().getPolicy() : 0, + params.getIsRendererInitiated(), params.getShouldReplaceCurrentEntry(), + params.getHasUserGesture(), params.getShouldClearHistoryList(), +- params.getInputStartTimestamp(), params.getIntentReceivedTimestamp()); ++ params.getInputStartTimestamp(), params.getIntentReceivedTimestamp(), ++ params.getUserAgentOverrideOption()); + + for (TabObserver observer : mObservers) { + observer.onLoadUrl(this, params, loadType); +@@ -1380,6 +1393,10 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer { + if (mWebContents != null) mWebContents.getNavigationController().loadIfNecessary(); + mIsBeingRestored = true; + for (TabObserver observer : mObservers) observer.onRestoreStarted(this); ++ ++ if(overrideUserAgentWhenUnFrozen != UserAgentOverrideOption.INHERIT) { ++ SetOverrideUserAgent(overrideUserAgentWhenUnFrozen == (int)UserAgentOverrideOption.TRUE ? true : false); ++ } + } finally { + TraceEvent.end("Tab.restoreIfNeeded"); + } +@@ -1497,6 +1514,31 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer { + } } - // TODO(https://crbug.com/1033955): Remove after check discard error is fixed. - private static WebContents createWebContents( - Profile profile, boolean initiallyHidden, boolean initializeRenderer) { -- return WebContentsFactoryJni.get().createWebContents( -+ WebContents webContents = WebContentsFactoryJni.get().createWebContents( - profile, initiallyHidden, initializeRenderer); -+ setUseDesktopUserAgent(webContents); -+ return webContents; - } - - /** -@@ -67,6 +73,14 @@ public class WebContentsFactory { - return createWebContents(profile, initiallyHidden, true); - } - -+ private static void setUseDesktopUserAgent(WebContents webContents) { -+ boolean enabled = SharedPreferencesManager.getInstance().readBoolean( -+ ChromePreferenceKeys.NAVIGATION_ALWAYS_DESKTOP_MODE, false); -+ if (enabled) { -+ webContents.getNavigationController().setShouldOverrideUserAgentForNewEntry(true); ++ int overrideUserAgentWhenUnFrozen = (int)UserAgentOverrideOption.INHERIT; ++ ++ public void SetOverrideUserAgent(boolean usingDesktopUserAgent) { ++ overrideUserAgentWhenUnFrozen = UserAgentOverrideOption.INHERIT; ++ ++ WebContents webContents = this.getWebContents(); ++ if (webContents != null) { ++ NavigationController navigationController = webContents.getNavigationController(); ++ navigationController.setUseDesktopUserAgent( ++ usingDesktopUserAgent, !this.isNativePage()); ++ } ++ else if (this.getPendingLoadParams() != null) { ++ if (usingDesktopUserAgent) { ++ this.getPendingLoadParams().setOverrideUserAgent((int)UserAgentOverrideOption.TRUE); ++ } ++ else { ++ this.getPendingLoadParams().setOverrideUserAgent((int)UserAgentOverrideOption.FALSE); ++ } ++ } ++ else { ++ overrideUserAgentWhenUnFrozen = usingDesktopUserAgent ? UserAgentOverrideOption.TRUE : ++ UserAgentOverrideOption.FALSE; + } + } + @NativeMethods interface Natives { - WebContents createWebContents( -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageSettings.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageSettings.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageSettings.java -@@ -25,6 +25,8 @@ import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; - import org.chromium.components.browser_ui.settings.SettingsUtils; - import org.chromium.components.browser_ui.settings.TextMessagePreference; - import org.chromium.components.url_formatter.UrlFormatter; -+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; -+import org.chromium.chrome.browser.preferences.SharedPreferencesManager; - - /** - * Fragment that allows the user to configure homepage related preferences. -@@ -38,6 +40,7 @@ public class HomepageSettings extends PreferenceFragmentCompat { - public static final String PREF_HOMEPAGE_RADIO_GROUP = "homepage_radio_group"; - @VisibleForTesting - public static final String PREF_TEXT_MANAGED = "text_managed"; -+ public static final String PREF_ALWAYS_DESKTOP_MODE_SWITCH = "always_desktop_mode_switch"; - - /** - * Delegate used to mark that the homepage is being managed. -@@ -91,6 +94,19 @@ public class HomepageSettings extends PreferenceFragmentCompat { - }); + void init(TabImpl caller); +@@ -1517,7 +1559,8 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer { + String referrerUrl, int referrerPolicy, boolean isRendererInitiated, + boolean shoulReplaceCurrentEntry, boolean hasUserGesture, + boolean shouldClearHistoryList, long inputStartTimestamp, +- long intentReceivedTimestamp); ++ long intentReceivedTimestamp, ++ int userAgentOverrideOption); + void setActiveNavigationEntryTitleForUrl( + long nativeTabAndroid, TabImpl caller, String url, String title); + void loadOriginalImage(long nativeTabAndroid, TabImpl caller); +diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManager.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManager.java +--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManager.java ++++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManager.java +@@ -248,4 +248,24 @@ public class TabWindowManager implements ActivityStateListener { + AsyncTabParamsManager.getInstance(), true, true, false); } - -+ ChromeSwitchPreference alwaysDesktopModeSwitch = -+ (ChromeSwitchPreference) findPreference(PREF_ALWAYS_DESKTOP_MODE_SWITCH); -+ if (alwaysDesktopModeSwitch != null) { -+ boolean enabled = SharedPreferencesManager.getInstance().readBoolean( -+ ChromePreferenceKeys.NAVIGATION_ALWAYS_DESKTOP_MODE, false); -+ alwaysDesktopModeSwitch.setChecked(enabled); -+ alwaysDesktopModeSwitch.setOnPreferenceChangeListener((preference, newValue) -> { -+ SharedPreferencesManager.getInstance().writeBoolean( -+ ChromePreferenceKeys.NAVIGATION_ALWAYS_DESKTOP_MODE, (boolean) newValue); -+ return true; -+ }); -+ } -+ - RecordUserAction.record("Settings.Homepage.Opened"); - - // Update preference views and state. -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsClient.java b/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsClient.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsClient.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsClient.java -@@ -32,6 +32,8 @@ import org.chromium.components.embedder_support.browser_context.BrowserContextHa - import org.chromium.components.embedder_support.util.Origin; - import org.chromium.content_public.browser.ContentFeatureList; - import org.chromium.content_public.common.ContentSwitches; -+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; -+import org.chromium.chrome.browser.preferences.SharedPreferencesManager; - - /** - * A SiteSettingsClient instance that contains Chrome-specific Site Settings logic. -@@ -199,4 +201,16 @@ public class ChromeSiteSettingsClient implements SiteSettingsClient { - - return null; } + -+ @Override -+ public boolean IsAlwaysDesktopModeEnabled() { -+ return SharedPreferencesManager.getInstance().readBoolean( -+ ChromePreferenceKeys.NAVIGATION_ALWAYS_DESKTOP_MODE, false); -+ } ++ public static void SetOverrideUserAgentForAllTabs(boolean usingDesktopUserAgent) { ++ TabWindowManager tabWindowManagerSingleton = TabWindowManager.getInstance(); + -+ @Override -+ public void SetAlwaysDesktopModeEnabled(boolean enabled) { -+ SharedPreferencesManager.getInstance().writeBoolean( -+ ChromePreferenceKeys.NAVIGATION_ALWAYS_DESKTOP_MODE, enabled); ++ List mSelectors = tabWindowManagerSingleton.mSelectors; ++ for (int selectorIndex = 0; selectorIndex < mSelectors.size(); selectorIndex++) { ++ TabModelSelector selector = mSelectors.get(selectorIndex); ++ if (selector != null) { ++ List models = selector.getModels(); ++ for (int modelIndex = 0; modelIndex < models.size(); modelIndex++) { ++ TabModel model = models.get(modelIndex); ++ ++ for (int tabIdex = 0; tabIdex < model.getCount(); tabIdex++) { ++ Tab theTab = model.getTabAt(tabIdex); ++ theTab.SetOverrideUserAgent(usingDesktopUserAgent); ++ } ++ } ++ } ++ } + } } +diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc +--- a/chrome/browser/android/tab_android.cc ++++ b/chrome/browser/android/tab_android.cc +@@ -363,7 +363,8 @@ TabAndroid::TabLoadStatus TabAndroid::LoadUrl( + jboolean has_user_gesture, + jboolean should_clear_history_list, + jlong input_start_timestamp, +- jlong intent_received_timestamp) { ++ jlong intent_received_timestamp, ++ jint user_agent_override_option) { + if (!web_contents()) + return PAGE_LOAD_FAILED; + +@@ -420,6 +421,8 @@ TabAndroid::TabLoadStatus TabAndroid::LoadUrl( + load_params.input_start = + base::TimeTicks::FromUptimeMillis(intent_received_timestamp); + } ++ load_params.override_user_agent = static_cast( ++ user_agent_override_option); + web_contents()->GetController().LoadURLWithParams(load_params); + } + return DEFAULT_PAGE_LOAD; +diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h +--- a/chrome/browser/android/tab_android.h ++++ b/chrome/browser/android/tab_android.h +@@ -148,7 +148,8 @@ class TabAndroid { + jboolean has_user_gesture, + jboolean should_clear_history_list, + jlong omnibox_input_received_timestamp, +- jlong intent_received_timestamp); ++ jlong intent_received_timestamp, ++ jint user_agent_override_option); + void SetActiveNavigationEntryTitleForUrl( + JNIEnv* env, + const base::android::JavaParamRef& obj, diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java @@ -159,7 +350,7 @@ diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/bro public static final KeyPrefix KEY_ZERO_SUGGEST_HEADER_GROUP_COLLAPSED_BY_DEFAULT_PREFIX = new KeyPrefix("zero_suggest_header_group_collapsed_by_default*"); -+ public static final String NAVIGATION_ALWAYS_DESKTOP_MODE = "Chrome.Navigation.AlwaysDesktopMode"; ++ public static final String USERAGENT_STICKY_DESKTOP_MODE = "Chrome.UserAgent.StickyDesktopMode"; + /** * These values are currently used as SharedPreferences keys, along with the keys in @@ -170,192 +361,100 @@ diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/bro SETTINGS_SAFETY_CHECK_RUN_COUNTER, - TWA_DISCLOSURE_SEEN_PACKAGES + TWA_DISCLOSURE_SEEN_PACKAGES, -+ NAVIGATION_ALWAYS_DESKTOP_MODE ++ USERAGENT_STICKY_DESKTOP_MODE ); // clang-format on } -diff --git a/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml b/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml ---- a/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml -+++ b/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml -@@ -105,4 +105,8 @@ - -+ - -diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java ---- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java -+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java -@@ -15,6 +15,7 @@ import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory.Typ - import org.chromium.components.content_settings.ContentSettingValues; - import org.chromium.components.embedder_support.browser_context.BrowserContextHandle; - import org.chromium.components.user_prefs.UserPrefs; -+import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; - - /** - * The main Site Settings screen, which shows all the site settings categories: All sites, Location, -@@ -27,11 +28,24 @@ public class SiteSettings - // The keys for each category shown on the Site Settings page - // are defined in the SiteSettingsCategory. - -+ private static final String PREF_ALWAYS_DESKTOP_MODE_SWITCH = "always_desktop_mode_switch"; -+ - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - SettingsUtils.addPreferencesFromResource(this, R.xml.site_settings_preferences); - getActivity().setTitle(R.string.prefs_site_settings); - -+ ChromeSwitchPreference alwaysDesktopModeSwitch = -+ (ChromeSwitchPreference) findPreference(PREF_ALWAYS_DESKTOP_MODE_SWITCH); -+ if (alwaysDesktopModeSwitch != null) { -+ boolean enabled = getSiteSettingsClient().IsAlwaysDesktopModeEnabled(); -+ alwaysDesktopModeSwitch.setChecked(enabled); -+ alwaysDesktopModeSwitch.setOnPreferenceChangeListener((preference, newValue) -> { -+ getSiteSettingsClient().SetAlwaysDesktopModeEnabled((boolean)newValue); -+ return true; -+ }); -+ } -+ - configurePreferences(); - updatePreferenceStates(); - } -diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsClient.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsClient.java ---- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsClient.java -+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsClient.java -@@ -87,4 +87,7 @@ public interface SiteSettingsClient { +diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java +--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java ++++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java +@@ -265,4 +265,6 @@ public interface Tab extends TabLifecycle { + * @param isDirty Whether the Tab's state has changed. */ - @Nullable - String getDelegatePackageNameForOrigin(Origin origin, @ContentSettingsType int type); + void setIsTabStateDirty(boolean isTabStateDirty); + -+ boolean IsAlwaysDesktopModeEnabled(); -+ void SetAlwaysDesktopModeEnabled(boolean enabled); ++ void SetOverrideUserAgent(boolean usingDesktopUserAgent); } -diff --git a/components/browser_ui/strings/android/browser_ui_strings.grd b/components/browser_ui/strings/android/browser_ui_strings.grd ---- a/components/browser_ui/strings/android/browser_ui_strings.grd -+++ b/components/browser_ui/strings/android/browser_ui_strings.grd -@@ -353,6 +353,10 @@ - This page is dangerous. Site information +diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd +--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd ++++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd +@@ -228,6 +228,20 @@ CHAR-LIMIT guidelines: + Visit help page -+ -+ Always desktop view ++ ++ ++ User Agent ++ ++ ++ Customize User Agent ++ ++ ++ Sticky flag for desktop mode view hambuger flag (for all tabs) ++ ++ ++ Use hambuger flag for desktop view mode only for current tab + + - - - {COOKIE_COUNT, plural, + + + General diff --git a/content/browser/frame_host/navigation_controller_android.cc b/content/browser/frame_host/navigation_controller_android.cc --- a/content/browser/frame_host/navigation_controller_android.cc +++ b/content/browser/frame_host/navigation_controller_android.cc -@@ -351,6 +351,13 @@ bool NavigationControllerAndroid::GetUseDesktopUserAgent( - return entry && entry->GetIsOverridingUserAgent(); +@@ -235,7 +235,8 @@ void NavigationControllerAndroid::LoadUrl( + const JavaParamRef& data_url_as_string, + jboolean can_load_local_resources, + jboolean is_renderer_initiated, +- jboolean should_replace_current_entry) { ++ jboolean should_replace_current_entry, ++ jint user_agent_override_option) { + DCHECK(url); + NavigationController::LoadURLParams params( + GURL(ConvertJavaStringToUTF8(env, url))); +@@ -289,6 +290,9 @@ void NavigationControllerAndroid::LoadUrl( + Referrer::ConvertToPolicy(referrer_policy)); + } + ++ params.override_user_agent = static_cast( ++ user_agent_override_option); ++ + navigation_controller_->LoadURLWithParams(params); } -+void NavigationControllerAndroid::ShouldOverrideUserAgentForNewEntry( -+ JNIEnv* env, -+ const JavaParamRef& obj, -+ jboolean enabled) { -+ navigation_controller_->ShouldOverrideUserAgentForNewEntry(enabled); -+} -+ - void NavigationControllerAndroid::SetUseDesktopUserAgent( - JNIEnv* env, - const JavaParamRef& obj, diff --git a/content/browser/frame_host/navigation_controller_android.h b/content/browser/frame_host/navigation_controller_android.h --- a/content/browser/frame_host/navigation_controller_android.h +++ b/content/browser/frame_host/navigation_controller_android.h -@@ -135,6 +135,10 @@ class CONTENT_EXPORT NavigationControllerAndroid { +@@ -80,7 +80,8 @@ class CONTENT_EXPORT NavigationControllerAndroid { + const base::android::JavaParamRef& data_url_as_string, + jboolean can_load_local_resources, + jboolean is_renderer_initiated, +- jboolean should_replace_current_entry); ++ jboolean should_replace_current_entry, ++ jint user_agent_override_option); + void ClearSslPreferences( JNIEnv* env, - const base::android::JavaParamRef& obj, - jint index); -+ void ShouldOverrideUserAgentForNewEntry( -+ JNIEnv* env, -+ const base::android::JavaParamRef& obj, -+ jboolean enabled); - - private: - NavigationControllerImpl* navigation_controller_; -diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc ---- a/content/browser/frame_host/navigation_controller_impl.cc -+++ b/content/browser/frame_host/navigation_controller_impl.cc -@@ -2989,6 +2989,8 @@ void NavigationControllerImpl::NavigateWithoutEntry( - // CreateNavigationRequestFromLoadURLParams. - bool override_user_agent = ShouldOverrideUserAgent(params.override_user_agent, - GetLastCommittedEntry()); -+ if (should_override_useragent_for_new_entry_ == true) -+ override_user_agent = true; - - // Don't allow an entry replacement if there is no entry to replace. - // http://crbug.com/457149 -@@ -3758,4 +3760,8 @@ void NavigationControllerImpl::PendingEntryRefDeleted(PendingEntryRef* ref) { - delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); - } - -+void NavigationControllerImpl::ShouldOverrideUserAgentForNewEntry(bool enabled) { -+ should_override_useragent_for_new_entry_ = enabled; -+} -+ - } // namespace content -diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h ---- a/content/browser/frame_host/navigation_controller_impl.h -+++ b/content/browser/frame_host/navigation_controller_impl.h -@@ -333,6 +333,8 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController { - scoped_refptr blob_url_loader_factory, - bool should_replace_entry); - -+ void ShouldOverrideUserAgentForNewEntry(bool enabled); -+ - private: - friend class RestoreHelper; - -@@ -701,6 +703,8 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController { - // go back into place after any subsequent commit. - std::unique_ptr entry_replaced_by_post_commit_error_; - -+ bool should_override_useragent_for_new_entry_ = false; -+ - // NOTE: This must be the last member. - base::WeakPtrFactory weak_factory_{this}; - + const base::android::JavaParamRef& /* obj */); diff --git a/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java --- a/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java -@@ -224,6 +224,15 @@ import org.chromium.content_public.common.ResourceRequestBody; +@@ -168,7 +168,8 @@ import org.chromium.content_public.common.ResourceRequestBody; + params.getUserAgentOverrideOption(), params.getExtraHeadersString(), + params.getPostData(), params.getBaseUrl(), params.getVirtualUrlForDataUrl(), + params.getDataUrlAsString(), params.getCanLoadLocalResources(), +- params.getIsRendererInitiated(), params.getShouldReplaceCurrentEntry()); ++ params.getIsRendererInitiated(), params.getShouldReplaceCurrentEntry(), ++ params.getUserAgentOverrideOption()); } } -+ @Override -+ public void setShouldOverrideUserAgentForNewEntry(boolean enabled) { -+ if (mNativeNavigationControllerAndroid != 0) { -+ NavigationControllerImplJni.get().ShouldOverrideUserAgentForNewEntry( -+ mNativeNavigationControllerAndroid, NavigationControllerImpl.this, -+ enabled); -+ } -+ } -+ - @Override - public NavigationEntry getEntryAtIndex(int index) { - if (mNativeNavigationControllerAndroid != 0) { -@@ -378,5 +387,7 @@ import org.chromium.content_public.common.ResourceRequestBody; - NavigationControllerImpl caller, int index, String key, String value); - boolean isEntryMarkedToBeSkipped( - long nativeNavigationControllerAndroid, NavigationControllerImpl caller, int index); -+ void ShouldOverrideUserAgentForNewEntry(long nativeNavigationControllerAndroid, -+ NavigationControllerImpl caller, boolean enabled); - } - } -diff --git a/content/public/android/java/src/org/chromium/content_public/browser/NavigationController.java b/content/public/android/java/src/org/chromium/content_public/browser/NavigationController.java ---- a/content/public/android/java/src/org/chromium/content_public/browser/NavigationController.java -+++ b/content/public/android/java/src/org/chromium/content_public/browser/NavigationController.java -@@ -138,6 +138,8 @@ public interface NavigationController { - */ - public void setUseDesktopUserAgent(boolean override, boolean reloadOnChange); - -+ public void setShouldOverrideUserAgentForNewEntry(boolean enabled); -+ - /** - * Return the NavigationEntry at the given index. - * @param index Index to retrieve the NavigationEntry for. +@@ -347,7 +348,8 @@ import org.chromium.content_public.common.ResourceRequestBody; + int referrerPolicy, int uaOverrideOption, String extraHeaders, + ResourceRequestBody postData, String baseUrlForDataUrl, String virtualUrlForDataUrl, + String dataUrlAsString, boolean canLoadLocalResources, boolean isRendererInitiated, +- boolean shouldReplaceCurrentEntry); ++ boolean shouldReplaceCurrentEntry, ++ int userAgentOverrideOption); + void clearHistory(long nativeNavigationControllerAndroid, NavigationControllerImpl caller); + int getNavigationHistory(long nativeNavigationControllerAndroid, + NavigationControllerImpl caller, Object history);