From: uazo <uazo@users.noreply.github.com>
Date: Tue, 5 Oct 2021 08:38:52 +0000
Subject: Site setting for images

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 |   5 ++++
 .../res/drawable-hdpi/permission_images.png   | Bin 0 -> 257 bytes
 .../res/drawable-mdpi/permission_images.png   | Bin 0 -> 186 bytes
 .../res/drawable-xhdpi/permission_images.png  | Bin 0 -> 316 bytes
 .../res/drawable-xxhdpi/permission_images.png | Bin 0 -> 449 bytes
 .../drawable-xxxhdpi/permission_images.png    | Bin 0 -> 532 bytes
 .../res/xml/site_settings_preferences.xml     |   4 ++++
 .../ContentSettingsResources.java             |   4 ++++
 .../site_settings/SingleCategorySettings.java |   4 ++++
 .../site_settings/SingleWebsiteSettings.java  |  22 ++++++++++++++++++
 .../site_settings/SiteSettingsCategory.java   |  10 ++++++--
 .../site_settings/SiteSettingsUtil.java       |   1 +
 .../browser_ui/site_settings/Website.java     |   7 ++++++
 .../WebsitePermissionsFetcher.java            |   1 +
 .../android/website_preference_bridge.cc      |   1 +
 .../strings/android/site_settings.grdp        |   6 +++++
 .../core/browser/content_settings_registry.cc |   3 ++-
 .../core/browser/content_settings_utils.cc    |   8 ++-----
 .../android/page_info_controller_android.cc   |   4 ++++
 components/page_info/page_info.cc             |   7 ++++--
 components/page_info/page_info_ui.cc          |   4 ++--
 components/site_settings_strings.grdp         |  12 +++++-----
 22 files changed, 84 insertions(+), 19 deletions(-)
 create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-hdpi/permission_images.png
 create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-mdpi/permission_images.png
 create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-xhdpi/permission_images.png
 create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-xxhdpi/permission_images.png
 create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-xxxhdpi/permission_images.png

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
@@ -163,6 +163,7 @@ android_resources("java_resources") {
   sources = [
     "java/res/drawable-hdpi/ic_volume_up_grey600_24dp.png",
     "java/res/drawable-hdpi/permission_background_sync.png",
+    "java/res/drawable-hdpi/permission_images.png",
     "java/res/drawable-hdpi/permission_javascript.png",
     "java/res/drawable-hdpi/permission_javascript_jit.png",
     "java/res/drawable-hdpi/permission_popups.png",
@@ -171,6 +172,7 @@ android_resources("java_resources") {
     "java/res/drawable-hdpi/web_asset.png",
     "java/res/drawable-mdpi/ic_volume_up_grey600_24dp.png",
     "java/res/drawable-mdpi/permission_background_sync.png",
+    "java/res/drawable-mdpi/permission_images.png",
     "java/res/drawable-mdpi/permission_javascript.png",
     "java/res/drawable-mdpi/permission_javascript_jit.png",
     "java/res/drawable-hdpi/settings_autoplay.png",
@@ -184,6 +186,7 @@ android_resources("java_resources") {
     "java/res/drawable-mdpi/web_asset.png",
     "java/res/drawable-xhdpi/ic_volume_up_grey600_24dp.png",
     "java/res/drawable-xhdpi/permission_background_sync.png",
+    "java/res/drawable-xhdpi/permission_images.png",
     "java/res/drawable-xhdpi/permission_javascript.png",
     "java/res/drawable-xhdpi/permission_javascript_jit.png",
     "java/res/drawable-xhdpi/permission_popups.png",
@@ -192,6 +195,7 @@ android_resources("java_resources") {
     "java/res/drawable-xhdpi/web_asset.png",
     "java/res/drawable-xxhdpi/ic_volume_up_grey600_24dp.png",
     "java/res/drawable-xxhdpi/permission_background_sync.png",
+    "java/res/drawable-xxhdpi/permission_images.png",
     "java/res/drawable-xxhdpi/permission_javascript.png",
     "java/res/drawable-xxhdpi/permission_javascript_jit.png",
     "java/res/drawable-xxhdpi/permission_popups.png",
@@ -200,6 +204,7 @@ android_resources("java_resources") {
     "java/res/drawable-xxhdpi/web_asset.png",
     "java/res/drawable-xxxhdpi/ic_volume_up_grey600_24dp.png",
     "java/res/drawable-xxxhdpi/permission_background_sync.png",
+    "java/res/drawable-xxxhdpi/permission_images.png",
     "java/res/drawable-xxxhdpi/permission_javascript.png",
     "java/res/drawable-xxxhdpi/permission_javascript_jit.png",
     "java/res/drawable-xxxhdpi/permission_popups.png",
diff --git a/components/browser_ui/site_settings/android/java/res/drawable-hdpi/permission_images.png b/components/browser_ui/site_settings/android/java/res/drawable-hdpi/permission_images.png
new file mode 100644
index 0000000000000000000000000000000000000000..cafee5acf2299e534676a15fb029192e066551c9
GIT binary patch
literal 257
zcmV+c0sj7pP)<h;3K|Lk000e1NJLTq001Na001Ni1ONa4O9@aD0002UNkl<ZcmZP|
z9*lxew#fFVXHox&g^^Dq+e6u~7z8xtKdCUX9g9IA*N_aKVKeAIIdG^OG-}YOL6J+M
z=1{?)$ormr4jfTui8lyg|4by_p9m|Enh1r+w*(DBw;xzO9fR>B>S3zFJ)`~-FbLEB
zAW2Bk5_vR~8KEwso}fXP_D5Pq{*3w<p@5>0DQX)*gD~xnN{fodD3paF?-Mi#Y(GH|
zZWQ&MkU`N5M1hFpL7hb?uSFuCQm<a4yrzwM2CZr74@Ln1pdnSs3x>A700000NkvXX
Hu0mjfaQkDG

literal 0
HcmV?d00001

diff --git a/components/browser_ui/site_settings/android/java/res/drawable-mdpi/permission_images.png b/components/browser_ui/site_settings/android/java/res/drawable-mdpi/permission_images.png
new file mode 100644
index 0000000000000000000000000000000000000000..52435094e69ea5278e5c2a60238c7c374961ef08
GIT binary patch
literal 186
zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+iMo$;VkP60Ri7g6uj9(RAslQ|J
zDR75+7h6ZspQr%SKk7Uy7bS)`KY4!Q!HV@QrgIuMJ4s3?32|iJ5IZHaQ|QdA<`XV@
z2No-Ss#_tz?5vUg<mCxxJ{<wc_;o8*?=Y$1H*fl&w8TkOplD%KVEo3c4v%9~rzs1a
k;0l{G+5Dws#s($^mqRr#7AM@F4s;BIr>mdKI;Vst089i%5C8xG

literal 0
HcmV?d00001

diff --git a/components/browser_ui/site_settings/android/java/res/drawable-xhdpi/permission_images.png b/components/browser_ui/site_settings/android/java/res/drawable-xhdpi/permission_images.png
new file mode 100644
index 0000000000000000000000000000000000000000..cf3b7d0e10cd0e660db9b2532c54a317c7ea4c6c
GIT binary patch
literal 316
zcmV-C0mJ@@P)<h;3K|Lk000e1NJLTq001xm001xu1ONa4{R=S+00034Nkl<ZcwX(7
zp$@_@5QZ0mAULoyC<KxxKwuEaWxZ2NaJ&Rhft#2akAUGBkO&lNQv*j3gp5D}*APnD
zbv5Mr>Azp{U()nEK1|&NKBkysSq;cA4gBBN7g$<S{7}G(0v4o70hMD#t`?N_zycO%
z!vYqtAcn-HU^{9}+qiQifTQR=0>J>!_JSCeAA(yrc_l<tSwK~cnz)hUVj*WBsVtx>
zumk&deC;*l3{ApVAXgFg@$^(4g07sPNoWexRp1z|cnOE!aw0MoP!$Bs#Y~li#6Un*
z=s=S&5Kt95&?K}4RD}s5`k&X-@#hyZwIFr*eRscr*soBS(+b5f^_@FBh3KYE{OnEu
O0000<MNUMnLSTY+QGR&<

literal 0
HcmV?d00001

diff --git a/components/browser_ui/site_settings/android/java/res/drawable-xxhdpi/permission_images.png b/components/browser_ui/site_settings/android/java/res/drawable-xxhdpi/permission_images.png
new file mode 100644
index 0000000000000000000000000000000000000000..d4d1f0c6e9a59ad9e334daeeb830c953f371706f
GIT binary patch
literal 449
zcmV;y0Y3hTP)<h;3K|Lk000e1NJLTq002k;002k`1ONa4|Kxkj0004qNkl<ZcwX(<
zze>YU6vy#j)Ir6`sdRGHQCx+t4o-6IId=*)FW?jO3G@jZvg!kL>E_acI_m1An@ca%
zLHq+j4wj_lLUKbY=X)QZAIixk<iIaY(=;vO#E#h6?*M0FN1Pynf2L)J0tj`6rUlO;
z;RGgm{!5$)An@VD4>Ya|WJi7=R~LvKd=fwnXDL7mQjmfaq#y+;NI?oxkb>CpiJdkG
zWDP)ZV?cb4EKVB%;+xJIvW_?HLp`9o1)vwxf@JpWG(2cvR{5%!!yj~rnJ5kn;wQ5W
zm<_%y0?`?AaT*fz-rYwQwfQ**x<)RUq%a`rL81eG`^(`+vxQtTNkKrDn2AsMOE|8(
zi@8x80(9S5&;3weum%g`v|<py(hl-Pzt7tR<|mU>CFrwzgrc(NO|C-8W0J~&sE@f(
z+xPP>#Z`d@SV1LmS`s8zVfkc|N`mAnET2qLDG>EgaTNdmS6BtHs|_@1`0}Os>#6z|
rcuTqBlqE2a!;CjO|0S@dX_|%~l|w?sH+N5m00000NkvXXu0mjfPvFC^

literal 0
HcmV?d00001

diff --git a/components/browser_ui/site_settings/android/java/res/drawable-xxxhdpi/permission_images.png b/components/browser_ui/site_settings/android/java/res/drawable-xxxhdpi/permission_images.png
new file mode 100644
index 0000000000000000000000000000000000000000..cca41100e76e81974b4c22d1d9a1fdffabe9cf60
GIT binary patch
literal 532
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%&M7z<Ar!#WAEJ?(J+tzrzVUt-OnZ
zj<TsIB)#y^ztG6Yc5Kzg<sLaPP0}u>4urJLS>(KvDJM1I5sSeVC!Qr--l?HpO;<zI
zelGp~lj*0*{_RKXuQCITW?(qR>{)S8Tk~J#v^^72Y!=i?d{cQE)Ag;b*t31_vH9nV
zHE+q!GY^>%($(j4E91N6`!0s(yqgp{MPz5Sl(mY-3OzXbj%l?Y=bDW0B`>bE=rS;J
zI502?G%&CzU@&c->ZCM25B&cuB92+~LH~=K&+k8LyEK}{Uu@Ih3sBg#T-SozH^Gg4
zORL(#T*i5ynspDne;j<vY4QX8gzcwZc+BHze1DQPRN&}au8h?uIQReE`FDE=bNX72
zDbcA#dh@q3^@lX89gIJaC%W^=e6Pmof%Cm)czzJS5El4jUD`>WMK{8MQcJJ6zdmUy
znIZIt^-b7CyHznp%AEI@%2rSLmEqQ&vKXj-L$vGf6?;<3penTVXY!_lRAk79>d&0Z
z;?9^WDsRH+$8<~UoXf_^4coe`=U8%Ntp2gcvp~Qg>Zmp6Z*GaTkLIw<kphN9qx`;8
zMn5h;e$c<a*?vF&A4ZoC{sBz&EFw>gb>bq=Zve-^0sWl|`X($0(Fg}|Jzf1=);T3K
F0RV{K+KvDK

literal 0
HcmV?d00001

diff --git a/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml b/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml
--- a/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml
+++ b/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml
@@ -47,6 +47,10 @@ found in the LICENSE file.
     <org.chromium.components.browser_ui.settings.ChromeBasePreference
         android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings"
         android:key="javascript" />
+    <!-- Images -->
+    <org.chromium.components.browser_ui.settings.ChromeBasePreference
+        android:key="images"
+        android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" />
     <!-- Timezone Override -->
     <org.chromium.components.browser_ui.settings.ChromeBasePreference
         android:key="timezone_override"
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
@@ -126,6 +126,10 @@ public class ContentSettingsResources {
                 return new ResourceItem(R.drawable.settings_bluetooth, 0, ContentSettingValues.ASK,
                         ContentSettingValues.BLOCK, 0, 0);
 
+            case ContentSettingsType.IMAGES:
+                return new ResourceItem(R.drawable.permission_images, R.string.images_permission_title,
+                        ContentSettingValues.ALLOW, ContentSettingValues.BLOCK, 0, 0);
+
             case ContentSettingsType.BLUETOOTH_GUARD:
                 return new ResourceItem(R.drawable.settings_bluetooth,
                         R.string.website_settings_bluetooth, ContentSettingValues.ASK,
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
@@ -642,6 +642,8 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
                                browserContextHandle, ContentSettingsType.SOUND)
                     ? R.string.website_settings_add_site_description_sound_block
                     : R.string.website_settings_add_site_description_sound_allow;
+        } else if (mCategory.getType() == SiteSettingsCategory.Type.IMAGES) {
+            resource = R.string.website_settings_add_site_description_images;
         } else if (mCategory.getType() == SiteSettingsCategory.Type.COOKIES) {
             if (mRequiresFourStateSetting) {
                 resource = cookieSettingsExceptionShouldBlock()
@@ -768,6 +770,8 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
             allowSpecifyingExceptions = true;
         } else if (mCategory.getType() == SiteSettingsCategory.Type.JAVASCRIPT_JIT) {
             allowSpecifyingExceptions = true;
+        } else if (mCategory.getType() == SiteSettingsCategory.Type.IMAGES) {
+            allowSpecifyingExceptions = true;
         } else if (mCategory.getType() == SiteSettingsCategory.Type.COOKIES) {
             allowSpecifyingExceptions = true;
         } else if (mCategory.getType() == SiteSettingsCategory.Type.BACKGROUND_SYNC
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
@@ -134,6 +134,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
                 return "autoplay_permission_list";
             case ContentSettingsType.IDLE_DETECTION:
                 return "idle_detection_permission_list";
+            case ContentSettingsType.IMAGES:
+                return "images_permission_list";
             case ContentSettingsType.JAVASCRIPT:
                 return "javascript_permission_list";
             case ContentSettingsType.JAVASCRIPT_JIT:
@@ -516,6 +518,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
                 setUpJavascriptPreference(preference);
             } else if (type == ContentSettingsType.GEOLOCATION) {
                 setUpLocationPreference(preference);
+            } else if (type == ContentSettingsType.IMAGES) {
+                setUpImagesPreference(preference);
             } else if (type == ContentSettingsType.JAVASCRIPT_JIT) {
                 setUpJavascriptJitPreference(preference);
             } else if (type == ContentSettingsType.NOTIFICATIONS) {
@@ -1137,6 +1141,24 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
                 mSite.isEmbargoed(ContentSettingsType.REQUEST_DESKTOP_SITE));
     }
 
+    private void setUpImagesPreference(Preference preference) {
+        BrowserContextHandle browserContextHandle =
+                getSiteSettingsDelegate().getBrowserContextHandle();
+        @ContentSettingValues
+        @Nullable
+        Integer currentValue =
+                mSite.getContentSetting(browserContextHandle, ContentSettingsType.IMAGES);
+        // Always show the Images permission
+        if (currentValue == null) {
+            currentValue = WebsitePreferenceBridge.isCategoryEnabled(
+                                   browserContextHandle, ContentSettingsType.IMAGES)
+                    ? ContentSettingValues.ALLOW
+                    : ContentSettingValues.BLOCK;
+        }
+        // Not possible to embargo IMAGES.
+        setupContentSettingsPreference(preference, currentValue, false /* isEmbargoed */);
+    }
+
     private String getDSECategorySummary(@ContentSettingValues int value) {
         return value == ContentSettingValues.ALLOW
                 ? getString(R.string.website_settings_permissions_allowed_dse)
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
@@ -43,7 +43,8 @@ public class SiteSettingsCategory {
             Type.JAVASCRIPT, Type.MICROPHONE, Type.NFC, Type.NOTIFICATIONS, Type.POPUPS,
             Type.PROTECTED_MEDIA, Type.SENSORS, Type.SOUND, Type.USB, Type.VIRTUAL_REALITY,
             Type.USE_STORAGE, Type.AUTO_DARK_WEB_CONTENT, Type.REQUEST_DESKTOP_SITE,
-            Type.FEDERATED_IDENTITY_API, Type.TIMEZONE_OVERRIDE, Type.AUTOPLAY, Type.JAVASCRIPT_JIT})
+            Type.FEDERATED_IDENTITY_API, Type.TIMEZONE_OVERRIDE, Type.AUTOPLAY, Type.JAVASCRIPT_JIT,
+            Type.IMAGES})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Type {
         // All updates here must also be reflected in {@link #preferenceKey(int)
@@ -77,10 +78,11 @@ public class SiteSettingsCategory {
         int TIMEZONE_OVERRIDE = 26;
         int AUTOPLAY = 27;
         int JAVASCRIPT_JIT = 28;
+        int IMAGES = 29;
         /**
          * Number of handled categories used for calculating array sizes.
          */
-        int NUM_ENTRIES = 29;
+        int NUM_ENTRIES = 30;
     }
 
     private final BrowserContextHandle mBrowserContextHandle;
@@ -185,6 +187,8 @@ public class SiteSettingsCategory {
                 return ContentSettingsType.FEDERATED_IDENTITY_API;
             case Type.IDLE_DETECTION:
                 return ContentSettingsType.IDLE_DETECTION;
+            case Type.IMAGES:
+                return ContentSettingsType.IMAGES;
             case Type.JAVASCRIPT:
                 return ContentSettingsType.JAVASCRIPT;
             case Type.JAVASCRIPT_JIT:
@@ -271,6 +275,8 @@ public class SiteSettingsCategory {
                 return "idle_detection";
             case Type.JAVASCRIPT:
                 return "javascript";
+            case Type.IMAGES:
+                return "images";
             case Type.MICROPHONE:
                 return "microphone";
             case Type.JAVASCRIPT_JIT:
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsUtil.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsUtil.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsUtil.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsUtil.java
@@ -32,6 +32,7 @@ public class SiteSettingsUtil {
             ContentSettingsType.SOUND,
             ContentSettingsType.MIDI_SYSEX,
             ContentSettingsType.CLIPBOARD_READ_WRITE,
+            ContentSettingsType.IMAGES,
             ContentSettingsType.NFC,
             ContentSettingsType.BLUETOOTH_SCANNING,
             ContentSettingsType.VR,
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
@@ -214,6 +214,13 @@ public final class Website implements WebsiteEntry {
                         /*isEmbargoed=*/false);
                 setContentSettingException(type, exception);
             }
+        } else if (type == ContentSettingsType.IMAGES) {
+            if (exception == null) {
+                exception = new ContentSettingException(
+                        ContentSettingsType.IMAGES, getAddress().getHost(), value, "",
+                        /*isEmbargoed=*/false);
+                setContentSettingException(type, exception);
+            }
         } else if (type == ContentSettingsType.JAVASCRIPT) {
             // It is possible to set the permission without having an existing exception,
             // because we show the javascript permission in Site Settings if javascript
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
@@ -67,6 +67,7 @@ public class WebsitePermissionsFetcher {
             case ContentSettingsType.AUTOPLAY:
             case ContentSettingsType.COOKIES:
             case ContentSettingsType.FEDERATED_IDENTITY_API:
+            case ContentSettingsType.IMAGES:
             case ContentSettingsType.JAVASCRIPT:
             case ContentSettingsType.JAVASCRIPT_JIT:
             case ContentSettingsType.POPUPS:
diff --git a/components/browser_ui/site_settings/android/website_preference_bridge.cc b/components/browser_ui/site_settings/android/website_preference_bridge.cc
--- a/components/browser_ui/site_settings/android/website_preference_bridge.cc
+++ b/components/browser_ui/site_settings/android/website_preference_bridge.cc
@@ -820,6 +820,7 @@ static void JNI_WebsitePreferenceBridge_SetContentSettingEnabled(
       case ContentSettingsType::BACKGROUND_SYNC:
       case ContentSettingsType::COOKIES:
       case ContentSettingsType::FEDERATED_IDENTITY_API:
+      case ContentSettingsType::IMAGES:
       case ContentSettingsType::JAVASCRIPT:
       case ContentSettingsType::JAVASCRIPT_JIT:
       case ContentSettingsType::POPUPS:
diff --git a/components/browser_ui/strings/android/site_settings.grdp b/components/browser_ui/strings/android/site_settings.grdp
--- a/components/browser_ui/strings/android/site_settings.grdp
+++ b/components/browser_ui/strings/android/site_settings.grdp
@@ -42,6 +42,9 @@
   <message name="IDS_WEBSITE_SETTINGS_IDLE_DETECTION" desc="Title of the permission to detect user activity [CHAR_LIMIT=32]">
     Your device use
   </message>
+  <message name="IDS_IMAGES_PERMISSION_TITLE" desc="Title of the permission to show images [CHAR-LIMIT=32]">
+    Images
+  </message>
   <message name="IDS_JAVASCRIPT_PERMISSION_TITLE" desc="Title of the permission to run javascript [CHAR_LIMIT=32]">
     JavaScript
   </message>
@@ -232,6 +235,9 @@
   <message name="IDS_WEBSITE_SETTINGS_ADD_SITE_TOAST" desc="The toast shown when a new site has been added to the exception list.">
     Site <ph name="SITE_NAME">%1$s<ex>google.com</ex></ph> added
   </message>
+  <message name="IDS_WEBSITE_SETTINGS_ADD_SITE_DESCRIPTION_IMAGES" desc="The description for the allow Images on website dialog.">
+    Allow images on websites you specify while blocking them for the rest of the web
+  </message>
   <message name="IDS_WEBSITE_SETTINGS_ADD_SITE_SITE_URL" desc="The label for the input field where the user can type a website URL.">
     Site URL
   </message>
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
@@ -149,7 +149,8 @@ void ContentSettingsRegistry::Init() {
                               kExtensionScheme),
            ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
            WebsiteSettingsInfo::TOP_ORIGIN_WITH_RESOURCE_EXCEPTIONS_SCOPE,
-           WebsiteSettingsRegistry::DESKTOP,
+           WebsiteSettingsRegistry::DESKTOP |
+               WebsiteSettingsRegistry::PLATFORM_ANDROID,
            ContentSettingsInfo::INHERIT_IN_INCOGNITO,
            ContentSettingsInfo::PERSISTENT,
            ContentSettingsInfo::EXCEPTIONS_ON_SECURE_AND_INSECURE_ORIGINS);
diff --git a/components/content_settings/core/browser/content_settings_utils.cc b/components/content_settings/core/browser/content_settings_utils.cc
--- a/components/content_settings/core/browser/content_settings_utils.cc
+++ b/components/content_settings/core/browser/content_settings_utils.cc
@@ -132,12 +132,8 @@ void GetRendererContentSettingRules(const HostContentSettingsMap* map,
       ContentSettingToValue(CONTENT_SETTING_ALLOW), std::string(),
       map->IsOffTheRecord()));
 #else
-  // Android doesn't use image content settings, so ALLOW rule is added for
-  // all origins.
-  rules->image_rules.push_back(ContentSettingPatternSource(
-      ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
-      ContentSettingToValue(CONTENT_SETTING_ALLOW), std::string(),
-      map->IsOffTheRecord()));
+  map->GetSettingsForOneType(ContentSettingsType::IMAGES,
+                             &(rules->image_rules));
   // In Android active mixed content is hard blocked, with no option to allow
   // it.
   rules->mixed_content_rules.push_back(ContentSettingPatternSource(
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
@@ -232,6 +232,10 @@ absl::optional<ContentSetting> PageInfoControllerAndroid::GetSettingToDisplay(
     // audio since last navigation.
     if (web_contents_->WasEverAudible())
       return permission.default_setting;
+  } else if (permission.type == ContentSettingsType::IMAGES) {
+    // 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;
   }
 
   // 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
@@ -94,9 +94,7 @@ ContentSettingsType kPermissionType[] = {
     ContentSettingsType::SENSORS,
     ContentSettingsType::NOTIFICATIONS,
     ContentSettingsType::JAVASCRIPT,
-#if !BUILDFLAG(IS_ANDROID)
     ContentSettingsType::IMAGES,
-#endif
     ContentSettingsType::POPUPS,
     ContentSettingsType::WINDOW_MANAGEMENT,
     ContentSettingsType::ADS,
@@ -152,6 +150,11 @@ bool ShouldShowPermission(const PageInfo::PermissionInfo& info,
      return true;
   }
 
+  // Always show images when it has a site-specific override
+  if (info.type == ContentSettingsType::IMAGES) {
+     return true;
+  }
+
   if (info.type == ContentSettingsType::SOUND) {
     // The sound content setting should always show up when the tab has played
     // audio.
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
@@ -200,6 +200,8 @@ base::span<const PageInfoUI::PermissionUIInfo> GetContentSettingsUIInfo() {
      IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API_MID_SENTENCE},
     {ContentSettingsType::IDLE_DETECTION, IDS_SITE_SETTINGS_TYPE_IDLE_DETECTION,
      IDS_SITE_SETTINGS_TYPE_IDLE_DETECTION_MID_SENTENCE},
+    {ContentSettingsType::IMAGES, IDS_SITE_SETTINGS_TYPE_IMAGES,
+     IDS_SITE_SETTINGS_TYPE_IMAGES_MID_SENTENCE},
 #if !BUILDFLAG(IS_ANDROID)
     // Page Info Permissions that are not defined in Android.
     {ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
@@ -209,8 +211,6 @@ base::span<const PageInfoUI::PermissionUIInfo> GetContentSettingsUIInfo() {
      IDS_SITE_SETTINGS_TYPE_FONT_ACCESS_MID_SENTENCE},
     {ContentSettingsType::HID_GUARD, IDS_SITE_SETTINGS_TYPE_HID_DEVICES,
      IDS_SITE_SETTINGS_TYPE_HID_DEVICES_MID_SENTENCE},
-    {ContentSettingsType::IMAGES, IDS_SITE_SETTINGS_TYPE_IMAGES,
-     IDS_SITE_SETTINGS_TYPE_IMAGES_MID_SENTENCE},
     {ContentSettingsType::SERIAL_GUARD, IDS_SITE_SETTINGS_TYPE_SERIAL_PORTS,
      IDS_SITE_SETTINGS_TYPE_SERIAL_PORTS_MID_SENTENCE},
     {ContentSettingsType::WINDOW_MANAGEMENT,
diff --git a/components/site_settings_strings.grdp b/components/site_settings_strings.grdp
--- a/components/site_settings_strings.grdp
+++ b/components/site_settings_strings.grdp
@@ -160,6 +160,12 @@
   <message name="IDS_SITE_SETTINGS_TYPE_VR_MID_SENTENCE" desc="The label used for the VR site settings controls when used mid-sentence.">
     virtual reality
   </message>
+  <message name="IDS_SITE_SETTINGS_TYPE_IMAGES" desc="The label used for images site settings controls.">
+    Images
+  </message>
+  <message name="IDS_SITE_SETTINGS_TYPE_IMAGES_MID_SENTENCE" desc="The label used for images site settings controls when used mid-sentence.">
+    images
+  </message>
 
   <!-- Site Settings desktop-only -->
   <if expr="not is_android">
@@ -187,12 +193,6 @@
   <message name="IDS_SITE_SETTINGS_TYPE_HID_DEVICES_MID_SENTENCE" desc="The label used for the HID site settings controls when used mid-sentence.">
     HID devices
   </message>
-  <message name="IDS_SITE_SETTINGS_TYPE_IMAGES" desc="The label used for images site settings controls.">
-    Images
-  </message>
-  <message name="IDS_SITE_SETTINGS_TYPE_IMAGES_MID_SENTENCE" desc="The label used for images site settings controls when used mid-sentence.">
-    images
-  </message>
   <message name="IDS_SITE_SETTINGS_TYPE_INSECURE_CONTENT" desc="The label used for the insecure content site settings controls. This setting controls whether HTTP content will be displayed on HTTPS sites.">
     Insecure content
   </message>
--
2.25.1
