Allow custom user agent

This commit is contained in:
Carmelo Messina 2020-11-13 13:19:42 +01:00
parent 578556604a
commit 204fafbf4a

View file

@ -3,34 +3,70 @@ Date: Mon, 26 Oct 2020 16:50:15 +0000
Subject: Add flag to always view the desktop site for all websites
---
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 | 17 ++++-
.../settings/UserAgentPreferences.java | 60 +++++++++++++++
.../chromium/chrome/browser/tab/TabImpl.java | 75 ++++++++++++++++++-
.../browser/tabmodel/TabWindowManager.java | 20 +++++
chrome/browser/android/tab_android.cc | 5 +-
chrome/browser/android/tab_android.h | 3 +-
.../preferences/ChromePreferenceKeys.java | 7 +-
.../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, 243 insertions(+), 12 deletions(-)
base/base_switches.cc | 2 +
base/base_switches.h | 2 +
chrome/android/chrome_java_resources.gni | 2 +
chrome/android/chrome_java_sources.gni | 1 +
.../layout/custom_useragent_preferences.xml | 108 ++++++++++
.../android/java/res/xml/main_preferences.xml | 5 +
.../java/res/xml/useragent_preferences.xml | 31 +++
.../chrome/browser/app/ChromeActivity.java | 17 +-
.../settings/PrivacyPreferencesManager.java | 30 +++
.../settings/UserAgentPreferences.java | 186 ++++++++++++++++++
.../chromium/chrome/browser/tab/TabImpl.java | 77 +++++++-
.../browser/tabmodel/TabWindowManager.java | 23 +++
.../browser/android/content/content_utils.cc | 64 ++++--
.../preferences/browser_prefs_android.cc | 7 +
.../privacy_preferences_manager.cc | 93 +++++++++
chrome/browser/android/tab_android.cc | 5 +-
chrome/browser/android/tab_android.h | 3 +-
.../preferences/ChromePreferenceKeys.java | 7 +-
.../org/chromium/chrome/browser/tab/Tab.java | 2 +
.../strings/android_chrome_strings.grd | 35 ++++
chrome/common/pref_names.cc | 13 ++
chrome/common/pref_names.h | 8 +
.../android/browser_startup_controller.cc | 35 ++++
.../navigation_controller_android.cc | 6 +-
.../navigation_controller_android.h | 3 +-
.../renderer_host/render_process_host_impl.cc | 1 +
.../browser/web_contents/web_contents_impl.cc | 4 +-
.../framehost/NavigationControllerImpl.java | 6 +-
28 files changed, 746 insertions(+), 30 deletions(-)
create mode 100644 chrome/android/java/res/layout/custom_useragent_preferences.xml
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/base/base_switches.cc b/base/base_switches.cc
--- a/base/base_switches.cc
+++ b/base/base_switches.cc
@@ -160,4 +160,6 @@ const char kForceFieldTrialParams[] = "force-fieldtrial-params";
const char kEnableThreadInstructionCount[] = "enable-thread-instruction-count";
#endif
+const char kDesktopModeViewportMetaEnabled[] = "dm-viewport-meta-enabled";
+
} // namespace switches
diff --git a/base/base_switches.h b/base/base_switches.h
--- a/base/base_switches.h
+++ b/base/base_switches.h
@@ -59,6 +59,8 @@ extern const char kForceFieldTrialParams[];
extern const char kEnableThreadInstructionCount[];
#endif
+extern const char kDesktopModeViewportMetaEnabled[];
+
} // namespace switches
#endif // BASE_BASE_SWITCHES_H_
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 = [
@@ -1130,4 +1130,6 @@ 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",
+ "java/res/layout/custom_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
@ -43,6 +79,119 @@ diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_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/layout/custom_useragent_preferences.xml b/chrome/android/java/res/layout/custom_useragent_preferences.xml
new file mode 100644
--- /dev/null
+++ b/chrome/android/java/res/layout/custom_useragent_preferences.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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 <https://www.gnu.org/licenses/>.
+-->
+
+<!-- Layout used by the UserAgentPreferences. -->
+
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_weight="0"
+ android:gravity="top"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:focusable="false"
+ android:orientation="vertical"
+ android:divider="?android:dividerHorizontal">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/TextAppearance.AccessibilityTextPreference"
+ android:background="@color/default_bg_color_secondary"
+ android:padding="16dp"
+ android:text="@string/custom_ua_text"/>
+
+ <org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout
+ android:id="@+id/ua_radio_button_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+ android:id="@+id/default_ua_switch"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ app:primaryText="@string/custom_ua_flag_off" />
+
+ <org.chromium.components.browser_ui.widget.RadioButtonWithEditText
+ android:id="@+id/custom_ua_switch"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:inputType="text"
+ android:hint="@string/custom_ua_placeholder"
+ app:descriptionText="@string/custom_ua_flag_on" />
+
+ </org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/TextAppearance.AccessibilityTextPreference"
+ android:background="@color/default_bg_color_secondary"
+ android:padding="16dp"
+ android:text="@string/custom_desktop_ua_text"/>
+
+ <org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout
+ android:id="@+id/ua_radio_button_layout_dm"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+ android:id="@+id/default_ua_switch_dm"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ app:primaryText="@string/custom_ua_flag_off" />
+
+ <org.chromium.components.browser_ui.widget.RadioButtonWithEditText
+ android:id="@+id/custom_ua_switch_dm"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:inputType="text"
+ android:hint="@string/custom_ua_placeholder"
+ app:descriptionText="@string/custom_ua_flag_on" />
+
+ </org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout>
+
+ <CheckBox
+ android:id="@+id/desktop_mode_viewportmeta"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_marginLeft="?android:attr/listPreferredItemPaddingStart"
+ android:text="@string/desktop_mode_viewportmeta_checkbox" />
+
+ </LinearLayout>
+
+</ScrollView>
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
@ -62,7 +211,7 @@ diff --git a/chrome/android/java/res/xml/useragent_preferences.xml b/chrome/andr
new file mode 100644
--- /dev/null
+++ b/chrome/android/java/res/xml/useragent_preferences.xml
@@ -0,0 +1,30 @@
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ This file is part of Bromite.
@ -89,6 +238,7 @@ new file mode 100644
+
+ <org.chromium.components.browser_ui.settings.ChromeSwitchPreference
+ android:key="desktop_mode_switch"
+ android:title="@string/option_desktop_flag"
+ android:summaryOn="@string/option_desktop_flag_on"
+ android:summaryOff="@string/option_desktop_flag_off" />
+
@ -129,11 +279,57 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActiv
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/privacy/settings/PrivacyPreferencesManager.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManager.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManager.java
@@ -315,6 +315,30 @@ public class PrivacyPreferencesManager implements CrashReportingPermissionManage
return PrivacyPreferencesManagerJni.get().isMetricsReportingManaged();
}
+ public boolean isOverrideUserAgentEnabled(boolean desktopMode) {
+ return PrivacyPreferencesManagerJni.get().isOverrideUserAgentEnabled(desktopMode);
+ }
+
+ public void setOverrideUserAgentEnabled(boolean enabled, boolean desktopMode) {
+ PrivacyPreferencesManagerJni.get().setOverrideUserAgentEnabled(enabled, desktopMode);
+ }
+
+ public String getOverrideUserAgentValue(boolean desktopMode) {
+ return PrivacyPreferencesManagerJni.get().getOverrideUserAgentValue(desktopMode);
+ }
+
+ public void setOverrideUserAgentValue(String user_agent, boolean desktopMode) {
+ PrivacyPreferencesManagerJni.get().setOverrideUserAgentValue(user_agent, desktopMode);
+ }
+
+ public boolean isDesktopModeViewportMetaEnabled() {
+ return PrivacyPreferencesManagerJni.get().isDesktopModeViewportMetaEnabled();
+ }
+
+ public void setDesktopModeViewportMetaEnabled(boolean enabled) {
+ PrivacyPreferencesManagerJni.get().setDesktopModeViewportMetaEnabled(enabled);
+ }
+
@NativeMethods
public interface Natives {
boolean canPrefetchAndPrerender();
@@ -325,5 +349,11 @@ public class PrivacyPreferencesManager implements CrashReportingPermissionManage
boolean isMetricsReportingEnabled();
void setMetricsReportingEnabled(boolean enabled);
boolean isMetricsReportingManaged();
+ boolean isOverrideUserAgentEnabled(boolean desktopMode);
+ void setOverrideUserAgentEnabled(boolean enabled, boolean desktopMode);
+ String getOverrideUserAgentValue(boolean desktopMode);
+ void setOverrideUserAgentValue(String timezone, boolean desktopMode);
+ boolean isDesktopModeViewportMetaEnabled();
+ void setDesktopModeViewportMetaEnabled(boolean enabled);
}
}
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,60 @@
@@ -0,0 +1,186 @@
+/*
+ This file is part of Bromite.
+
@ -156,19 +352,47 @@ new file mode 100644
+import android.os.Bundle;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
+import androidx.preference.PreferenceViewHolder;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.widget.RadioGroup;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import androidx.recyclerview.widget.RecyclerView;
+
+import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+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.browser.privacy.settings.PrivacyPreferencesManager;
+import org.chromium.chrome.R;
+
+/**
+ * Fragment that allows the user to configure User Agent related preferences.
+ */
+public class UserAgentPreferences extends PreferenceFragmentCompat {
+public class UserAgentPreferences
+ extends PreferenceFragmentCompat implements RadioGroup.OnCheckedChangeListener {
+
+ private static final String PREF_STICK_DESKTOP_MODE_SWITCH = "desktop_mode_switch";
+ private RadioButtonWithDescription useDefaultAgentSwitch;
+ private RadioButtonWithEditText useCustomAgentSwitch;
+ private RadioButtonWithDescription useDefaultAgentSwitchDesktopMode;
+ private RadioButtonWithEditText useCustomAgentSwitchDesktopMode;
+ private RadioGroup mRadioGroup;
+ private RadioGroup mRadioGroupDesktopMode;
+ private CheckBox mDesktopModeViewportmeta;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
@ -188,11 +412,109 @@ new file mode 100644
+ });
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ LinearLayout viewGroup = (LinearLayout) super.onCreateView(inflater, container, savedInstanceState);
+ ScrollView view = (ScrollView) inflater.inflate(R.layout.custom_useragent_preferences, viewGroup, false);
+ viewGroup.addView(view);
+
+ boolean enabledCustomUA = PrivacyPreferencesManager.getInstance().isOverrideUserAgentEnabled(false);
+ boolean enabledCustomUADesktopMode = PrivacyPreferencesManager.getInstance().isOverrideUserAgentEnabled(true);
+ boolean enabledDesktopModeViewportmeta = PrivacyPreferencesManager.getInstance().isDesktopModeViewportMetaEnabled();
+
+ useDefaultAgentSwitch =
+ (RadioButtonWithDescription) view.findViewById(R.id.default_ua_switch);
+ useCustomAgentSwitch =
+ (RadioButtonWithEditText) view.findViewById(R.id.custom_ua_switch);
+ useDefaultAgentSwitchDesktopMode =
+ (RadioButtonWithDescription) view.findViewById(R.id.default_ua_switch_dm);
+ useCustomAgentSwitchDesktopMode =
+ (RadioButtonWithEditText) view.findViewById(R.id.custom_ua_switch_dm);
+
+ mRadioGroup = (RadioGroup) view.findViewById(R.id.ua_radio_button_layout);
+ mRadioGroup.setOnCheckedChangeListener(this);
+
+ mRadioGroupDesktopMode = (RadioGroup) view.findViewById(R.id.ua_radio_button_layout_dm);
+ mRadioGroupDesktopMode.setOnCheckedChangeListener(this);
+
+ mDesktopModeViewportmeta = (CheckBox) view.findViewById(R.id.desktop_mode_viewportmeta);
+ mDesktopModeViewportmeta.setChecked(enabledDesktopModeViewportmeta);
+ mDesktopModeViewportmeta.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ PrivacyPreferencesManager.getInstance().setDesktopModeViewportMetaEnabled(
+ mDesktopModeViewportmeta.isChecked());
+ }
+ });
+
+ useDefaultAgentSwitch.setChecked(!enabledCustomUA);
+ useCustomAgentSwitch.setChecked(enabledCustomUA);
+
+ useDefaultAgentSwitchDesktopMode.setChecked(!enabledCustomUADesktopMode);
+ useCustomAgentSwitchDesktopMode.setChecked(enabledCustomUADesktopMode);
+
+ useCustomAgentSwitch.setPrimaryText(
+ PrivacyPreferencesManager.getInstance().getOverrideUserAgentValue(false));
+ useCustomAgentSwitch.addTextChangeListener(new RadioButtonWithEditText.OnTextChangeListener() {
+ @Override
+ public void onTextChanged(CharSequence newText) {
+ PrivacyPreferencesManager.getInstance().setOverrideUserAgentValue(
+ newText.toString(), false);
+ }
+ });
+
+ useCustomAgentSwitchDesktopMode.setPrimaryText(
+ PrivacyPreferencesManager.getInstance().getOverrideUserAgentValue(true));
+ useCustomAgentSwitchDesktopMode.addTextChangeListener(new RadioButtonWithEditText.OnTextChangeListener() {
+ @Override
+ public void onTextChanged(CharSequence newText) {
+ PrivacyPreferencesManager.getInstance().setOverrideUserAgentValue(
+ newText.toString(), true);
+ }
+ });
+
+ return viewGroup;
+ }
+
+ // @Override
+ // public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
+ // super.onViewCreated(view, savedInstanceState);
+
+ // final RecyclerView rv = getListView();
+ // rv.setPadding(0, 0, 0, 156); // (left, top, right, bottom)
+ // }
+
+ private void UpdateAllTabs() {
+ final boolean alwaysDesktopModeEnabled = SharedPreferencesManager.getInstance().readBoolean(
+ ChromePreferenceKeys.USERAGENT_ALWAYS_DESKTOP_MODE, false);
+ TabWindowManager.getInstance().SetOverrideUserAgentForAllTabs(alwaysDesktopModeEnabled);
+ }
+
+ @Override
+ public void onCheckedChanged(RadioGroup group, int checkedId) {
+ if (useDefaultAgentSwitch.isChecked()) {
+ PrivacyPreferencesManager.getInstance().setOverrideUserAgentEnabled(false, false);
+ }
+ else if (useCustomAgentSwitch.isChecked()) {
+ PrivacyPreferencesManager.getInstance().setOverrideUserAgentEnabled(true, false);
+ }
+
+ if (useDefaultAgentSwitchDesktopMode.isChecked()) {
+ PrivacyPreferencesManager.getInstance().setOverrideUserAgentEnabled(false, true);
+ }
+ else if (useCustomAgentSwitchDesktopMode.isChecked()) {
+ PrivacyPreferencesManager.getInstance().setOverrideUserAgentEnabled(true, true);
+ }
+
+ UpdateAllTabs();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ UpdateAllTabs();
+ }
+}
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
@ -263,7 +585,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.jav
} finally {
TraceEvent.end("Tab.restoreIfNeeded");
}
@@ -1497,6 +1533,40 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
@@ -1497,6 +1533,42 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
}
}
@ -283,6 +605,8 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.jav
+ }
+
+ if (webContents != null) {
+ ContentUtils.setUserAgentOverride(webContents);
+
+ NavigationController navigationController = webContents.getNavigationController();
+ navigationController.setUseDesktopUserAgent(
+ usingDesktopUserAgent, !this.isNativePage());
@ -304,7 +628,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.jav
@NativeMethods
interface Natives {
void init(TabImpl caller);
@@ -1517,7 +1587,8 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
@@ -1517,7 +1589,8 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
String referrerUrl, int referrerPolicy, boolean isRendererInitiated,
boolean shoulReplaceCurrentEntry, boolean hasUserGesture,
boolean shouldClearHistoryList, long inputStartTimestamp,
@ -317,7 +641,17 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.jav
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 {
@@ -27,6 +27,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
+
/**
* Manages multiple {@link TabModelSelector} instances, each owned by different {@link Activity}s.
*/
@@ -248,4 +251,24 @@ public class TabWindowManager implements ActivityStateListener {
AsyncTabParamsManager.getInstance(), true, true, false);
}
}
@ -342,6 +676,214 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabWin
+ }
+ }
}
diff --git a/chrome/browser/android/content/content_utils.cc b/chrome/browser/android/content/content_utils.cc
--- a/chrome/browser/android/content/content_utils.cc
+++ b/chrome/browser/android/content/content_utils.cc
@@ -9,6 +9,20 @@
#include "content/public/browser/web_contents.h"
#include "content/public/common/user_agent.h"
+#include "base/android/jni_android.h"
+#include "base/android/scoped_java_ref.h"
+#include "chrome/browser/browser_process.h"
+#include "components/prefs/pref_service.h"
+#include "chrome/common/pref_names.h"
+
+using base::android::ConvertJavaStringToUTF8;
+using base::android::ConvertUTF16ToJavaString;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::JavaParamRef;
+using base::android::JavaRef;
+using base::android::ScopedJavaGlobalRef;
+using base::android::ScopedJavaLocalRef;
+
static base::android::ScopedJavaLocalRef<jstring>
JNI_ContentUtils_GetBrowserUserAgent(JNIEnv* env) {
return base::android::ConvertUTF8ToJavaString(env, GetUserAgent());
@@ -17,21 +31,37 @@ JNI_ContentUtils_GetBrowserUserAgent(JNIEnv* env) {
static void JNI_ContentUtils_SetUserAgentOverride(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& jweb_contents) {
- const char kLinuxInfoStr[] = "X11; Linux x86_64";
- std::string product = version_info::GetProductNameAndVersionForUserAgent();
-
- blink::UserAgentOverride spoofed_ua;
- spoofed_ua.ua_string_override =
- content::BuildUserAgentFromOSAndProduct(kLinuxInfoStr, product);
- spoofed_ua.ua_metadata_override = ::GetUserAgentMetadata();
- spoofed_ua.ua_metadata_override->platform = "Linux";
- spoofed_ua.ua_metadata_override->platform_version =
- std::string(); // match content::GetOSVersion(false) on Linux
- spoofed_ua.ua_metadata_override->architecture = "x86";
- spoofed_ua.ua_metadata_override->model = std::string();
- spoofed_ua.ua_metadata_override->mobile = false;
-
- content::WebContents* web_contents =
- content::WebContents::FromJavaWebContents(jweb_contents);
- web_contents->SetUserAgentOverride(spoofed_ua, false);
+
+ bool enabled =
+ g_browser_process->local_state()->GetBoolean(prefs::kOverrideUserAgentDesktopModeEnabled);
+
+ if (enabled == false) {
+ const char kLinuxInfoStr[] = "X11; Linux x86_64";
+ std::string product = version_info::GetProductNameAndVersionForUserAgent();
+
+ blink::UserAgentOverride spoofed_ua;
+ spoofed_ua.ua_string_override =
+ content::BuildUserAgentFromOSAndProduct(kLinuxInfoStr, product);
+ spoofed_ua.ua_metadata_override = ::GetUserAgentMetadata();
+ spoofed_ua.ua_metadata_override->platform = "Linux";
+ spoofed_ua.ua_metadata_override->platform_version =
+ std::string(); // match content::GetOSVersion(false) on Linux
+ spoofed_ua.ua_metadata_override->architecture = "x86";
+ spoofed_ua.ua_metadata_override->model = std::string();
+ spoofed_ua.ua_metadata_override->mobile = false;
+
+ content::WebContents* web_contents =
+ content::WebContents::FromJavaWebContents(jweb_contents);
+ web_contents->SetUserAgentOverride(spoofed_ua, false);
+ }
+ else
+ {
+ std::string ua = g_browser_process->local_state()->GetString(prefs::kOverrideUserAgentDesktopMode);
+ blink::UserAgentOverride spoofed_ua;
+ spoofed_ua.ua_string_override = ua;
+
+ content::WebContents* web_contents =
+ content::WebContents::FromJavaWebContents(jweb_contents);
+ web_contents->SetUserAgentOverride(spoofed_ua, false);
+ }
}
diff --git a/chrome/browser/android/preferences/browser_prefs_android.cc b/chrome/browser/android/preferences/browser_prefs_android.cc
--- a/chrome/browser/android/preferences/browser_prefs_android.cc
+++ b/chrome/browser/android/preferences/browser_prefs_android.cc
@@ -10,11 +10,18 @@
#include "chrome/browser/notifications/notification_platform_bridge_android.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_registry_simple.h"
+#include "chrome/common/pref_names.h"
namespace android {
void RegisterPrefs(PrefRegistrySimple* registry) {
RegisterClipboardAndroidPrefs(registry);
+
+ registry->RegisterBooleanPref(prefs::kOverrideUserAgentEnabled, false);
+ registry->RegisterStringPref(prefs::kOverrideUserAgent, "");
+ registry->RegisterBooleanPref(prefs::kOverrideUserAgentDesktopModeEnabled, false);
+ registry->RegisterStringPref(prefs::kOverrideUserAgentDesktopMode, "");
+ registry->RegisterBooleanPref(prefs::kDesktopModeViewportMetaEnabled, false);
}
void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
diff --git a/chrome/browser/android/preferences/privacy_preferences_manager.cc b/chrome/browser/android/preferences/privacy_preferences_manager.cc
--- a/chrome/browser/android/preferences/privacy_preferences_manager.cc
+++ b/chrome/browser/android/preferences/privacy_preferences_manager.cc
@@ -11,6 +11,22 @@
#include "chrome/common/pref_names.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/prefs/pref_service.h"
+#include "base/command_line.h"
+#include "base/base_switches.h"
+#include "chrome/common/chrome_switches.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+
+using base::android::ConvertJavaStringToUTF8;
+using base::android::ConvertUTF16ToJavaString;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::JavaParamRef;
+using base::android::JavaRef;
+using base::android::ScopedJavaGlobalRef;
+using base::android::ScopedJavaLocalRef;
namespace {
@@ -74,3 +90,80 @@ JNI_PrivacyPreferencesManager_ObsoleteNetworkPredictionOptionsHasUserSetting(
return GetPrefService()->GetUserPrefValue(prefs::kNetworkPredictionOptions) !=
nullptr;
}
+
+static void UpdateCommandLine() {
+ bool overrideUserAgentEnabled =
+ g_browser_process->local_state()->GetBoolean(prefs::kOverrideUserAgentEnabled);
+ std::string ua = g_browser_process->local_state()->GetString(prefs::kOverrideUserAgent);
+
+ base::CommandLine* parsed_command_line =
+ base::CommandLine::ForCurrentProcess();
+ parsed_command_line->RemoveSwitch(switches::kUserAgent);
+ if (overrideUserAgentEnabled) {
+ parsed_command_line->AppendSwitchASCII(switches::kUserAgent, ua);
+ }
+
+ parsed_command_line->RemoveSwitch(switches::kDesktopModeViewportMetaEnabled);
+ if (g_browser_process->local_state()->GetBoolean(prefs::kDesktopModeViewportMetaEnabled))
+ parsed_command_line->AppendSwitch(switches::kDesktopModeViewportMetaEnabled);
+}
+
+static jboolean JNI_PrivacyPreferencesManager_IsOverrideUserAgentEnabled(
+ JNIEnv* env, jboolean desktopMode) {
+ if (desktopMode == false)
+ return g_browser_process->local_state()->GetBoolean(prefs::kOverrideUserAgentEnabled);
+ else
+ return g_browser_process->local_state()->GetBoolean(prefs::kOverrideUserAgentDesktopModeEnabled);
+}
+
+static void JNI_PrivacyPreferencesManager_SetOverrideUserAgentEnabled(
+ JNIEnv* env,
+ jboolean enabled, jboolean desktopMode) {
+ if (desktopMode == false) {
+ g_browser_process->local_state()->SetBoolean(prefs::kOverrideUserAgentEnabled,
+ enabled);
+ UpdateCommandLine();
+ } else {
+ g_browser_process->local_state()->SetBoolean(prefs::kOverrideUserAgentDesktopModeEnabled,
+ enabled);
+ }
+}
+
+static void JNI_PrivacyPreferencesManager_SetOverrideUserAgentValue(
+ JNIEnv* env,
+ const JavaParamRef<jstring>& ua, jboolean desktopMode) {
+ std::string new_ua = ConvertJavaStringToUTF8(env, ua);
+ if (desktopMode == false) {
+ g_browser_process->local_state()->SetString(prefs::kOverrideUserAgent,
+ new_ua);
+ UpdateCommandLine();
+ } else {
+ g_browser_process->local_state()->SetString(prefs::kOverrideUserAgentDesktopMode,
+ new_ua);
+ }
+}
+
+static base::android::ScopedJavaLocalRef<jstring>
+ JNI_PrivacyPreferencesManager_GetOverrideUserAgentValue(
+ JNIEnv* env, jboolean desktopMode) {
+ if (desktopMode == false) {
+ std::string ua = g_browser_process->local_state()->GetString(prefs::kOverrideUserAgent);
+ return ConvertUTF8ToJavaString(env, ua);
+ } else {
+ std::string ua = g_browser_process->local_state()->GetString(prefs::kOverrideUserAgentDesktopMode);
+ return ConvertUTF8ToJavaString(env, ua);
+ }
+}
+
+static jboolean JNI_PrivacyPreferencesManager_IsDesktopModeViewportMetaEnabled(
+ JNIEnv* env) {
+ return g_browser_process->local_state()->GetBoolean(prefs::kDesktopModeViewportMetaEnabled);
+}
+
+static void JNI_PrivacyPreferencesManager_SetDesktopModeViewportMetaEnabled(
+ JNIEnv* env,
+ jboolean enabled) {
+ g_browser_process->local_state()->SetBoolean(prefs::kDesktopModeViewportMetaEnabled,
+ enabled);
+ UpdateCommandLine();
+}
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
@ -414,7 +956,7 @@ diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.jav
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:
@@ -228,6 +228,41 @@ CHAR-LIMIT guidelines:
Visit help page
</message>
@ -425,16 +967,126 @@ diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chro
+ <message name="IDS_USERAGENT_SETTINGS_TITLE" desc="Title of the User Agent screen. [CHAR-LIMIT=32]">
+ Customize User Agent
+ </message>
+ <message name="IDS_OPTION_DESKTOP_FLAG_ON" desc="The label of the option that allows users to sticky desktop mode view flag under hambuger menu.">
+ Desktop mode toggle in hamburger menu applies to all tabs
+ <message name="IDS_OPTION_DESKTOP_FLAG" desc="The label of the option that allows users to sticky desktop mode view flag under hambuger menu.">
+ Current behaviour for desktop mode toggle in hamburger menu
+ </message>
+ <message name="IDS_OPTION_DESKTOP_FLAG_OFF" desc="The label of the option that revert the hambuger menu flag to actual behaviour.">
+ Desktop mode toggle in hamburger menu applies to current tab only
+ <message name="IDS_OPTION_DESKTOP_FLAG_ON" desc="The label of the option that allows users to sticky desktop mode view flag under hambuger menu. [CHAR-LIMIT=32]">
+ Applies to all tabs (sticky mode)
+ </message>
+ <message name="IDS_OPTION_DESKTOP_FLAG_OFF" desc="The label of the option that revert the hambuger menu flag to actual behaviour. [CHAR-LIMIT=32]">
+ Applies to current tab only
+ </message>
+ <message name="IDS_CUSTOM_UA_FLAG_ON" desc="The label of the option that allows users to define custom user agent.">
+ Use custom user agent
+ </message>
+ <message name="IDS_CUSTOM_UA_FLAG_OFF" desc="The label of the option that revert the user agent to actual value.">
+ Use standard user agent
+ </message>
+ <message name="IDS_CUSTOM_UA_PLACEHOLDER" desc="The label of the placeholder for user agent textbox.">
+ Insert a valid user agent
+ </message>
+ <message name="IDS_CUSTOM_UA_TEXT" desc="The label of the placeholder for user agent textbox.">
+ Mobile User Agent
+ </message>
+ <message name="IDS_CUSTOM_DESKTOP_UA_TEXT" desc="The label of the placeholder for user agent textbox.">
+ Desktop Mode User Agent
+ </message>
+ <message name="IDS_DESKTOP_MODE_VIEWPORTMETA_CHECKBOX" desc="The label of the enable viewport meta checkbox for user desktop mode.">
+ Enable processing of the viewport meta tag also for desktop mode
+ </message>
+
<!-- Notification channels -->
<message name="IDS_NOTIFICATION_CATEGORY_GROUP_GENERAL" desc='Subheading for "General" section of a list of notification categories. [CHAR-LIMIT=32]'>
General
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -3105,4 +3105,17 @@ const char kIncognitoTabHistoryEnabled[] =
"incognito_tab_history_enabled";
#endif
+#if defined(OS_ANDROID)
+const char kOverrideUserAgentEnabled[] =
+ "override_user_agent_enabled";
+const char kOverrideUserAgent[] =
+ "override_user_agent";
+const char kOverrideUserAgentDesktopModeEnabled[] =
+ "override_user_agent_dm_enabled";
+const char kOverrideUserAgentDesktopMode[] =
+ "override_user_agent_dm";
+const char kDesktopModeViewportMetaEnabled[] =
+ "dm-viewport-meta-enabled";
+#endif
+
} // namespace prefs
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -1091,6 +1091,14 @@ extern const char kShowCaretBrowsingDialog[];
extern const char kIncognitoTabHistoryEnabled[];
#endif
+#if defined(OS_ANDROID)
+extern const char kOverrideUserAgentEnabled[];
+extern const char kOverrideUserAgent[];
+extern const char kOverrideUserAgentDesktopModeEnabled[];
+extern const char kOverrideUserAgentDesktopMode[];
+extern const char kDesktopModeViewportMetaEnabled[];
+#endif
+
} // namespace prefs
#endif // CHROME_COMMON_PREF_NAMES_H_
diff --git a/content/browser/android/browser_startup_controller.cc b/content/browser/android/browser_startup_controller.cc
--- a/content/browser/android/browser_startup_controller.cc
+++ b/content/browser/android/browser_startup_controller.cc
@@ -10,11 +10,46 @@
#include "content/browser/browser_main_loop.h"
#include "content/public/android/content_jni_headers/BrowserStartupControllerImpl_jni.h"
+#include "base/logging.h"
+#include "base/command_line.h"
+#include "base/base_switches.h"
+#include "components/prefs/pref_service.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/chrome_switches.h"
+#include "net/http/http_util.h"
+
using base::android::JavaParamRef;
namespace content {
void BrowserStartupComplete(int result) {
+
+ LOG(INFO) << "---Checking user agent override status";
+
+ base::CommandLine* parsed_command_line =
+ base::CommandLine::ForCurrentProcess();
+
+ parsed_command_line->RemoveSwitch(switches::kUserAgent);
+
+ PrefService* local_state = g_browser_process->local_state();
+ bool overrideUserAgentEnabled =
+ local_state->GetBoolean(prefs::kOverrideUserAgentEnabled);
+ if (overrideUserAgentEnabled) {
+ std::string ua = local_state->GetString(prefs::kOverrideUserAgent);
+ if (net::HttpUtil::IsValidHeaderValue(ua)) {
+ parsed_command_line->AppendSwitchASCII(switches::kUserAgent,
+ ua);
+ }
+ else {
+ LOG(INFO) << "Ignored invalid value for ua --" << ua;
+ }
+
+ parsed_command_line->RemoveSwitch(switches::kDesktopModeViewportMetaEnabled);
+ if (local_state->GetBoolean(prefs::kDesktopModeViewportMetaEnabled))
+ parsed_command_line->AppendSwitch(switches::kDesktopModeViewportMetaEnabled);
+ }
+
JNIEnv* env = base::android::AttachCurrentThread();
Java_BrowserStartupControllerImpl_browserStartupComplete(env, result);
}
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
@ -471,6 +1123,38 @@ diff --git a/content/browser/frame_host/navigation_controller_android.h b/conten
void ClearSslPreferences(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& /* obj */);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3503,6 +3503,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kIpcDumpDirectory,
switches::kIpcFuzzerTestcase,
#endif
+ switches::kDesktopModeViewportMetaEnabled,
};
renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
base::size(kSwitchNames));
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -37,6 +37,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h"
+#include "base/base_switches.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
@@ -2319,7 +2320,8 @@ const WebPreferences WebContentsImpl::ComputeWebPreferences() {
prefs.viewport_enabled = command_line.HasSwitch(switches::kEnableViewport);
- if (IsOverridingUserAgent())
+ if (IsOverridingUserAgent() &&
+ !command_line.HasSwitch(switches::kDesktopModeViewportMetaEnabled))
prefs.viewport_meta_enabled = false;
prefs.main_frame_resizes_are_orientation_changes =
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