blob: 072b0422ee09fb3cb17fcd7ce0f2627fe4e2d8c6 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/content_settings/content_setting_image_model.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "net/cookies/cookie_options.h"
#include "services/device/public/cpp/device_features.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/color_palette.h"
namespace {
bool HasIcon(const ContentSettingImageModel& model) {
return !model.GetIcon(gfx::kPlaceholderColor).IsEmpty();
}
// Forward all NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED to the specified
// ContentSettingImageModel.
class NotificationForwarder : public content::NotificationObserver {
public:
explicit NotificationForwarder(ContentSettingImageModel* model)
: model_(model) {
registrar_.Add(this,
chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
content::NotificationService::AllSources());
}
~NotificationForwarder() override {}
void clear() {
registrar_.RemoveAll();
}
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override {
if (type == chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED) {
model_->Update(content::Source<content::WebContents>(source).ptr());
}
}
private:
content::NotificationRegistrar registrar_;
ContentSettingImageModel* model_;
DISALLOW_COPY_AND_ASSIGN(NotificationForwarder);
};
class ContentSettingImageModelTest : public ChromeRenderViewHostTestHarness {
};
TEST_F(ContentSettingImageModelTest, Update) {
TabSpecificContentSettings::CreateForWebContents(web_contents());
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::FromWebContents(web_contents());
auto content_setting_image_model =
ContentSettingImageModel::CreateForContentType(
ContentSettingImageModel::ImageType::IMAGES);
EXPECT_FALSE(content_setting_image_model->is_visible());
EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
}
TEST_F(ContentSettingImageModelTest, RPHUpdate) {
TabSpecificContentSettings::CreateForWebContents(web_contents());
auto content_setting_image_model =
ContentSettingImageModel::CreateForContentType(
ContentSettingImageModel::ImageType::PROTOCOL_HANDLERS);
content_setting_image_model->Update(web_contents());
EXPECT_FALSE(content_setting_image_model->is_visible());
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::FromWebContents(web_contents());
content_settings->set_pending_protocol_handler(
ProtocolHandler::CreateProtocolHandler(
"mailto", GURL("http://www.google.com/")));
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
}
TEST_F(ContentSettingImageModelTest, CookieAccessed) {
TabSpecificContentSettings::CreateForWebContents(web_contents());
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::FromWebContents(web_contents());
HostContentSettingsMapFactory::GetForProfile(profile())
->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
CONTENT_SETTING_BLOCK);
auto content_setting_image_model =
ContentSettingImageModel::CreateForContentType(
ContentSettingImageModel::ImageType::COOKIES);
EXPECT_FALSE(content_setting_image_model->is_visible());
EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
net::CookieOptions options;
GURL origin("http://google.com");
std::unique_ptr<net::CanonicalCookie> cookie(
net::CanonicalCookie::Create(origin, "A=B", base::Time::Now(), options));
ASSERT_TRUE(cookie);
content_settings->OnCookieChange(origin, origin, *cookie, false);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
}
TEST_F(ContentSettingImageModelTest, SensorAccessed) {
// Enable all sensors just to avoid hardcoding the expected messages to the
// motion sensor-specific ones.
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kGenericSensorExtraClasses);
TabSpecificContentSettings::CreateForWebContents(web_contents());
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::FromWebContents(web_contents());
auto content_setting_image_model =
ContentSettingImageModel::CreateForContentType(
ContentSettingImageModel::ImageType::SENSORS);
EXPECT_FALSE(content_setting_image_model->is_visible());
EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
// Allowing by default means sensor access will not cause the indicator to be
// shown.
HostContentSettingsMapFactory::GetForProfile(profile())
->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_ALLOW);
content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
EXPECT_FALSE(content_setting_image_model->is_visible());
EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
content_settings->ClearContentSettingsExceptForNavigationRelatedSettings();
// Allowing by default but blocking (e.g. due to a feature policy) causes the
// indicator to be shown.
HostContentSettingsMapFactory::GetForProfile(profile())
->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_ALLOW);
content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
EXPECT_EQ(content_setting_image_model->get_tooltip(),
l10n_util::GetStringUTF16(IDS_SENSORS_BLOCKED_TOOLTIP));
content_settings->ClearContentSettingsExceptForNavigationRelatedSettings();
// Blocking by default but allowing (e.g. via a site-specific exception)
// causes the indicator to be shown.
HostContentSettingsMapFactory::GetForProfile(profile())
->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_BLOCK);
content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
EXPECT_EQ(content_setting_image_model->get_tooltip(),
l10n_util::GetStringUTF16(IDS_SENSORS_ALLOWED_TOOLTIP));
content_settings->ClearContentSettingsExceptForNavigationRelatedSettings();
// Blocking access by default also causes the indicator to be shown so users
// can set an exception.
HostContentSettingsMapFactory::GetForProfile(profile())
->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_BLOCK);
content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
EXPECT_EQ(content_setting_image_model->get_tooltip(),
l10n_util::GetStringUTF16(IDS_SENSORS_BLOCKED_TOOLTIP));
}
// Regression test for https://crbug.com/955408
// See also: ContentSettingBubbleModelTest.SensorAccessPermissionsChanged
TEST_F(ContentSettingImageModelTest, SensorAccessPermissionsChanged) {
// Enable all sensors just to avoid hardcoding the expected messages to the
// motion sensor-specific ones.
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kGenericSensorExtraClasses);
TabSpecificContentSettings::CreateForWebContents(web_contents());
content::WebContentsTester::For(web_contents())
->NavigateAndCommit(GURL("https://www.example.com"));
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::FromWebContents(web_contents());
HostContentSettingsMap* settings_map =
HostContentSettingsMapFactory::GetForProfile(profile());
auto content_setting_image_model =
ContentSettingImageModel::CreateForContentType(
ContentSettingImageModel::ImageType::SENSORS);
EXPECT_FALSE(content_setting_image_model->is_visible());
EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
// Go from allow by default to block by default to allow by default.
{
settings_map->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_ALLOW);
content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
EXPECT_FALSE(content_setting_image_model->is_visible());
EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
settings_map->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_BLOCK);
content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
EXPECT_EQ(content_setting_image_model->get_tooltip(),
l10n_util::GetStringUTF16(IDS_SENSORS_BLOCKED_TOOLTIP));
settings_map->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_ALLOW);
content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
// The icon and toolip remain set to the values above, but it is not a
// problem since the image model is not visible.
EXPECT_FALSE(content_setting_image_model->is_visible());
}
content_settings->ClearContentSettingsExceptForNavigationRelatedSettings();
// Go from block by default to allow by default to block by default.
{
settings_map->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_BLOCK);
content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
EXPECT_EQ(content_setting_image_model->get_tooltip(),
l10n_util::GetStringUTF16(IDS_SENSORS_BLOCKED_TOOLTIP));
settings_map->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_ALLOW);
content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
// The icon and toolip remain set to the values above, but it is not a
// problem since the image model is not visible.
EXPECT_FALSE(content_setting_image_model->is_visible());
settings_map->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_BLOCK);
content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
EXPECT_EQ(content_setting_image_model->get_tooltip(),
l10n_util::GetStringUTF16(IDS_SENSORS_BLOCKED_TOOLTIP));
}
content_settings->ClearContentSettingsExceptForNavigationRelatedSettings();
// Block by default but allow a specific site.
{
settings_map->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_BLOCK);
settings_map->SetContentSettingDefaultScope(
web_contents()->GetURL(), web_contents()->GetURL(),
CONTENT_SETTINGS_TYPE_SENSORS, std::string(), CONTENT_SETTING_ALLOW);
content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
EXPECT_EQ(content_setting_image_model->get_tooltip(),
l10n_util::GetStringUTF16(IDS_SENSORS_ALLOWED_TOOLTIP));
}
content_settings->ClearContentSettingsExceptForNavigationRelatedSettings();
// Clear site-specific exceptions.
settings_map->ClearSettingsForOneType(CONTENT_SETTINGS_TYPE_SENSORS);
// Allow by default but allow a specific site.
{
settings_map->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_SENSORS,
CONTENT_SETTING_ALLOW);
settings_map->SetContentSettingDefaultScope(
web_contents()->GetURL(), web_contents()->GetURL(),
CONTENT_SETTINGS_TYPE_SENSORS, std::string(), CONTENT_SETTING_BLOCK);
content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_SENSORS);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
EXPECT_EQ(content_setting_image_model->get_tooltip(),
l10n_util::GetStringUTF16(IDS_SENSORS_BLOCKED_TOOLTIP));
}
}
// Regression test for http://crbug.com/161854.
TEST_F(ContentSettingImageModelTest, NULLTabSpecificContentSettings) {
auto content_setting_image_model =
ContentSettingImageModel::CreateForContentType(
ContentSettingImageModel::ImageType::IMAGES);
NotificationForwarder forwarder(content_setting_image_model.get());
// Should not crash.
TabSpecificContentSettings::CreateForWebContents(web_contents());
forwarder.clear();
}
TEST_F(ContentSettingImageModelTest, SubresourceFilter) {
TabSpecificContentSettings::CreateForWebContents(web_contents());
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::FromWebContents(web_contents());
auto content_setting_image_model =
ContentSettingImageModel::CreateForContentType(
ContentSettingImageModel::ImageType::ADS);
EXPECT_FALSE(content_setting_image_model->is_visible());
EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_ADS);
content_setting_image_model->Update(web_contents());
EXPECT_TRUE(content_setting_image_model->is_visible());
EXPECT_TRUE(HasIcon(*content_setting_image_model));
EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
}
} // namespace