From: uazo <uazo@users.noreply.github.com>
Date: Thu, 24 Feb 2022 07:54:36 +0000
Subject: Content settings infrastructure

This patch is used by other patches to provide the UI for Bromite-specific
site settings.

See BromiteCustomContentSetting_README.md for more information.

Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
---
 .../browser_ui/site_settings/android/BUILD.gn |   4 +
 .../BromiteCustomContentSetting.java          | 125 ++++++++
 .../BromiteCustomContentSettingImpl.java      | 270 ++++++++++++++++++
 .../BromiteCustomContentSetting_README.md     | 151 ++++++++++
 .../ContentSettingsResources.java             |  13 +-
 .../site_settings/SingleCategorySettings.java |  30 +-
 .../site_settings/SingleWebsiteSettings.java  |  24 +-
 .../site_settings/SiteSettings.java           |   3 +-
 .../site_settings/SiteSettingsCategory.java   |   9 +-
 .../TriStateSiteSettingsPreference.java       |  13 +-
 .../browser_ui/site_settings/Website.java     |   4 +
 .../WebsitePermissionsFetcher.java            |   2 +-
 .../WebsitePreferenceBridge.java              |   2 +-
 .../core/browser/content_settings_registry.cc |  11 +-
 .../core/browser/content_settings_registry.h  |   5 +-
 .../core/browser/website_settings_info.cc     |  10 +-
 .../core/browser/website_settings_info.h      |  12 +-
 .../core/browser/website_settings_registry.cc |   8 +-
 .../core/browser/website_settings_registry.h  |   5 +-
 .../PermissionParamsListBuilder.java          |   1 +
 .../android/page_info_controller_android.cc   |  18 ++
 components/page_info/page_info.cc             |  23 +-
 components/page_info/page_info_ui.cc          |  18 ++
 23 files changed, 733 insertions(+), 28 deletions(-)
 create mode 100644 components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSetting.java
 create mode 100644 components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSettingImpl.java
 create mode 100644 components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSetting_README.md

diff --git a/components/browser_ui/site_settings/android/BUILD.gn b/components/browser_ui/site_settings/android/BUILD.gn
--- a/components/browser_ui/site_settings/android/BUILD.gn
+++ b/components/browser_ui/site_settings/android/BUILD.gn
@@ -88,6 +88,10 @@ android_library("java") {
     "java/src/org/chromium/components/browser_ui/site_settings/WebsiteRowPreference.java",
     "java/src/org/chromium/components/browser_ui/site_settings/TimezoneOverrideSiteSettingsPreference.java"
   ]
+  sources += [
+    "java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSettingImpl.java",
+    "java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSetting.java",
+  ]
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   resources_package = "org.chromium.components.browser_ui.site_settings"
   deps = [
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSetting.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSetting.java
new file mode 100644
--- /dev/null
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSetting.java
@@ -0,0 +1,125 @@
+/*
+    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/>.
+*/
+
+package org.chromium.components.browser_ui.site_settings;
+
+import org.chromium.components.browser_ui.site_settings.ContentSettingsResources;
+import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory;
+import org.chromium.components.content_settings.ContentSettingValues;
+import org.chromium.components.content_settings.ContentSettingsType;
+import org.chromium.content_public.browser.BrowserContextHandle;
+
+import androidx.annotation.Nullable;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import java.util.ArrayList;
+
+public abstract class BromiteCustomContentSetting {
+
+    private @ContentSettingsType int mContentSettingsType;
+    private @SiteSettingsCategory.Type int mSiteSettingsCategory;
+    private @ContentSettingValues Integer mDefaultEnabledValue;
+    private @ContentSettingValues Integer mDefaultDisabledValue;
+    private boolean mAllowException;
+    private String mPreferenceKey;
+    private String mProfilePrefKey;
+
+    public BromiteCustomContentSetting(@ContentSettingsType int contentSettingsType,
+                                       @SiteSettingsCategory.Type int siteSettingsCategory,
+                                       @ContentSettingValues Integer defaultEnabledValue,
+                                       @ContentSettingValues Integer defaultDisabledValue,
+                                       boolean allowException,
+                                       String preferenceKey,
+                                       String profilePrefKey) {
+        mContentSettingsType = contentSettingsType;
+        mSiteSettingsCategory = siteSettingsCategory;
+        mDefaultEnabledValue = defaultEnabledValue;
+        mDefaultDisabledValue = defaultDisabledValue;
+        mAllowException = allowException;
+        mPreferenceKey = preferenceKey;
+        mProfilePrefKey = profilePrefKey;
+    }
+
+    public @ContentSettingsType int getContentSetting() {
+        return mContentSettingsType;
+    }
+
+    public @SiteSettingsCategory.Type int getSiteSettingsCategory() {
+        return mSiteSettingsCategory;
+    }
+
+    protected @ContentSettingValues Integer getDefaultEnabledValue() {
+        return mDefaultEnabledValue;
+    }
+
+    public @ContentSettingValues Integer getDefaultDisabledValue() {
+        return mDefaultDisabledValue;
+    }
+
+    public String getPreferenceKey() {
+        return mPreferenceKey;
+    }
+
+    public String getProfilePrefKey() {
+        return mProfilePrefKey;
+    }
+
+    public boolean isExceptionAllowed() {
+        return mAllowException;
+    }
+
+    public WebsitePermissionsFetcher.WebsitePermissionsType getPermissionsType() {
+        return WebsitePermissionsFetcher.WebsitePermissionsType.CONTENT_SETTING_EXCEPTION;
+    }
+
+    public abstract ContentSettingsResources.ResourceItem getResourceItem();
+    public abstract int getCategorySummary(@Nullable @ContentSettingValues int value);
+    public abstract int getAddExceptionDialogMessage();
+
+    public boolean processOnBlockList(@ContentSettingValues Integer value) {
+        return true;
+    }
+
+    public boolean isOnBlockList(@ContentSettingValues Integer contentSetting) {
+        return mDefaultDisabledValue == contentSetting;
+    }
+
+    public abstract @Nullable Boolean considerException(SiteSettingsCategory category, @ContentSettingValues int value);
+
+    public ContentSettingException createCustomException(@ContentSettingsType int type,
+                                                         @ContentSettingValues int value,
+                                                         WebsiteAddress websiteAddress) {
+        return null;
+    }
+
+    public boolean requiresTriStateContentSetting() {
+        return false;
+    }
+
+    public int[] getTriStateSettingDescriptionIDs() {
+        return null;
+    }
+
+    public boolean showOnlyDescriptions() {
+        return false;
+    }
+
+    public boolean showIntoInfoPage() {
+        return true;
+    }
+}
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSettingImpl.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSettingImpl.java
new file mode 100644
--- /dev/null
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSettingImpl.java
@@ -0,0 +1,270 @@
+/*
+    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/>.
+*/
+
+package org.chromium.components.browser_ui.site_settings;
+
+import android.app.Activity;
+import android.content.Context;
+
+import org.chromium.components.browser_ui.site_settings.ContentSettingsResources;
+import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory;
+import org.chromium.components.content_settings.ContentSettingValues;
+import org.chromium.components.content_settings.ContentSettingsType;
+import org.chromium.content_public.browser.BrowserContextHandle;
+import org.chromium.components.browser_ui.settings.ChromeBasePreference;
+
+import androidx.annotation.Nullable;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.appcompat.app.AlertDialog;
+import android.content.DialogInterface;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public abstract class BromiteCustomContentSettingImpl {
+
+    static private final ArrayList<BromiteCustomContentSetting> mItemList;
+
+    static {
+        mItemList = new ArrayList<BromiteCustomContentSetting>();
+    }
+
+    public static SiteSettingsCategory createFromType(
+            BrowserContextHandle browserContextHandle, @SiteSettingsCategory.Type int type) {
+        return null;
+    }
+
+    public static BromiteCustomContentSetting getContentSetting(@ContentSettingsType int type) {
+        for (BromiteCustomContentSetting cs : mItemList) {
+            if (type == cs.getContentSetting()) {
+                return cs;
+            }
+        }
+        return null;
+    }
+
+    public static @Nullable String getPreferenceKey(@SiteSettingsCategory.Type int type) {
+        for (BromiteCustomContentSetting cs : mItemList) {
+            if (type == cs.getSiteSettingsCategory()) {
+                return cs.getPreferenceKey();
+            }
+        }
+        return null;
+    }
+
+   public static String getProfilePrefKey(@ContentSettingsType int type) {
+        BromiteCustomContentSetting cs = getContentSetting(type);
+        if (cs != null) return cs.getProfilePrefKey();
+        return null;
+    }
+
+    public static @ContentSettingsType int contentSettingsType(@SiteSettingsCategory.Type int type) {
+        for (BromiteCustomContentSetting cs : mItemList) {
+            if (type == cs.getSiteSettingsCategory()) {
+                return cs.getContentSetting();
+            }
+        }
+        return ContentSettingsType.DEFAULT; // Conversion unavailable.
+    }
+
+    public static WebsitePermissionsFetcher.WebsitePermissionsType getPermissionsType(
+            @ContentSettingsType int type) {
+        BromiteCustomContentSetting cs = getContentSetting(type);
+        if (cs != null) return cs.getPermissionsType();
+        return null;
+    }
+
+    public static ContentSettingsResources.ResourceItem getResourceItem(@ContentSettingsType int type) {
+        BromiteCustomContentSetting cs = getContentSetting(type);
+        if (cs != null) return cs.getResourceItem();
+        return null;
+    }
+
+    public static int getCategorySummary(@ContentSettingsType int type, @Nullable @ContentSettingValues int value) {
+        BromiteCustomContentSetting cs = getContentSetting(type);
+        if (cs != null) return cs.getCategorySummary(value);
+        return 0;
+    }
+
+    public static boolean requiresTriStateContentSetting(@ContentSettingsType int type) {
+        BromiteCustomContentSetting cs = getContentSetting(type);
+        if (cs != null) return cs.requiresTriStateContentSetting();
+        return false;
+    }
+
+    public static int[] getTriStateSettingDescriptionIDs(@ContentSettingsType int type) {
+        BromiteCustomContentSetting cs = getContentSetting(type);
+        if (cs != null) return cs.getTriStateSettingDescriptionIDs();
+        return null;
+    }
+
+    public static boolean onPreferenceChange(SiteSettingsCategory category,
+                                             BrowserContextHandle browserContextHandle,
+                                             Preference preference, Object newValue) {
+        for (BromiteCustomContentSetting cs : mItemList) {
+            if (category.getType() != cs.getSiteSettingsCategory()) {
+                continue;
+            }
+
+            if (SingleCategorySettings.BINARY_TOGGLE_KEY.equals(preference.getKey())) {
+                int setting = ((boolean) newValue) == true ? cs.getDefaultEnabledValue() :
+                                                             cs.getDefaultDisabledValue();
+
+                WebsitePreferenceBridge.setDefaultContentSetting(browserContextHandle,
+                        cs.getContentSetting(), setting);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public static boolean processOnBlockList(@ContentSettingsType int type, @ContentSettingValues Integer value) {
+        BromiteCustomContentSetting cs = getContentSetting(type);
+        if (cs != null) return cs.processOnBlockList(value);
+        return false;
+    }
+
+    public static boolean isOnBlockList(@ContentSettingsType int type,
+                                        WebsitePreference website,
+                                        @ContentSettingValues Integer contentSetting) {
+        BromiteCustomContentSetting cs = getContentSetting(type);
+        if (cs != null) return cs.isOnBlockList(contentSetting);
+        return false;
+    }
+
+    public static @Nullable Boolean considerException(SiteSettingsCategory category, @ContentSettingValues int value) {
+        for (BromiteCustomContentSetting cs : mItemList) {
+            if (category.getType() == cs.getSiteSettingsCategory()) {
+                return cs.considerException(category, value);
+            }
+        }
+        return null;
+    }
+
+    public static int getAddExceptionDialogMessage(SiteSettingsCategory category) {
+        for (BromiteCustomContentSetting cs : mItemList) {
+            if (category.getType() == cs.getSiteSettingsCategory()) {
+                return cs.getAddExceptionDialogMessage();
+            }
+        }
+        return 0;
+    }
+
+    public static @Nullable Boolean allowSpecifyingExceptions(SiteSettingsCategory category) {
+        for (BromiteCustomContentSetting cs : mItemList) {
+            if (category.getType() == cs.getSiteSettingsCategory()) {
+                return cs.isExceptionAllowed();
+            }
+        }
+        return null;
+    }
+
+    public static void configurePreferences(SiteSettings settings) {
+        Activity activity = settings.getActivity();
+        PreferenceScreen preferenceScreen = settings.getPreferenceScreen();
+
+        Context styledContext = settings.getPreferenceManager().getContext();
+        for (BromiteCustomContentSetting cs : mItemList) {
+            ChromeBasePreference pref = new ChromeBasePreference(styledContext);
+            pref.setKey(cs.getPreferenceKey());
+            pref.setFragment(SingleCategorySettings.class.getCanonicalName());
+            preferenceScreen.addPreference(pref);
+        }
+    }
+
+    public static List<Integer> getSettingsOrder() {
+        int[] settingOrder = SiteSettingsUtil.SETTINGS_ORDER;
+        List<Integer> order = new ArrayList<Integer>();
+        for (int i = 0; i < settingOrder.length && order.add(settingOrder[i]); i++);
+
+        for (BromiteCustomContentSetting cs : mItemList) {
+            if (cs.showIntoInfoPage() && !order.contains(cs.getContentSetting())) {
+               order.add(cs.getContentSetting());
+            }
+        }
+        return order;
+    }
+
+    public static void onActivityCreated(SingleCategorySettings singleCategorySettings) {
+    }
+
+    public static void configureGlobalToggles(SiteSettingsCategory category, PreferenceScreen preferences) {
+    }
+
+    public static ContentSettingException createCustomException(@ContentSettingsType int type,
+                                                                @ContentSettingValues int value,
+                                                                WebsiteAddress websiteAddress) {
+        BromiteCustomContentSetting cs = getContentSetting(type);
+        if (cs != null) {
+            ContentSettingException exception = cs.createCustomException(type, value, websiteAddress);
+            if (exception == null) {
+                exception = new ContentSettingException(
+                    cs.getContentSetting(), websiteAddress.getHost(), value, "",
+                    /*isEmbargoed=*/false);
+            }
+            return exception;
+        }
+        return null;
+    }
+
+    public static AlertDialog.Builder buildPreferenceDialog(Website site, @ContentSettingsType int type,
+                                                            BrowserContextHandle browserContextHandle,
+                                                            Context context,
+                                                            final DialogInterface.OnClickListener listener) {
+        BromiteCustomContentSetting cs = getContentSetting(type);
+        if (cs != null && cs.requiresTriStateContentSetting()) {
+            int[] values = cs.getTriStateSettingDescriptionIDs();
+
+            CharSequence[] descriptions = new String[3];
+            descriptions[0] = context.getString(values[0]); // ALLOWED
+            descriptions[1] = context.getString(values[1]); // ASK
+            descriptions[2] = context.getString(values[2]); // BLOCKED
+
+            @ContentSettingValues
+            Integer value = site.getContentSetting(browserContextHandle, type);
+
+            return new AlertDialog.Builder(context, R.style.ThemeOverlay_BrowserUI_AlertDialog)
+                    .setPositiveButton(R.string.cancel, null)
+                    .setNegativeButton(R.string.remove,
+                            (dialog, which) -> {
+                                site.setContentSetting(browserContextHandle, type,
+                                        ContentSettingValues.DEFAULT);
+                                listener.onClick(dialog, which);
+                                dialog.dismiss();
+                            })
+                    .setSingleChoiceItems(descriptions,
+                            value == ContentSettingValues.ALLOW ? 0 :
+                            value == ContentSettingValues.ASK ? 1 :
+                                     2,
+                            (dialog, which) -> {
+                                @ContentSettingValues
+                                int permission = which == 0 ? ContentSettingValues.ALLOW :
+                                                 which == 1 ? ContentSettingValues.ASK :
+                                                              ContentSettingValues.BLOCK;
+                                site.setContentSetting(
+                                        browserContextHandle, type, permission);
+
+                                listener.onClick(dialog, which);
+                                dialog.dismiss();
+                            });
+        }
+        return null;
+    }
+}
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSetting_README.md b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSetting_README.md
new file mode 100644
--- /dev/null
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BromiteCustomContentSetting_README.md
@@ -0,0 +1,151 @@
+# Content Settings and Site Settings in Bromite
+
+[TOC]
+
+## Overview
+
+To simplify the addition and management of content settings ui in Bromite, you can use this method: automatically the new menus in the site settings and the item in page info management will be added.
+
+## How to use
+
+* Add a class derived from [BromiteCustomContentSettingImpl](BromiteCustomContentSettingImpl.java)
+
+```
+public class NewContentSetting extends BromiteCustomContentSetting {
+    public BromiteWebGLContentSetting() {
+        super(/*contentSettingsType*/ ContentSettingsType.NEW_CONTENT_SETTING,
+              /*siteSettingsCategory*/ SiteSettingsCategory.Type.NEW_CONTENT_SETTING,
+              /*defaultEnabledValue*/ ContentSettingValues.ALLOW,
+              /*defaultDisabledValue*/ ContentSettingValues.BLOCK,
+              /*allowException*/ true,
+              /*preferenceKey*/ "new_content_setting",
+              /*profilePrefKey*/ "new_content_setting");
+    }
+
+    @Override
+    public ContentSettingsResources.ResourceItem getResourceItem() {
+        return new ContentSettingsResources.ResourceItem(
+            /*icon*/ R.drawable.web_asset,
+            /*title*/ R.string.new_content_setting_permission_title,
+            /*defaultEnabledValue*/ getDefaultEnabledValue(),
+            /*defaultDisabledValue*/ getDefaultDisabledValue(),
+            /*enabledSummary*/ R.string.new_content_setting_enabled,
+            /*disabledSummary*/ R.string.new_content_setting_disabled);
+    }
+
+    @Override
+    public int getCategorySummary(@Nullable @ContentSettingValues int value) {
+        switch (value) {
+            case ContentSettingValues.ALLOW:
+                return R.string.new_content_setting_allow;
+            case ContentSettingValues.ASK:
+                return R.string.new_content_setting_ask;
+            case ContentSettingValues.BLOCK:
+                return R.string.new_content_setting_disabled;
+            default:
+                return 0;
+        }
+    }
+
+    @Override
+    public boolean requiresTriStateContentSetting() {
+        return true; // or false if is a on/off content setting
+    }
+
+    @Override
+    public int[] getTriStateSettingDescriptionIDs() {
+        // only needed if is a tristate setting
+        int[] descriptionIDs = {
+                R.string.website_settings_category_webgl_enabled_antifingerprint,  // ALLOWED
+                R.string.website_settings_category_webgl_enabled,                  // ASK
+                R.string.website_settings_category_webgl_disabled };               // BLOCKED
+        return descriptionIDs;
+    }
+
+    @Override
+    public boolean showOnlyDescriptions() {
+        // true will remove ALLOWED/ASK/BLOCKED from UI
+        // leaving only the descriptions
+        return true;
+    }
+
+    @Override
+    public int getAddExceptionDialogMessage() {
+        return R.string.new_content_setting_exception_dialog_message;
+    }
+
+    @Override
+    public @Nullable Boolean considerException(SiteSettingsCategory category, @ContentSettingValues int value) {
+        // indicate when the value should be considered an exception
+        return value != ContentSettingValues.BLOCK;
+    }
+}
+```
+
+* Add the new class to `BromiteCustomContentSettingImpl` `cctor`
+
+```
+    static {
+        mItemList = new ArrayList<BromiteCustomContentSetting>();
+        mItemList.add(new NewContentSetting());
+    }
+```
+
+* Register the new content setting as usual in `ContentSettingsRegistry::Init()`
+
+```
+ Register(ContentSettingsType::NEW_CONTENT_SETTING, "new_content_setting", CONTENT_SETTING_BLOCK,
+           WebsiteSettingsInfo::SYNCABLE,
+           AllowlistedSchemes(),
+           ValidSettings(CONTENT_SETTING_ALLOW,   // allow
+                         CONTENT_SETTING_ASK,     // ask
+                         CONTENT_SETTING_BLOCK),  // block
+           WebsiteSettingsInfo::SINGLE_ORIGIN_WITH_EMBEDDED_EXCEPTIONS_SCOPE,
+           WebsiteSettingsRegistry::PLATFORM_ANDROID,
+           ContentSettingsInfo::INHERIT_IN_INCOGNITO,
+           ContentSettingsInfo::PERSISTENT,
+           ContentSettingsInfo::EXCEPTIONS_ON_SECURE_AND_INSECURE_ORIGINS,
+           /*show_into_info_page*/ true,
+           /*permission_type_ui*/ IDS_NEW_CONTENT_SETTING,
+           /*permission_type_ui_mid_sentence*/ IDS_NEW_CONTENT_SETTING_MID_SENTENCE);
+```
+
+* Add your content setting in `@IntDef()` and `Type` in `SiteSettingsCategory` as usual
+
+* Add your strings in a new file in `components/browser_ui/strings/android/`
+
+```
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+  <message name="IDS_NEW_CONTENT_SETTING" desc="The label used for your content type site settings controls.">
+    your content type
+  </message>
+  <message name="IDS_NEW_CONTENT_SETTING_MID_SENTENCE" desc="The label used for your content type site settings controls when used mid-sentence.">
+    your content type
+  </message>
+  <message name="IDS_NEW_CONTENT_SETTING_PERMISSION_TITLE" desc="Title of the permission to use your content type [CHAR-LIMIT=32]">
+    your content type
+  </message>
+  <message name="IDS_NEW_CONTENT_SETTING_ENABLED" desc="Summary text explaining that your content type is enabled with fingerprinting protection.">
+    your content type is enabled
+  </message>
+  <message name="IDS_NEW_CONTENT_SETTING_ASK" desc="Summary text explaining that your content type is full enabled.">
+    ask before activate your content type
+  </message>
+  <message name="IDS_NEW_CONTENT_SETTING_DISABLED" desc="Summary text explaining that your content type is full disabled.">
+    your content type is disabled
+  </message>
+</grit-part>
+```
+
+* Reference it in `components/components_strings.grd` to have strings in native
+
+```
+<part file="browser_ui/strings/android/new_content_setting_file.grdp" />
+```
+
+* Reference it in `components/browser_ui/strings/android/browser_ui_strings.grd` to have the strings in java
+
+```
+<part file="new_content_setting_file.grdp" />
+```
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
@@ -38,7 +38,7 @@ public class ContentSettingsResources {
     /**
      * An inner class contains all the resources for a ContentSettingsType
      */
-    private static class ResourceItem {
+    public static class ResourceItem {
         private final int mIcon;
         private final int mTitle;
         private final @ContentSettingValues @Nullable Integer mDefaultEnabledValue;
@@ -290,6 +290,8 @@ public class ContentSettingsResources {
                             R.string.website_settings_category_timezone_override_custom,
                             R.string.website_settings_category_timezone_override_random);
         }
+        ResourceItem ri = BromiteCustomContentSettingImpl.getResourceItem(contentType);
+        if (ri != null) return ri;
         assert false; // NOTREACHED
         return null;
     }
@@ -441,7 +443,9 @@ public class ContentSettingsResources {
         }
     }
 
-    public static int getCategorySummary(int contentType, @Nullable @ContentSettingValues int value) {
+    public static int getCategorySummary(int contentType, @Nullable @ContentSettingValues int value) { //
+        int result = BromiteCustomContentSettingImpl.getCategorySummary(contentType, value);
+        if (result != 0) return result;
         if (contentType == ContentSettingsType.TIMEZONE_OVERRIDE) {
             switch (value) {
                 case ContentSettingValues.ALLOW:
@@ -454,8 +458,7 @@ public class ContentSettingsResources {
                     return 0;
             }
         }
-        else
-            return getCategorySummary(value);
+        return getCategorySummary(value);
     }
 
     /**
@@ -570,6 +573,8 @@ public class ContentSettingsResources {
      *         Blocked states, in that order.
      */
     public static int[] getTriStateSettingDescriptionIDs(int contentType) {
+        int[] value = BromiteCustomContentSettingImpl.getTriStateSettingDescriptionIDs(contentType);
+        if (value != null) return value;
         if (contentType == ContentSettingsType.PROTECTED_MEDIA_IDENTIFIER) {
             // The recommended setting is different on different android versions depending on
             // whether per-origin provisioning is available. See https://crbug.com/904883.
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
@@ -247,6 +247,10 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
         @ContentSettingValues
         Integer contentSetting = website.site().getContentSetting(
                 browserContextHandle, mCategory.getContentSettingsType());
+        if (contentSetting != null &&
+                BromiteCustomContentSettingImpl.processOnBlockList(contentSetting, contentSetting)) {
+            return BromiteCustomContentSettingImpl.isOnBlockList(contentSetting, website, contentSetting);
+        }
         if (contentSetting != null) {
             if (mCategory.getContentSettingsType() == SiteSettingsCategory.Type.TIMEZONE_OVERRIDE) {
                 return ContentSettingValues.ALLOW != contentSetting;
@@ -402,6 +406,7 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
                 ? new HashSet<>(getArguments().getStringArrayList(EXTRA_SELECTED_DOMAINS))
                 : null;
 
+        BromiteCustomContentSettingImpl.onActivityCreated(this);
         configureGlobalToggles();
         if (mCategory.getType() == SiteSettingsCategory.Type.REQUEST_DESKTOP_SITE) {
             RecordUserAction.record("DesktopSiteContentSetting.SettingsPage.Entered");
@@ -508,6 +513,11 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
         BrowserContextHandle browserContextHandle =
                 getSiteSettingsDelegate().getBrowserContextHandle();
         PrefService prefService = UserPrefs.get(browserContextHandle);
+        if (BromiteCustomContentSettingImpl.onPreferenceChange(mCategory,
+                    browserContextHandle, preference, newValue) == true) {
+            getInfoForOrigins();
+            return true;
+        }
         if (BINARY_TOGGLE_KEY.equals(preference.getKey())) {
             assert !mCategory.isManaged();
 
@@ -672,6 +682,8 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
         } else if (mCategory.getType() == SiteSettingsCategory.Type.TIMEZONE_OVERRIDE) {
             resource = R.string.website_settings_category_timezone_override_allowed;
         }
+        if (resource == 0)
+            resource = BromiteCustomContentSettingImpl.getAddExceptionDialogMessage(mCategory);
         assert resource > 0;
         return getString(resource);
     }
@@ -790,6 +802,9 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
             allowSpecifyingExceptions = true;
         } else if (mCategory.getType() == SiteSettingsCategory.Type.TIMEZONE_OVERRIDE) {
             allowSpecifyingExceptions = true;
+        } else {
+            Boolean allow = BromiteCustomContentSettingImpl.allowSpecifyingExceptions(mCategory);
+            if (allow != null) allowSpecifyingExceptions = (boolean)allow;
         }
         if (allowSpecifyingExceptions) {
             getPreferenceScreen().addPreference(new AddExceptionPreference(getStyledContext(),
@@ -961,6 +976,10 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
             TriStateSiteSettingsPreference triStateToggle =
                     (TriStateSiteSettingsPreference) getPreferenceScreen().findPreference(
                             TRI_STATE_TOGGLE_KEY);
+            if (triStateToggle != null) {
+                Boolean blocked = BromiteCustomContentSettingImpl.considerException(mCategory, triStateToggle.getCheckedSetting());
+                if (blocked != null) return (boolean)blocked;
+            }
             if (triStateToggle != null)
               return (triStateToggle.getCheckedSetting() == ContentSettingValues.BLOCK);
 
@@ -1039,6 +1058,7 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
         if (mCategory.getType() != SiteSettingsCategory.Type.TIMEZONE_OVERRIDE) {
             screen.removePreference(screen.findPreference(TIMEOVERRIDE_INFO_TEXT));
         }
+        BromiteCustomContentSettingImpl.configureGlobalToggles(mCategory, screen);
 
         if (permissionBlockedByOs) {
             maybeShowOsWarning(screen);
@@ -1170,7 +1190,7 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
                 getSiteSettingsDelegate().getBrowserContextHandle(), contentType);
         int[] descriptionIds =
                 ContentSettingsResources.getTriStateSettingDescriptionIDs(contentType);
-        triStateToggle.initialize(setting, descriptionIds);
+        triStateToggle.initialize(contentType, setting, descriptionIds);
     }
 
     private void configureTimeOverrideStateToggle(
@@ -1281,6 +1301,14 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
         @ContentSettingValues
         Integer value = site.getContentSetting(browserContextHandle, contentSettingsType);
 
+        AlertDialog.Builder alertDialog =
+            BromiteCustomContentSettingImpl.buildPreferenceDialog(site, contentSettingsType,
+                browserContextHandle, getContext(),
+                (dialog, which) -> { getInfoForOrigins(); });
+        if (alertDialog != null) {
+            return alertDialog;
+        }
+
         CharSequence[] descriptions = new String[2];
         descriptions[0] = getString(ContentSettingsResources.getSiteSummary(
                 ContentSettingValues.ALLOW, contentSettingsType));
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
@@ -42,6 +42,7 @@ import org.chromium.content_public.browser.ContentFeatureList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.List;
 
 /**
  * Shows the permissions and other settings for a particular website.
@@ -171,7 +172,7 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
             case ContentSettingsType.CLIPBOARD_READ_WRITE:
                 return "clipboard_permission_list";
             default:
-                return null;
+                return BromiteCustomContentSettingImpl.getProfilePrefKey(type);
         }
     }
 
@@ -504,7 +505,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
 
     private void setupContentSettingsPreferences() {
         mMaxPermissionOrder = findPreference(PREF_PERMISSIONS_HEADER).getOrder();
-        for (@ContentSettingsType int type : SiteSettingsUtil.SETTINGS_ORDER) {
+        List<Integer> order = BromiteCustomContentSettingImpl.getSettingsOrder();
+        for (@ContentSettingsType int type : order) {
             Preference preference = new ChromeSwitchPreference(getStyledContext());
             preference.setKey(getPreferenceKey(type));
 
@@ -945,16 +947,22 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
 
     private void setupContentSettingsPreference(Preference preference,
             @ContentSettingValues @Nullable Integer value, boolean isEmbargoed) {
-        if (value == null) return;
-        setUpPreferenceCommon(preference, value);
-
         int content_type = getContentSettingsTypeFromPreferenceKey(preference.getKey());
+        BromiteCustomContentSetting cs =
+                BromiteCustomContentSettingImpl.getContentSetting(content_type);
+        if (value == null && cs == null) return;
+        if (value == null) {
+            if (cs.showIntoInfoPage() == false) return;
+            value = WebsitePreferenceBridge.getDefaultContentSetting(
+                        getSiteSettingsDelegate().getBrowserContextHandle(), content_type);
+        }
+        setUpPreferenceCommon(preference, value);
 
         ChromeSwitchPreference switchPreference = (ChromeSwitchPreference) preference;
-        switchPreference.setChecked(value == ContentSettingValues.ALLOW);
+        switchPreference.setChecked(value != ContentSettingValues.BLOCK);
         switchPreference.setSummary(isEmbargoed
                         ? getString(R.string.automatically_blocked)
-                        : getString(ContentSettingsResources.getCategorySummary(content_type, value)));
+                        : getString(ContentSettingsResources.getCategorySummary(content_type, value))); //
         switchPreference.setOnPreferenceChangeListener(this);
         @ContentSettingsType
         int contentType = getContentSettingsTypeFromPreferenceKey(preference.getKey());
@@ -1206,7 +1214,7 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
         }
 
         mSite.setContentSetting(browserContextHandle, type, permission);
-        preference.setSummary(getString(ContentSettingsResources.getCategorySummary(type, permission)));
+        preference.setSummary(getString(ContentSettingsResources.getCategorySummary(type, permission))); //
         preference.setIcon(getContentSettingsIcon(type, permission));
 
         if (mWebsiteSettingsObserver != null) {
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
@@ -33,6 +33,7 @@ public class SiteSettings
         SettingsUtils.addPreferencesFromResource(this, R.xml.site_settings_preferences);
         getActivity().setTitle(getContext().getString(R.string.prefs_site_settings));
 
+        BromiteCustomContentSettingImpl.configurePreferences(this);
         configurePreferences();
         updatePreferenceStates();
     }
@@ -119,7 +120,7 @@ public class SiteSettings
             } else if (requiresTriStateSetting) {
                 p.setSummary(ContentSettingsResources.getCategorySummary(contentType, setting));
             } else {
-                p.setSummary(ContentSettingsResources.getCategorySummary(contentType, checked));
+                p.setSummary(ContentSettingsResources.getCategorySummary(contentType, checked)); //
             }
 
             p.setIcon(SettingsUtils.getTintedIcon(
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java
@@ -126,6 +126,9 @@ public class SiteSettingsCategory {
         } else {
             permission = "";
         }
+        SiteSettingsCategory category = BromiteCustomContentSettingImpl.createFromType(
+            browserContextHandle, type);
+        if (category != null) return category;
         return new SiteSettingsCategory(browserContextHandle, type, permission);
     }
 
@@ -218,7 +221,7 @@ public class SiteSettingsCategory {
             // case Type.ALL_SITES
             // case Type.USE_STORAGE
             default:
-                return ContentSettingsType.DEFAULT; // Conversion unavailable.
+                return BromiteCustomContentSettingImpl.contentSettingsType(type);
         }
     }
 
@@ -304,8 +307,12 @@ public class SiteSettingsCategory {
             case Type.TIMEZONE_OVERRIDE:
                 return "timezone_override";
             default:
+            {
+                String value = BromiteCustomContentSettingImpl.getPreferenceKey(type);
+                if (value != null) return value;
                 assert false;
                 return "";
+            }
         }
     }
 
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/TriStateSiteSettingsPreference.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/TriStateSiteSettingsPreference.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/TriStateSiteSettingsPreference.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/TriStateSiteSettingsPreference.java
@@ -13,6 +13,7 @@ import androidx.preference.PreferenceViewHolder;
 
 import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
 import org.chromium.components.content_settings.ContentSettingValues;
+import org.chromium.components.content_settings.ContentSettingsType;
 
 /**
  * A 3-state Allowed/Ask/Blocked radio group Preference used for SiteSettings.
@@ -25,6 +26,7 @@ public class TriStateSiteSettingsPreference
     private RadioButtonWithDescription mAsk;
     private RadioButtonWithDescription mBlocked;
     private RadioGroup mRadioGroup;
+    private @ContentSettingsType int mContentType;
 
     public TriStateSiteSettingsPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -44,7 +46,9 @@ public class TriStateSiteSettingsPreference
      * @param descriptionIds An array of 3 resource IDs for descriptions for
      *                       Allowed, Ask and Blocked states, in that order.
      */
-    public void initialize(@ContentSettingValues int setting, int[] descriptionIds) {
+    public void initialize(@ContentSettingsType int contentType,
+                           @ContentSettingValues int setting, int[] descriptionIds) {
+        mContentType = contentType;
         mSetting = setting;
         mDescriptionIds = descriptionIds;
     }
@@ -79,6 +83,13 @@ public class TriStateSiteSettingsPreference
         mRadioGroup = (RadioGroup) holder.findViewById(R.id.radio_button_layout);
         mRadioGroup.setOnCheckedChangeListener(this);
 
+        BromiteCustomContentSetting cs =
+                BromiteCustomContentSettingImpl.getContentSetting(mContentType);
+        if (cs != null && cs.showOnlyDescriptions() == true) {
+            mAllowed.setPrimaryText(getContext().getText(mDescriptionIds[0]));
+            mAsk.setPrimaryText(getContext().getText(mDescriptionIds[1]));
+            mBlocked.setPrimaryText(getContext().getText(mDescriptionIds[2]));
+        } else
         if (mDescriptionIds != null) {
             mAllowed.setDescriptionText(getContext().getText(mDescriptionIds[0]));
             mAsk.setDescriptionText(getContext().getText(mDescriptionIds[1]));
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java
@@ -277,6 +277,10 @@ public final class Website implements WebsiteEntry {
                         /*isEmbargoed=*/false);
                 setContentSettingException(type, exception);
             }
+        } else if (exception == null) {
+            exception = BromiteCustomContentSettingImpl.createCustomException(type, value, getAddress());
+            if (exception != null)
+                setContentSettingException(type, exception);
         }
         // We want to call setContentSetting even after explicitly setting
         // mContentSettingException above because this will trigger the actual change
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java
@@ -92,7 +92,7 @@ public class WebsitePermissionsFetcher {
             case ContentSettingsType.USB_GUARD:
                 return WebsitePermissionsType.CHOSEN_OBJECT_INFO;
             default:
-                return null;
+                return BromiteCustomContentSettingImpl.getPermissionsType(contentSettingsType);
         }
     }
 
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
@@ -246,7 +246,7 @@ public class WebsitePreferenceBridge {
             case ContentSettingsType.TIMEZONE_OVERRIDE:
                 return true;
             default:
-                return false;
+                return BromiteCustomContentSettingImpl.requiresTriStateContentSetting(contentSettingsType);
         }
     }
 
diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc
--- a/components/content_settings/core/browser/content_settings_registry.cc
+++ b/components/content_settings/core/browser/content_settings_registry.cc
@@ -15,6 +15,8 @@
 #include "components/content_settings/core/browser/website_settings_registry.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/features.h"
+#include "components/strings/grit/components_chromium_strings.h"
+#include "components/strings/grit/components_strings.h"
 
 #if BUILDFLAG(IS_ANDROID)
 #include "media/base/android/media_drm_bridge.h"
@@ -680,7 +682,10 @@ void ContentSettingsRegistry::Register(
     Platforms platforms,
     ContentSettingsInfo::IncognitoBehavior incognito_behavior,
     ContentSettingsInfo::StorageBehavior storage_behavior,
-    ContentSettingsInfo::OriginRestriction origin_restriction) {
+    ContentSettingsInfo::OriginRestriction origin_restriction,
+    bool show_into_info_page,
+    int permission_type_ui,
+    int permission_type_ui_mid_sentence) {
   // Ensure that nothing has been registered yet for the given type.
   DCHECK(!website_settings_registry_->Get(type));
 
@@ -689,7 +694,9 @@ void ContentSettingsRegistry::Register(
       website_settings_registry_->Register(
           type, name, std::move(default_value), sync_status,
           WebsiteSettingsInfo::NOT_LOSSY, scoping_type, platforms,
-          WebsiteSettingsInfo::INHERIT_IN_INCOGNITO);
+          WebsiteSettingsInfo::INHERIT_IN_INCOGNITO,
+          show_into_info_page, permission_type_ui,
+          permission_type_ui_mid_sentence);
 
   // WebsiteSettingsInfo::Register() will return nullptr if content setting type
   // is not used on the current platform and doesn't need to be registered.
diff --git a/components/content_settings/core/browser/content_settings_registry.h b/components/content_settings/core/browser/content_settings_registry.h
--- a/components/content_settings/core/browser/content_settings_registry.h
+++ b/components/content_settings/core/browser/content_settings_registry.h
@@ -71,7 +71,10 @@ class ContentSettingsRegistry {
                 Platforms platforms,
                 ContentSettingsInfo::IncognitoBehavior incognito_behavior,
                 ContentSettingsInfo::StorageBehavior storage_behavior,
-                ContentSettingsInfo::OriginRestriction origin_restriction);
+                ContentSettingsInfo::OriginRestriction origin_restriction,
+                bool show_into_info_page = false,
+                int permission_type_ui = 0,
+                int permission_type_ui_mid_sentence = 0);
 
   Map content_settings_info_;
   raw_ptr<WebsiteSettingsRegistry> website_settings_registry_;
diff --git a/components/content_settings/core/browser/website_settings_info.cc b/components/content_settings/core/browser/website_settings_info.cc
--- a/components/content_settings/core/browser/website_settings_info.cc
+++ b/components/content_settings/core/browser/website_settings_info.cc
@@ -33,7 +33,10 @@ WebsiteSettingsInfo::WebsiteSettingsInfo(ContentSettingsType type,
                                          SyncStatus sync_status,
                                          LossyStatus lossy_status,
                                          ScopingType scoping_type,
-                                         IncognitoBehavior incognito_behavior)
+                                         IncognitoBehavior incognito_behavior,
+    bool show_into_info_page,
+    int permission_type_ui,
+    int permission_type_ui_mid_sentence)
     : type_(type),
       name_(name),
       pref_name_(GetPreferenceName(name, kPrefPrefix)),
@@ -42,7 +45,10 @@ WebsiteSettingsInfo::WebsiteSettingsInfo(ContentSettingsType type,
       sync_status_(sync_status),
       lossy_status_(lossy_status),
       scoping_type_(scoping_type),
-      incognito_behavior_(incognito_behavior) {
+      incognito_behavior_(incognito_behavior),
+      show_into_info_page_(show_into_info_page),
+      permission_type_ui_(permission_type_ui),
+      permission_type_ui_mid_sentence_(permission_type_ui_mid_sentence) {
   // For legacy reasons the default value is currently restricted to be an int
   // or none.
   // TODO(raymes): We should migrate the underlying pref to be a dictionary
diff --git a/components/content_settings/core/browser/website_settings_info.h b/components/content_settings/core/browser/website_settings_info.h
--- a/components/content_settings/core/browser/website_settings_info.h
+++ b/components/content_settings/core/browser/website_settings_info.h
@@ -88,7 +88,10 @@ class WebsiteSettingsInfo {
                       SyncStatus sync_status,
                       LossyStatus lossy_status,
                       ScopingType scoping_type,
-                      IncognitoBehavior incognito_behavior);
+                      IncognitoBehavior incognito_behavior,
+                      bool show_into_info_page,
+                      int permission_type_ui,
+                      int permission_type_ui_mid_sentence);
 
   WebsiteSettingsInfo(const WebsiteSettingsInfo&) = delete;
   WebsiteSettingsInfo& operator=(const WebsiteSettingsInfo&) = delete;
@@ -113,6 +116,10 @@ class WebsiteSettingsInfo {
   ScopingType scoping_type() const { return scoping_type_; }
   IncognitoBehavior incognito_behavior() const { return incognito_behavior_; }
 
+  bool show_into_info_page() const { return show_into_info_page_; }
+  int permission_type_ui() const { return permission_type_ui_; }
+  int permission_type_ui_mid_sentence() const { return permission_type_ui_mid_sentence_; }
+
  private:
   const ContentSettingsType type_;
   const std::string name_;
@@ -124,6 +131,9 @@ class WebsiteSettingsInfo {
   const LossyStatus lossy_status_;
   const ScopingType scoping_type_;
   const IncognitoBehavior incognito_behavior_;
+  const bool show_into_info_page_;
+  const int permission_type_ui_;
+  const int permission_type_ui_mid_sentence_;
 };
 
 }  // namespace content_settings
diff --git a/components/content_settings/core/browser/website_settings_registry.cc b/components/content_settings/core/browser/website_settings_registry.cc
--- a/components/content_settings/core/browser/website_settings_registry.cc
+++ b/components/content_settings/core/browser/website_settings_registry.cc
@@ -62,7 +62,10 @@ const WebsiteSettingsInfo* WebsiteSettingsRegistry::Register(
     WebsiteSettingsInfo::LossyStatus lossy_status,
     WebsiteSettingsInfo::ScopingType scoping_type,
     Platforms platform,
-    WebsiteSettingsInfo::IncognitoBehavior incognito_behavior) {
+    WebsiteSettingsInfo::IncognitoBehavior incognito_behavior,
+    bool show_into_info_page,
+    int permission_type_ui,
+    int permission_type_ui_mid_sentence) {
 #if BUILDFLAG(IS_WIN)
   if (!(platform & PLATFORM_WINDOWS))
     return nullptr;
@@ -98,7 +101,8 @@ const WebsiteSettingsInfo* WebsiteSettingsRegistry::Register(
 
   WebsiteSettingsInfo* info = new WebsiteSettingsInfo(
       type, name, std::move(initial_default_value), sync_status, lossy_status,
-      scoping_type, incognito_behavior);
+      scoping_type, incognito_behavior,
+      show_into_info_page, permission_type_ui, permission_type_ui_mid_sentence);
   website_settings_info_[info->type()] = base::WrapUnique(info);
   return info;
 }
diff --git a/components/content_settings/core/browser/website_settings_registry.h b/components/content_settings/core/browser/website_settings_registry.h
--- a/components/content_settings/core/browser/website_settings_registry.h
+++ b/components/content_settings/core/browser/website_settings_registry.h
@@ -76,7 +76,10 @@ class WebsiteSettingsRegistry {
       WebsiteSettingsInfo::LossyStatus lossy_status,
       WebsiteSettingsInfo::ScopingType scoping_type,
       Platforms platforms,
-      WebsiteSettingsInfo::IncognitoBehavior incognito_behavior);
+      WebsiteSettingsInfo::IncognitoBehavior incognito_behavior,
+      bool show_into_info_page = false,
+      int permission_type_ui = 0,
+      int permission_type_ui_mid_sentence = 0);
 
   const_iterator begin() const;
   const_iterator end() const;
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java b/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java
--- a/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java
@@ -104,6 +104,7 @@ public class PermissionParamsListBuilder {
                 permissionParams.allowed = true;
                 break;
             case ContentSettingValues.BLOCK:
+            case ContentSettingValues.ASK:
                 permissionParams.allowed = false;
                 break;
             default:
diff --git a/components/page_info/android/page_info_controller_android.cc b/components/page_info/android/page_info_controller_android.cc
--- a/components/page_info/android/page_info_controller_android.cc
+++ b/components/page_info/android/page_info_controller_android.cc
@@ -11,6 +11,7 @@
 #include "base/command_line.h"
 #include "base/containers/contains.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/content_settings/core/browser/website_settings_registry.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "components/page_info/android/jni_headers/PageInfoController_jni.h"
@@ -160,6 +161,14 @@ void PageInfoControllerAndroid::SetPermissionInfo(
         ContentSettingsType::FEDERATED_IDENTITY_API);
   }
 
+  content_settings::WebsiteSettingsRegistry* website_settings =
+      content_settings::WebsiteSettingsRegistry::GetInstance();
+  for (const content_settings::WebsiteSettingsInfo* info : *website_settings) {
+    if (info->show_into_info_page()) {
+       permissions_to_display.push_back(info->type());
+    }
+  }
+
   std::map<ContentSettingsType, ContentSetting>
       user_specified_settings_to_display;
 
@@ -236,6 +245,15 @@ absl::optional<ContentSetting> PageInfoControllerAndroid::GetSettingToDisplay(
     // The images content setting should show up if it is blocked globally
     // to give users an easy way to create exceptions.
     return permission.default_setting;
+  } else {
+    content_settings::WebsiteSettingsRegistry* website_settings =
+        content_settings::WebsiteSettingsRegistry::GetInstance();
+    for (const content_settings::WebsiteSettingsInfo* info : *website_settings) {
+      if (info->type() == permission.type &&
+          info->show_into_info_page()) {
+        return permission.default_setting;
+      }
+    }
   }
 
   // TODO(crbug.com/1077766): Also return permissions that are non
diff --git a/components/page_info/page_info.cc b/components/page_info/page_info.cc
--- a/components/page_info/page_info.cc
+++ b/components/page_info/page_info.cc
@@ -24,6 +24,7 @@
 #include "components/browser_ui/util/android/url_constants.h"
 #include "components/browsing_data/content/local_storage_helper.h"
 #include "components/content_settings/browser/page_specific_content_settings.h"
+#include "components/content_settings/core/browser/website_settings_registry.h"
 #include "components/content_settings/browser/ui/cookie_controls_controller.h"
 #include "components/content_settings/core/browser/content_settings_registry.h"
 #include "components/content_settings/core/browser/content_settings_utils.h"
@@ -167,6 +168,15 @@ bool ShouldShowPermission(const PageInfo::PermissionInfo& info,
     return true;
   }
 
+  content_settings::WebsiteSettingsRegistry* website_settings =
+      content_settings::WebsiteSettingsRegistry::GetInstance();
+  for (const content_settings::WebsiteSettingsInfo* winfo : *website_settings) {
+    if (info.type == winfo->type() &&
+        winfo->show_into_info_page()) {
+      return true;
+    }
+  }
+
   const bool is_incognito = web_contents->GetBrowserContext()->IsOffTheRecord();
 #if BUILDFLAG(IS_ANDROID)
   // Special geolocation DSE settings apply only on Android, so make sure it
@@ -1150,7 +1160,18 @@ void PageInfo::PresentSitePermissions() {
   PermissionInfo permission_info;
   HostContentSettingsMap* content_settings = GetContentSettings();
   DCHECK(web_contents_);
-  for (const ContentSettingsType type : kPermissionType) {
+  std::vector<ContentSettingsType> permission_list;
+  for (const ContentSettingsType type : kPermissionType)
+    permission_list.push_back(type);
+
+  content_settings::WebsiteSettingsRegistry* website_settings =
+      content_settings::WebsiteSettingsRegistry::GetInstance();
+  for (const content_settings::WebsiteSettingsInfo* info : *website_settings) {
+    if (info->show_into_info_page()) {
+      permission_list.push_back(info->type());
+    }
+  }
+  for (const ContentSettingsType type : permission_list) {
     permission_info.type = type;
 
     content_settings::SettingInfo info;
diff --git a/components/page_info/page_info_ui.cc b/components/page_info/page_info_ui.cc
--- a/components/page_info/page_info_ui.cc
+++ b/components/page_info/page_info_ui.cc
@@ -12,6 +12,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "components/content_settings/core/browser/website_settings_registry.h"
 #include "components/omnibox/common/omnibox_features.h"
 #include "components/page_info/core/features.h"
 #include "components/page_info/page_info_ui_delegate.h"
@@ -572,6 +573,12 @@ std::u16string PageInfoUI::PermissionTypeToUIString(ContentSettingsType type) {
     if (info.type == type)
       return l10n_util::GetStringUTF16(info.string_id);
   }
+  const content_settings::WebsiteSettingsInfo* settingInfo =
+    content_settings::WebsiteSettingsRegistry::GetInstance()->Get(type);
+  if (settingInfo && settingInfo->show_into_info_page() &&
+      settingInfo->permission_type_ui() != 0) {
+    return l10n_util::GetStringUTF16(settingInfo->permission_type_ui());
+  }
   NOTREACHED();
   return std::u16string();
 }
@@ -583,6 +590,12 @@ std::u16string PageInfoUI::PermissionTypeToUIStringMidSentence(
     if (info.type == type)
       return l10n_util::GetStringUTF16(info.string_id_mid_sentence);
   }
+  const content_settings::WebsiteSettingsInfo* settingInfo =
+    content_settings::WebsiteSettingsRegistry::GetInstance()->Get(type);
+  if (settingInfo && settingInfo->show_into_info_page() &&
+      settingInfo->permission_type_ui_mid_sentence() != 0) {
+    return l10n_util::GetStringUTF16(settingInfo->permission_type_ui_mid_sentence());
+  }
   NOTREACHED();
   return std::u16string();
 }
@@ -970,6 +983,11 @@ bool PageInfoUI::ContentSettingsTypeInPageInfo(ContentSettingsType type) {
     if (info.type == type)
       return true;
   }
+  const content_settings::WebsiteSettingsInfo* settingInfo =
+    content_settings::WebsiteSettingsRegistry::GetInstance()->Get(type);
+  if (settingInfo) {
+    return settingInfo->show_into_info_page();
+  }
   return false;
 }
 
--
2.25.1
