diff options
Diffstat (limited to 'chromium/components/blocked_content/android')
-rw-r--r-- | chromium/components/blocked_content/android/BUILD.gn | 16 | ||||
-rw-r--r-- | chromium/components/blocked_content/android/DEPS | 6 | ||||
-rw-r--r-- | chromium/components/blocked_content/android/popup_blocked_infobar_delegate.cc | 141 | ||||
-rw-r--r-- | chromium/components/blocked_content/android/popup_blocked_infobar_delegate.h | 61 | ||||
-rw-r--r-- | chromium/components/blocked_content/android/popup_blocked_infobar_delegate_unittest.cc | 133 | ||||
-rw-r--r-- | chromium/components/blocked_content/android/res/drawable-hdpi/infobar_blocked_popups.png | bin | 0 -> 285 bytes | |||
-rw-r--r-- | chromium/components/blocked_content/android/res/drawable-mdpi/infobar_blocked_popups.png | bin | 0 -> 210 bytes | |||
-rw-r--r-- | chromium/components/blocked_content/android/res/drawable-xhdpi/infobar_blocked_popups.png | bin | 0 -> 328 bytes | |||
-rw-r--r-- | chromium/components/blocked_content/android/res/drawable-xxhdpi/infobar_blocked_popups.png | bin | 0 -> 472 bytes | |||
-rw-r--r-- | chromium/components/blocked_content/android/res/drawable-xxxhdpi/infobar_blocked_popups.png | bin | 0 -> 563 bytes |
10 files changed, 357 insertions, 0 deletions
diff --git a/chromium/components/blocked_content/android/BUILD.gn b/chromium/components/blocked_content/android/BUILD.gn new file mode 100644 index 00000000000..1a42a65a8cf --- /dev/null +++ b/chromium/components/blocked_content/android/BUILD.gn @@ -0,0 +1,16 @@ +# Copyright 2020 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. + +import("//build/config/android/rules.gni") + +android_resources("java_resources") { + sources = [ + "res/drawable-hdpi/infobar_blocked_popups.png", + "res/drawable-mdpi/infobar_blocked_popups.png", + "res/drawable-xhdpi/infobar_blocked_popups.png", + "res/drawable-xxhdpi/infobar_blocked_popups.png", + "res/drawable-xxxhdpi/infobar_blocked_popups.png", + ] + custom_package = "org.chromium.components.blocked_content" +} diff --git a/chromium/components/blocked_content/android/DEPS b/chromium/components/blocked_content/android/DEPS new file mode 100644 index 00000000000..61e69ecd030 --- /dev/null +++ b/chromium/components/blocked_content/android/DEPS @@ -0,0 +1,6 @@ +include_rules = [ + "+components/infobars/content", + "+components/infobars/core", + "+components/resources/android", + "+components/strings", +] diff --git a/chromium/components/blocked_content/android/popup_blocked_infobar_delegate.cc b/chromium/components/blocked_content/android/popup_blocked_infobar_delegate.cc new file mode 100644 index 00000000000..0e4d3818aef --- /dev/null +++ b/chromium/components/blocked_content/android/popup_blocked_infobar_delegate.cc @@ -0,0 +1,141 @@ +// Copyright 2013 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 "components/blocked_content/android/popup_blocked_infobar_delegate.h" + +#include <stddef.h> +#include <utility> + +#include "components/blocked_content/popup_blocker_tab_helper.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/content_settings_types.h" +#include "components/infobars/content/content_infobar_manager.h" +#include "components/infobars/core/infobar.h" +#include "components/prefs/pref_service.h" +#include "components/resources/android/theme_resources.h" +#include "components/strings/grit/components_strings.h" +#include "ui/base/l10n/l10n_util.h" + +namespace blocked_content { + +// static +bool PopupBlockedInfoBarDelegate::Create( + infobars::ContentInfoBarManager* infobar_manager, + int num_popups, + HostContentSettingsMap* settings_map, + base::OnceClosure on_accept_callback) { + const GURL& url = infobar_manager->web_contents()->GetURL(); + std::unique_ptr<infobars::InfoBar> infobar( + infobar_manager->CreateConfirmInfoBar( + std::unique_ptr<ConfirmInfoBarDelegate>( + new PopupBlockedInfoBarDelegate(num_popups, url, settings_map, + std::move(on_accept_callback))))); + + // See if there is an existing popup infobar already. + // TODO(dfalcantara) When triggering more than one popup the infobar + // will be shown once, then hide then be shown again. + // This will be fixed once we have an in place replace infobar mechanism. + for (size_t i = 0; i < infobar_manager->infobar_count(); ++i) { + infobars::InfoBar* existing_infobar = infobar_manager->infobar_at(i); + if (existing_infobar->delegate()->AsPopupBlockedInfoBarDelegate()) { + infobar_manager->ReplaceInfoBar(existing_infobar, std::move(infobar)); + return false; + } + } + + infobar_manager->AddInfoBar(std::move(infobar)); + + return true; +} + +PopupBlockedInfoBarDelegate::~PopupBlockedInfoBarDelegate() = default; + +infobars::InfoBarDelegate::InfoBarIdentifier +PopupBlockedInfoBarDelegate::GetIdentifier() const { + return POPUP_BLOCKED_INFOBAR_DELEGATE_MOBILE; +} + +int PopupBlockedInfoBarDelegate::GetIconId() const { + return IDR_ANDROID_INFOBAR_BLOCKED_POPUPS; +} + +PopupBlockedInfoBarDelegate* +PopupBlockedInfoBarDelegate::AsPopupBlockedInfoBarDelegate() { + return this; +} + +PopupBlockedInfoBarDelegate::PopupBlockedInfoBarDelegate( + int num_popups, + const GURL& url, + HostContentSettingsMap* map, + base::OnceClosure on_accept_callback) + : ConfirmInfoBarDelegate(), + num_popups_(num_popups), + url_(url), + map_(map), + on_accept_callback_(std::move(on_accept_callback)) { + content_settings::SettingInfo setting_info; + std::unique_ptr<base::Value> setting = map->GetWebsiteSetting( + url, url, ContentSettingsType::POPUPS, std::string(), &setting_info); + can_show_popups_ = + setting_info.source != content_settings::SETTING_SOURCE_POLICY; +} + +base::string16 PopupBlockedInfoBarDelegate::GetMessageText() const { + return l10n_util::GetPluralStringFUTF16(IDS_POPUPS_BLOCKED_INFOBAR_TEXT, + num_popups_); +} + +int PopupBlockedInfoBarDelegate::GetButtons() const { + if (!can_show_popups_) + return 0; + + int buttons = BUTTON_OK; + + return buttons; +} + +base::string16 PopupBlockedInfoBarDelegate::GetButtonLabel( + InfoBarButton button) const { + switch (button) { + case BUTTON_OK: + return l10n_util::GetStringUTF16(IDS_POPUPS_BLOCKED_INFOBAR_BUTTON_SHOW); + case BUTTON_CANCEL: + return l10n_util::GetStringUTF16(IDS_PERMISSION_DENY); + default: + NOTREACHED(); + break; + } + return base::string16(); +} + +bool PopupBlockedInfoBarDelegate::Accept() { + DCHECK(can_show_popups_); + + // Create exceptions. + map_->SetNarrowestContentSetting(url_, url_, ContentSettingsType::POPUPS, + CONTENT_SETTING_ALLOW); + + // Launch popups. + content::WebContents* web_contents = + infobars::ContentInfoBarManager::WebContentsFromInfoBar(infobar()); + blocked_content::PopupBlockerTabHelper* popup_blocker_helper = + blocked_content::PopupBlockerTabHelper::FromWebContents(web_contents); + DCHECK(popup_blocker_helper); + blocked_content::PopupBlockerTabHelper::PopupIdMap blocked_popups = + popup_blocker_helper->GetBlockedPopupRequests(); + for (blocked_content::PopupBlockerTabHelper::PopupIdMap::iterator it = + blocked_popups.begin(); + it != blocked_popups.end(); ++it) { + popup_blocker_helper->ShowBlockedPopup(it->first, + WindowOpenDisposition::CURRENT_TAB); + } + + if (on_accept_callback_) + std::move(on_accept_callback_).Run(); + return true; +} + +} // namespace blocked_content diff --git a/chromium/components/blocked_content/android/popup_blocked_infobar_delegate.h b/chromium/components/blocked_content/android/popup_blocked_infobar_delegate.h new file mode 100644 index 00000000000..43e31266e73 --- /dev/null +++ b/chromium/components/blocked_content/android/popup_blocked_infobar_delegate.h @@ -0,0 +1,61 @@ +// Copyright 2013 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. + +#ifndef COMPONENTS_BLOCKED_CONTENT_ANDROID_POPUP_BLOCKED_INFOBAR_DELEGATE_H_ +#define COMPONENTS_BLOCKED_CONTENT_ANDROID_POPUP_BLOCKED_INFOBAR_DELEGATE_H_ + +#include "base/callback.h" +#include "components/infobars/core/confirm_infobar_delegate.h" +#include "url/gurl.h" + +namespace infobars { +class ContentInfoBarManager; +} + +class HostContentSettingsMap; + +namespace blocked_content { + +class PopupBlockedInfoBarDelegate : public ConfirmInfoBarDelegate { + public: + // Creates a popup blocked infobar and delegate and adds the infobar to + // |infobar_manager|. Returns true if the infobar was created, and false if it + // replaced an existing popup infobar. |on_accept_callback| will be run if the + // accept button is pressed on the infobar. + static bool Create(infobars::ContentInfoBarManager* infobar_manager, + int num_popups, + HostContentSettingsMap* settings_map, + base::OnceClosure on_accept_callback); + + ~PopupBlockedInfoBarDelegate() override; + + PopupBlockedInfoBarDelegate(const PopupBlockedInfoBarDelegate&) = delete; + PopupBlockedInfoBarDelegate& operator=(const PopupBlockedInfoBarDelegate&) = + delete; + + private: + PopupBlockedInfoBarDelegate(int num_popups, + const GURL& url, + HostContentSettingsMap* map, + base::OnceClosure on_accept_callback); + + // ConfirmInfoBarDelegate: + infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; + int GetIconId() const override; + PopupBlockedInfoBarDelegate* AsPopupBlockedInfoBarDelegate() override; + base::string16 GetMessageText() const override; + int GetButtons() const override; + base::string16 GetButtonLabel(InfoBarButton button) const override; + bool Accept() override; + + const int num_popups_; + const GURL url_; + HostContentSettingsMap* map_; + bool can_show_popups_; + base::OnceClosure on_accept_callback_; +}; + +} // namespace blocked_content + +#endif // COMPONENTS_BLOCKED_CONTENT_ANDROID_POPUP_BLOCKED_INFOBAR_DELEGATE_H_ diff --git a/chromium/components/blocked_content/android/popup_blocked_infobar_delegate_unittest.cc b/chromium/components/blocked_content/android/popup_blocked_infobar_delegate_unittest.cc new file mode 100644 index 00000000000..e9d3bdf24e3 --- /dev/null +++ b/chromium/components/blocked_content/android/popup_blocked_infobar_delegate_unittest.cc @@ -0,0 +1,133 @@ +// Copyright 2020 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 "components/blocked_content/android/popup_blocked_infobar_delegate.h" + +#include "base/strings/utf_string_conversions.h" +#include "base/test/bind_test_util.h" +#include "base/test/scoped_feature_list.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" +#include "components/blocked_content/safe_browsing_triggered_popup_blocker.h" +#include "components/blocked_content/test/test_popup_navigation_delegate.h" +#include "components/content_settings/browser/tab_specific_content_settings.h" +#include "components/content_settings/browser/test_tab_specific_content_settings_delegate.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/infobars/content/content_infobar_manager.h" +#include "components/infobars/core/infobar.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "content/public/test/test_renderer_host.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace blocked_content { +namespace { +constexpr char kPageUrl[] = "http://example_page.test"; +constexpr char kPopupUrl[] = "http://example_popup.test"; + +class TestInfoBarManager : public infobars::ContentInfoBarManager { + public: + explicit TestInfoBarManager(content::WebContents* web_contents) + : ContentInfoBarManager(web_contents) {} + + // infobars::InfoBarManager: + std::unique_ptr<infobars::InfoBar> CreateConfirmInfoBar( + std::unique_ptr<ConfirmInfoBarDelegate> delegate) override { + return std::make_unique<infobars::InfoBar>(std::move(delegate)); + } +}; + +} // namespace + +class PopupBlockedInfoBarDelegateTest + : public content::RenderViewHostTestHarness { + public: + ~PopupBlockedInfoBarDelegateTest() override { + settings_map_->ShutdownOnUIThread(); + } + + // content::RenderViewHostTestHarness: + void SetUp() override { + content::RenderViewHostTestHarness::SetUp(); + // Make sure the SafeBrowsingTriggeredPopupBlocker is not created. + feature_list_.InitAndDisableFeature(kAbusiveExperienceEnforce); + + HostContentSettingsMap::RegisterProfilePrefs(pref_service_.registry()); + settings_map_ = base::MakeRefCounted<HostContentSettingsMap>( + &pref_service_, false, false, false, false); + content_settings::TabSpecificContentSettings::CreateForWebContents( + web_contents(), + std::make_unique< + content_settings::TestTabSpecificContentSettingsDelegate>( + /*prefs=*/nullptr, settings_map_.get())); + + PopupBlockerTabHelper::CreateForWebContents(web_contents()); + helper_ = PopupBlockerTabHelper::FromWebContents(web_contents()); + infobar_manager_ = std::make_unique<TestInfoBarManager>(web_contents()); + + NavigateAndCommit(GURL(kPageUrl)); + } + + PopupBlockerTabHelper* helper() { return helper_; } + + TestInfoBarManager* infobar_manager() { return infobar_manager_.get(); } + + HostContentSettingsMap* settings_map() { return settings_map_.get(); } + + private: + base::test::ScopedFeatureList feature_list_; + PopupBlockerTabHelper* helper_ = nullptr; + sync_preferences::TestingPrefServiceSyncable pref_service_; + scoped_refptr<HostContentSettingsMap> settings_map_; + std::unique_ptr<TestInfoBarManager> infobar_manager_; +}; + +TEST_F(PopupBlockedInfoBarDelegateTest, ReplacesInfobarOnSecondPopup) { + EXPECT_TRUE(PopupBlockedInfoBarDelegate::Create( + infobar_manager(), 1, settings_map(), base::NullCallback())); + EXPECT_EQ(infobar_manager()->infobar_count(), 1u); + // First message should not contain "2"; + EXPECT_FALSE(base::Contains(infobar_manager() + ->infobar_at(0) + ->delegate() + ->AsConfirmInfoBarDelegate() + ->GetMessageText(), + base::ASCIIToUTF16("2"))); + + EXPECT_FALSE(PopupBlockedInfoBarDelegate::Create( + infobar_manager(), 2, settings_map(), base::NullCallback())); + EXPECT_EQ(infobar_manager()->infobar_count(), 1u); + // Second message blocks 2 popups, so should contain "2"; + EXPECT_TRUE(base::Contains(infobar_manager() + ->infobar_at(0) + ->delegate() + ->AsConfirmInfoBarDelegate() + ->GetMessageText(), + base::ASCIIToUTF16("2"))); +} + +TEST_F(PopupBlockedInfoBarDelegateTest, ShowsBlockedPopups) { + TestPopupNavigationDelegate::ResultHolder result; + helper()->AddBlockedPopup( + std::make_unique<TestPopupNavigationDelegate>(GURL(kPopupUrl), &result), + blink::mojom::WindowFeatures(), PopupBlockType::kNoGesture); + bool on_accept_called = false; + EXPECT_TRUE(PopupBlockedInfoBarDelegate::Create( + infobar_manager(), 1, settings_map(), + base::BindLambdaForTesting( + [&on_accept_called] { on_accept_called = true; }))); + EXPECT_FALSE(on_accept_called); + + EXPECT_TRUE(infobar_manager() + ->infobar_at(0) + ->delegate() + ->AsConfirmInfoBarDelegate() + ->Accept()); + EXPECT_TRUE(result.did_navigate); + EXPECT_TRUE(on_accept_called); + EXPECT_EQ(settings_map()->GetContentSetting(GURL(kPageUrl), GURL(kPageUrl), + ContentSettingsType::POPUPS, + std::string()), + CONTENT_SETTING_ALLOW); +} + +} // namespace blocked_content diff --git a/chromium/components/blocked_content/android/res/drawable-hdpi/infobar_blocked_popups.png b/chromium/components/blocked_content/android/res/drawable-hdpi/infobar_blocked_popups.png Binary files differnew file mode 100644 index 00000000000..c3ebd4ecb8a --- /dev/null +++ b/chromium/components/blocked_content/android/res/drawable-hdpi/infobar_blocked_popups.png diff --git a/chromium/components/blocked_content/android/res/drawable-mdpi/infobar_blocked_popups.png b/chromium/components/blocked_content/android/res/drawable-mdpi/infobar_blocked_popups.png Binary files differnew file mode 100644 index 00000000000..06bcee8d67b --- /dev/null +++ b/chromium/components/blocked_content/android/res/drawable-mdpi/infobar_blocked_popups.png diff --git a/chromium/components/blocked_content/android/res/drawable-xhdpi/infobar_blocked_popups.png b/chromium/components/blocked_content/android/res/drawable-xhdpi/infobar_blocked_popups.png Binary files differnew file mode 100644 index 00000000000..48e6a6a6ec2 --- /dev/null +++ b/chromium/components/blocked_content/android/res/drawable-xhdpi/infobar_blocked_popups.png diff --git a/chromium/components/blocked_content/android/res/drawable-xxhdpi/infobar_blocked_popups.png b/chromium/components/blocked_content/android/res/drawable-xxhdpi/infobar_blocked_popups.png Binary files differnew file mode 100644 index 00000000000..98379ed4c49 --- /dev/null +++ b/chromium/components/blocked_content/android/res/drawable-xxhdpi/infobar_blocked_popups.png diff --git a/chromium/components/blocked_content/android/res/drawable-xxxhdpi/infobar_blocked_popups.png b/chromium/components/blocked_content/android/res/drawable-xxxhdpi/infobar_blocked_popups.png Binary files differnew file mode 100644 index 00000000000..43e03065686 --- /dev/null +++ b/chromium/components/blocked_content/android/res/drawable-xxxhdpi/infobar_blocked_popups.png |