Commit e3da3b00 authored by Charlie Harrison's avatar Charlie Harrison Committed by Commit Bot

ContentSettingBubbleModel: ensure destruction on WebContentsDestroyed

ContentSettingBubbleContents owns the underlying bubble model. It is
also a WebContentsObserver. This CL destroys the bubble model in
WebContentsDestroyed, which allows the model to avoid paranoid
null checking throughout the code.

In the process, we also remove:
1. Notification observation about profile / web contents destruction.
   The profile should be alive as long as the web contents.

2. Storing the profile directly and accessing the raw ptr. Instead,
   just pull it off the web contents.

One subtle thing about this patch. On WebContentsDestroyed, we do not
synchronously destroy the underlying ContentSettingBubbleContents,
instead, we synchronously hide it and post a task which actually
deletes it. This means we need to be careful about properly null
checking the content_setting_bubble_model_. Thankfully, we can assume
that event listeners are not invoked on hidden widgets.

Bug: None
Change-Id: I0a1ff38a705ace8a9898a4c89f81d51d8474b4da
Reviewed-on: https://chromium-review.googlesource.com/c/1334097
Commit-Queue: Charlie Harrison <csharrison@chromium.org>
Reviewed-by: default avatarBalazs Engedy <engedy@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarRobert Liao <robliao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610852}
parent 6b8f64da
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
#include "chrome/common/custom_handlers/protocol_handler.h" #include "chrome/common/custom_handlers/protocol_handler.h"
#include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h" #include "components/content_settings/core/common/content_settings_types.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/common/media_stream_request.h" #include "content/public/common/media_stream_request.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -67,7 +65,7 @@ class ContentSettingFramebustBlockBubbleModel; ...@@ -67,7 +65,7 @@ class ContentSettingFramebustBlockBubbleModel;
// This model provides data for ContentSettingBubble, and also controls // This model provides data for ContentSettingBubble, and also controls
// the action triggered when the allow / block radio buttons are triggered. // the action triggered when the allow / block radio buttons are triggered.
class ContentSettingBubbleModel : public content::NotificationObserver { class ContentSettingBubbleModel {
public: public:
typedef ContentSettingBubbleModelDelegate Delegate; typedef ContentSettingBubbleModelDelegate Delegate;
...@@ -167,20 +165,14 @@ class ContentSettingBubbleModel : public content::NotificationObserver { ...@@ -167,20 +165,14 @@ class ContentSettingBubbleModel : public content::NotificationObserver {
static std::unique_ptr<ContentSettingBubbleModel> static std::unique_ptr<ContentSettingBubbleModel>
CreateContentSettingBubbleModel(Delegate* delegate, CreateContentSettingBubbleModel(Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents,
Profile* profile,
ContentSettingsType content_type); ContentSettingsType content_type);
~ContentSettingBubbleModel() override; virtual ~ContentSettingBubbleModel();
const BubbleContent& bubble_content() const { return bubble_content_; } const BubbleContent& bubble_content() const { return bubble_content_; }
void set_owner(Owner* owner) { owner_ = owner; } void set_owner(Owner* owner) { owner_ = owner; }
// content::NotificationObserver:
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
virtual void OnListItemClicked(int index, int event_flags) {} virtual void OnListItemClicked(int index, int event_flags) {}
virtual void OnCustomLinkClicked() {} virtual void OnCustomLinkClicked() {}
virtual void OnManageButtonClicked() {} virtual void OnManageButtonClicked() {}
...@@ -221,13 +213,13 @@ class ContentSettingBubbleModel : public content::NotificationObserver { ...@@ -221,13 +213,13 @@ class ContentSettingBubbleModel : public content::NotificationObserver {
} }
protected: protected:
ContentSettingBubbleModel( // |web_contents| must outlive this.
Delegate* delegate, ContentSettingBubbleModel(Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents);
Profile* profile);
// Should always be non-nullptr.
content::WebContents* web_contents() const { return web_contents_; } content::WebContents* web_contents() const { return web_contents_; }
Profile* profile() const { return profile_; } Profile* GetProfile() const;
Delegate* delegate() const { return delegate_; } Delegate* delegate() const { return delegate_; }
int selected_item() const { return owner_->GetSelectedRadioOption(); } int selected_item() const { return owner_->GetSelectedRadioOption(); }
...@@ -274,12 +266,9 @@ class ContentSettingBubbleModel : public content::NotificationObserver { ...@@ -274,12 +266,9 @@ class ContentSettingBubbleModel : public content::NotificationObserver {
private: private:
content::WebContents* web_contents_; content::WebContents* web_contents_;
Profile* profile_;
Owner* owner_; Owner* owner_;
Delegate* delegate_; Delegate* delegate_;
BubbleContent bubble_content_; BubbleContent bubble_content_;
// A registrar for listening for WEB_CONTENTS_DESTROYED notifications.
content::NotificationRegistrar registrar_;
// The service used to record Rappor metrics. Can be set for testing. // The service used to record Rappor metrics. Can be set for testing.
rappor::RapporServiceImpl* rappor_service_; rappor::RapporServiceImpl* rappor_service_;
...@@ -291,7 +280,6 @@ class ContentSettingSimpleBubbleModel : public ContentSettingBubbleModel { ...@@ -291,7 +280,6 @@ class ContentSettingSimpleBubbleModel : public ContentSettingBubbleModel {
public: public:
ContentSettingSimpleBubbleModel(Delegate* delegate, ContentSettingSimpleBubbleModel(Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents,
Profile* profile,
ContentSettingsType content_type); ContentSettingsType content_type);
ContentSettingsType content_type() { return content_type_; } ContentSettingsType content_type() { return content_type_; }
...@@ -320,7 +308,6 @@ class ContentSettingRPHBubbleModel : public ContentSettingSimpleBubbleModel { ...@@ -320,7 +308,6 @@ class ContentSettingRPHBubbleModel : public ContentSettingSimpleBubbleModel {
public: public:
ContentSettingRPHBubbleModel(Delegate* delegate, ContentSettingRPHBubbleModel(Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents,
Profile* profile,
ProtocolHandlerRegistry* registry); ProtocolHandlerRegistry* registry);
~ContentSettingRPHBubbleModel() override; ~ContentSettingRPHBubbleModel() override;
...@@ -345,8 +332,7 @@ class ContentSettingRPHBubbleModel : public ContentSettingSimpleBubbleModel { ...@@ -345,8 +332,7 @@ class ContentSettingRPHBubbleModel : public ContentSettingSimpleBubbleModel {
class ContentSettingMediaStreamBubbleModel : public ContentSettingBubbleModel { class ContentSettingMediaStreamBubbleModel : public ContentSettingBubbleModel {
public: public:
ContentSettingMediaStreamBubbleModel(Delegate* delegate, ContentSettingMediaStreamBubbleModel(Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents);
Profile* profile);
~ContentSettingMediaStreamBubbleModel() override; ~ContentSettingMediaStreamBubbleModel() override;
...@@ -402,9 +388,9 @@ class ContentSettingMediaStreamBubbleModel : public ContentSettingBubbleModel { ...@@ -402,9 +388,9 @@ class ContentSettingMediaStreamBubbleModel : public ContentSettingBubbleModel {
class ContentSettingSubresourceFilterBubbleModel class ContentSettingSubresourceFilterBubbleModel
: public ContentSettingBubbleModel { : public ContentSettingBubbleModel {
public: public:
ContentSettingSubresourceFilterBubbleModel(Delegate* delegate, ContentSettingSubresourceFilterBubbleModel(
content::WebContents* web_contents, Delegate* delegate,
Profile* profile); content::WebContents* web_contents);
~ContentSettingSubresourceFilterBubbleModel() override; ~ContentSettingSubresourceFilterBubbleModel() override;
...@@ -429,8 +415,7 @@ class ContentSettingSubresourceFilterBubbleModel ...@@ -429,8 +415,7 @@ class ContentSettingSubresourceFilterBubbleModel
class ContentSettingDownloadsBubbleModel : public ContentSettingBubbleModel { class ContentSettingDownloadsBubbleModel : public ContentSettingBubbleModel {
public: public:
ContentSettingDownloadsBubbleModel(Delegate* delegate, ContentSettingDownloadsBubbleModel(Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents);
Profile* profile);
~ContentSettingDownloadsBubbleModel() override; ~ContentSettingDownloadsBubbleModel() override;
// ContentSettingBubbleModel overrides: // ContentSettingBubbleModel overrides:
...@@ -452,7 +437,6 @@ class ContentSettingSingleRadioGroup : public ContentSettingSimpleBubbleModel { ...@@ -452,7 +437,6 @@ class ContentSettingSingleRadioGroup : public ContentSettingSimpleBubbleModel {
public: public:
ContentSettingSingleRadioGroup(Delegate* delegate, ContentSettingSingleRadioGroup(Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents,
Profile* profile,
ContentSettingsType content_type); ContentSettingsType content_type);
~ContentSettingSingleRadioGroup() override; ~ContentSettingSingleRadioGroup() override;
...@@ -482,16 +466,10 @@ class ContentSettingFramebustBlockBubbleModel ...@@ -482,16 +466,10 @@ class ContentSettingFramebustBlockBubbleModel
public UrlListManager::Observer { public UrlListManager::Observer {
public: public:
ContentSettingFramebustBlockBubbleModel(Delegate* delegate, ContentSettingFramebustBlockBubbleModel(Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents);
Profile* profile);
~ContentSettingFramebustBlockBubbleModel() override; ~ContentSettingFramebustBlockBubbleModel() override;
// content::NotificationObserver:
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// ContentSettingBubbleModel: // ContentSettingBubbleModel:
void OnListItemClicked(int index, int event_flags) override; void OnListItemClicked(int index, int event_flags) override;
ContentSettingFramebustBlockBubbleModel* AsFramebustBlockBubbleModel() ContentSettingFramebustBlockBubbleModel* AsFramebustBlockBubbleModel()
......
...@@ -68,7 +68,7 @@ IN_PROC_BROWSER_TEST_F(ContentSettingBubbleModelMixedScriptTest, MainFrame) { ...@@ -68,7 +68,7 @@ IN_PROC_BROWSER_TEST_F(ContentSettingBubbleModelMixedScriptTest, MainFrame) {
ContentSettingBubbleModel::CreateContentSettingBubbleModel( ContentSettingBubbleModel::CreateContentSettingBubbleModel(
browser()->content_setting_bubble_model_delegate(), browser()->content_setting_bubble_model_delegate(),
browser()->tab_strip_model()->GetActiveWebContents(), browser()->tab_strip_model()->GetActiveWebContents(),
browser()->profile(), CONTENT_SETTINGS_TYPE_MIXEDSCRIPT)); CONTENT_SETTINGS_TYPE_MIXEDSCRIPT));
model->OnCustomLinkClicked(); model->OnCustomLinkClicked();
// Wait for reload // Wait for reload
...@@ -128,7 +128,7 @@ IN_PROC_BROWSER_TEST_F(ContentSettingsMixedScriptIgnoreCertErrorsTest, ...@@ -128,7 +128,7 @@ IN_PROC_BROWSER_TEST_F(ContentSettingsMixedScriptIgnoreCertErrorsTest,
ContentSettingBubbleModel::CreateContentSettingBubbleModel( ContentSettingBubbleModel::CreateContentSettingBubbleModel(
browser()->content_setting_bubble_model_delegate(), browser()->content_setting_bubble_model_delegate(),
browser()->tab_strip_model()->GetActiveWebContents(), browser()->tab_strip_model()->GetActiveWebContents(),
browser()->profile(), CONTENT_SETTINGS_TYPE_MIXEDSCRIPT)); CONTENT_SETTINGS_TYPE_MIXEDSCRIPT));
model->SetRapporServiceImplForTesting(&rappor_service); model->SetRapporServiceImplForTesting(&rappor_service);
model->OnCustomLinkClicked(); model->OnCustomLinkClicked();
...@@ -187,8 +187,7 @@ class ContentSettingBubbleModelMediaStreamTest : public InProcessBrowserTest { ...@@ -187,8 +187,7 @@ class ContentSettingBubbleModelMediaStreamTest : public InProcessBrowserTest {
state, std::string(), std::string(), std::string(), std::string()); state, std::string(), std::string(), std::string(), std::string());
std::unique_ptr<ContentSettingBubbleModel> bubble( std::unique_ptr<ContentSettingBubbleModel> bubble(
new ContentSettingMediaStreamBubbleModel( new ContentSettingMediaStreamBubbleModel(
browser()->content_setting_bubble_model_delegate(), original_tab, browser()->content_setting_bubble_model_delegate(), original_tab));
browser()->profile()));
// Click the manage button, which opens in a new tab or window. Wait until // Click the manage button, which opens in a new tab or window. Wait until
// it loads. // it loads.
...@@ -264,7 +263,7 @@ IN_PROC_BROWSER_TEST_F(ContentSettingBubbleModelPopupTest, ...@@ -264,7 +263,7 @@ IN_PROC_BROWSER_TEST_F(ContentSettingBubbleModelPopupTest,
ContentSettingBubbleModel::CreateContentSettingBubbleModel( ContentSettingBubbleModel::CreateContentSettingBubbleModel(
browser()->content_setting_bubble_model_delegate(), browser()->content_setting_bubble_model_delegate(),
browser()->tab_strip_model()->GetActiveWebContents(), browser()->tab_strip_model()->GetActiveWebContents(),
browser()->profile(), CONTENT_SETTINGS_TYPE_POPUPS)); CONTENT_SETTINGS_TYPE_POPUPS));
std::unique_ptr<FakeOwner> owner = std::unique_ptr<FakeOwner> owner =
FakeOwner::Create(*model, kDisallowButtonIndex); FakeOwner::Create(*model, kDisallowButtonIndex);
...@@ -341,7 +340,7 @@ IN_PROC_BROWSER_TEST_F(ContentSettingBubbleModelMixedScriptOopifTest, ...@@ -341,7 +340,7 @@ IN_PROC_BROWSER_TEST_F(ContentSettingBubbleModelMixedScriptOopifTest,
std::unique_ptr<ContentSettingBubbleModel> model( std::unique_ptr<ContentSettingBubbleModel> model(
ContentSettingBubbleModel::CreateContentSettingBubbleModel( ContentSettingBubbleModel::CreateContentSettingBubbleModel(
browser()->content_setting_bubble_model_delegate(), web_contents, browser()->content_setting_bubble_model_delegate(), web_contents,
browser()->profile(), CONTENT_SETTINGS_TYPE_MIXEDSCRIPT)); CONTENT_SETTINGS_TYPE_MIXEDSCRIPT));
model->OnCustomLinkClicked(); model->OnCustomLinkClicked();
// Wait for reload and verify that mixed content is allowed. // Wait for reload and verify that mixed content is allowed.
......
...@@ -126,8 +126,7 @@ class ContentSettingMediaImageModel : public ContentSettingImageModel { ...@@ -126,8 +126,7 @@ class ContentSettingMediaImageModel : public ContentSettingImageModel {
std::unique_ptr<ContentSettingBubbleModel> CreateBubbleModelImpl( std::unique_ptr<ContentSettingBubbleModel> CreateBubbleModelImpl(
ContentSettingBubbleModel::Delegate* delegate, ContentSettingBubbleModel::Delegate* delegate,
WebContents* web_contents, WebContents* web_contents) override;
Profile* profile) override;
private: private:
DISALLOW_COPY_AND_ASSIGN(ContentSettingMediaImageModel); DISALLOW_COPY_AND_ASSIGN(ContentSettingMediaImageModel);
...@@ -215,13 +214,9 @@ ContentSettingSimpleImageModel::ContentSettingSimpleImageModel( ...@@ -215,13 +214,9 @@ ContentSettingSimpleImageModel::ContentSettingSimpleImageModel(
std::unique_ptr<ContentSettingBubbleModel> std::unique_ptr<ContentSettingBubbleModel>
ContentSettingSimpleImageModel::CreateBubbleModelImpl( ContentSettingSimpleImageModel::CreateBubbleModelImpl(
ContentSettingBubbleModel::Delegate* delegate, ContentSettingBubbleModel::Delegate* delegate,
WebContents* web_contents, WebContents* web_contents) {
Profile* profile) {
return ContentSettingBubbleModel::CreateContentSettingBubbleModel( return ContentSettingBubbleModel::CreateContentSettingBubbleModel(
delegate, delegate, web_contents, content_type());
web_contents,
profile,
content_type());
} }
// static // static
...@@ -548,10 +543,9 @@ bool ContentSettingMediaImageModel::UpdateAndGetVisibility( ...@@ -548,10 +543,9 @@ bool ContentSettingMediaImageModel::UpdateAndGetVisibility(
std::unique_ptr<ContentSettingBubbleModel> std::unique_ptr<ContentSettingBubbleModel>
ContentSettingMediaImageModel::CreateBubbleModelImpl( ContentSettingMediaImageModel::CreateBubbleModelImpl(
ContentSettingBubbleModel::Delegate* delegate, ContentSettingBubbleModel::Delegate* delegate,
WebContents* web_contents, WebContents* web_contents) {
Profile* profile) { return std::make_unique<ContentSettingMediaStreamBubbleModel>(delegate,
return std::make_unique<ContentSettingMediaStreamBubbleModel>( web_contents);
delegate, web_contents, profile);
} }
// Blocked Framebust ----------------------------------------------------------- // Blocked Framebust -----------------------------------------------------------
...@@ -573,10 +567,9 @@ bool ContentSettingFramebustBlockImageModel::UpdateAndGetVisibility( ...@@ -573,10 +567,9 @@ bool ContentSettingFramebustBlockImageModel::UpdateAndGetVisibility(
std::unique_ptr<ContentSettingBubbleModel> std::unique_ptr<ContentSettingBubbleModel>
ContentSettingFramebustBlockImageModel::CreateBubbleModelImpl( ContentSettingFramebustBlockImageModel::CreateBubbleModelImpl(
ContentSettingBubbleModel::Delegate* delegate, ContentSettingBubbleModel::Delegate* delegate,
WebContents* web_contents, WebContents* web_contents) {
Profile* profile) {
return std::make_unique<ContentSettingFramebustBlockBubbleModel>( return std::make_unique<ContentSettingFramebustBlockBubbleModel>(
delegate, web_contents, profile); delegate, web_contents);
} }
// Sensors --------------------------------------------------------------------- // Sensors ---------------------------------------------------------------------
...@@ -639,12 +632,12 @@ ContentSettingImageModel::ContentSettingImageModel(ImageType image_type) ...@@ -639,12 +632,12 @@ ContentSettingImageModel::ContentSettingImageModel(ImageType image_type)
std::unique_ptr<ContentSettingBubbleModel> std::unique_ptr<ContentSettingBubbleModel>
ContentSettingImageModel::CreateBubbleModel( ContentSettingImageModel::CreateBubbleModel(
ContentSettingBubbleModel::Delegate* delegate, ContentSettingBubbleModel::Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents) {
Profile* profile) { DCHECK(web_contents);
UMA_HISTOGRAM_ENUMERATION( UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.ImagePressed", image_type(), "ContentSettings.ImagePressed", image_type(),
ContentSettingImageModel::ImageType::NUM_IMAGE_TYPES); ContentSettingImageModel::ImageType::NUM_IMAGE_TYPES);
return CreateBubbleModelImpl(delegate, web_contents, profile); return CreateBubbleModelImpl(delegate, web_contents);
} }
// static // static
......
...@@ -72,8 +72,7 @@ class ContentSettingImageModel { ...@@ -72,8 +72,7 @@ class ContentSettingImageModel {
// Creates the model for the bubble that will be attached to this image. // Creates the model for the bubble that will be attached to this image.
std::unique_ptr<ContentSettingBubbleModel> CreateBubbleModel( std::unique_ptr<ContentSettingBubbleModel> CreateBubbleModel(
ContentSettingBubbleModel::Delegate* delegate, ContentSettingBubbleModel::Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents);
Profile* profile);
// Whether the animation should be run for the given |web_contents|. // Whether the animation should be run for the given |web_contents|.
bool ShouldRunAnimation(content::WebContents* web_contents); bool ShouldRunAnimation(content::WebContents* web_contents);
...@@ -106,8 +105,7 @@ class ContentSettingImageModel { ...@@ -106,8 +105,7 @@ class ContentSettingImageModel {
// Internal implementation by subclasses of bubble model creation. // Internal implementation by subclasses of bubble model creation.
virtual std::unique_ptr<ContentSettingBubbleModel> CreateBubbleModelImpl( virtual std::unique_ptr<ContentSettingBubbleModel> CreateBubbleModelImpl(
ContentSettingBubbleModel::Delegate* delegate, ContentSettingBubbleModel::Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents) = 0;
Profile* profile) = 0;
void set_icon(const gfx::VectorIcon& icon, const gfx::VectorIcon& badge) { void set_icon(const gfx::VectorIcon& icon, const gfx::VectorIcon& badge) {
icon_ = &icon; icon_ = &icon;
...@@ -140,8 +138,7 @@ class ContentSettingSimpleImageModel : public ContentSettingImageModel { ...@@ -140,8 +138,7 @@ class ContentSettingSimpleImageModel : public ContentSettingImageModel {
// ContentSettingImageModel implementation. // ContentSettingImageModel implementation.
std::unique_ptr<ContentSettingBubbleModel> CreateBubbleModelImpl( std::unique_ptr<ContentSettingBubbleModel> CreateBubbleModelImpl(
ContentSettingBubbleModel::Delegate* delegate, ContentSettingBubbleModel::Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents) override;
Profile* profile) override;
ContentSettingsType content_type() { return content_type_; } ContentSettingsType content_type() { return content_type_; }
...@@ -159,8 +156,7 @@ class ContentSettingFramebustBlockImageModel : public ContentSettingImageModel { ...@@ -159,8 +156,7 @@ class ContentSettingFramebustBlockImageModel : public ContentSettingImageModel {
std::unique_ptr<ContentSettingBubbleModel> CreateBubbleModelImpl( std::unique_ptr<ContentSettingBubbleModel> CreateBubbleModelImpl(
ContentSettingBubbleModel::Delegate* delegate, ContentSettingBubbleModel::Delegate* delegate,
content::WebContents* web_contents, content::WebContents* web_contents) override;
Profile* profile) override;
private: private:
DISALLOW_COPY_AND_ASSIGN(ContentSettingFramebustBlockImageModel); DISALLOW_COPY_AND_ASSIGN(ContentSettingFramebustBlockImageModel);
......
...@@ -54,11 +54,10 @@ IN_PROC_BROWSER_TEST_F(ContentSettingImageModelBrowserTest, CreateBubbleModel) { ...@@ -54,11 +54,10 @@ IN_PROC_BROWSER_TEST_F(ContentSettingImageModelBrowserTest, CreateBubbleModel) {
ImageType::MIDI_SYSEX, ImageType::MIDI_SYSEX,
}; };
Profile* profile = browser()->profile();
for (auto type : content_settings_to_test) { for (auto type : content_settings_to_test) {
auto model = ContentSettingImageModel::CreateForContentType(type); auto model = ContentSettingImageModel::CreateForContentType(type);
std::unique_ptr<ContentSettingBubbleModel> bubble( std::unique_ptr<ContentSettingBubbleModel> bubble(
model->CreateBubbleModel(nullptr, web_contents, profile)); model->CreateBubbleModel(nullptr, web_contents));
// All of the above content settings should create a // All of the above content settings should create a
// ContentSettingSimpleBubbleModel that is tied to a particular setting, // ContentSettingSimpleBubbleModel that is tied to a particular setting,
...@@ -78,7 +77,7 @@ IN_PROC_BROWSER_TEST_F(ContentSettingImageModelBrowserTest, CreateBubbleModel) { ...@@ -78,7 +77,7 @@ IN_PROC_BROWSER_TEST_F(ContentSettingImageModelBrowserTest, CreateBubbleModel) {
std::vector<std::unique_ptr<ContentSettingImageModel>> models = std::vector<std::unique_ptr<ContentSettingImageModel>> models =
ContentSettingImageModel::GenerateContentSettingImageModels(); ContentSettingImageModel::GenerateContentSettingImageModels();
for (auto& model : models) { for (auto& model : models) {
EXPECT_TRUE(model->CreateBubbleModel(nullptr, web_contents, profile)); EXPECT_TRUE(model->CreateBubbleModel(nullptr, web_contents));
EXPECT_TRUE(image_types.insert(model->image_type()).second); EXPECT_TRUE(image_types.insert(model->image_type()).second);
} }
} }
...@@ -116,10 +115,8 @@ IN_PROC_BROWSER_TEST_F(ContentSettingImageModelBrowserTest, ...@@ -116,10 +115,8 @@ IN_PROC_BROWSER_TEST_F(ContentSettingImageModelBrowserTest,
browser()->tab_strip_model()->GetActiveWebContents(); browser()->tab_strip_model()->GetActiveWebContents();
auto model = ContentSettingImageModel::CreateForContentType(ImageType::ADS); auto model = ContentSettingImageModel::CreateForContentType(ImageType::ADS);
Profile* profile = browser()->profile();
std::unique_ptr<ContentSettingBubbleModel> bubble(model->CreateBubbleModel( std::unique_ptr<ContentSettingBubbleModel> bubble(model->CreateBubbleModel(
browser()->content_setting_bubble_model_delegate(), web_contents, browser()->content_setting_bubble_model_delegate(), web_contents));
profile));
content::TestNavigationObserver observer(nullptr); content::TestNavigationObserver observer(nullptr);
observer.StartWatchingNewWebContents(); observer.StartWatchingNewWebContents();
......
...@@ -128,8 +128,7 @@ IN_PROC_BROWSER_TEST_F(FramebustBlockBrowserTest, ModelAllowsRedirection) { ...@@ -128,8 +128,7 @@ IN_PROC_BROWSER_TEST_F(FramebustBlockBrowserTest, ModelAllowsRedirection) {
// Simulate clicking on the second blocked URL. // Simulate clicking on the second blocked URL.
ContentSettingFramebustBlockBubbleModel framebust_block_bubble_model( ContentSettingFramebustBlockBubbleModel framebust_block_bubble_model(
browser()->content_setting_bubble_model_delegate(), GetWebContents(), browser()->content_setting_bubble_model_delegate(), GetWebContents());
browser()->profile());
EXPECT_FALSE(clicked_index_.has_value()); EXPECT_FALSE(clicked_index_.has_value());
EXPECT_FALSE(clicked_url_.has_value()); EXPECT_FALSE(clicked_url_.has_value());
...@@ -166,8 +165,7 @@ IN_PROC_BROWSER_TEST_F(FramebustBlockBrowserTest, AllowRadioButtonSelected) { ...@@ -166,8 +165,7 @@ IN_PROC_BROWSER_TEST_F(FramebustBlockBrowserTest, AllowRadioButtonSelected) {
// Create a content bubble and simulate clicking on the first radio button // Create a content bubble and simulate clicking on the first radio button
// before closing it. // before closing it.
ContentSettingFramebustBlockBubbleModel framebust_block_bubble_model( ContentSettingFramebustBlockBubbleModel framebust_block_bubble_model(
browser()->content_setting_bubble_model_delegate(), GetWebContents(), browser()->content_setting_bubble_model_delegate(), GetWebContents());
browser()->profile());
std::unique_ptr<FakeOwner> owner = FakeOwner::Create( std::unique_ptr<FakeOwner> owner = FakeOwner::Create(
framebust_block_bubble_model, kDisallowRadioButtonIndex); framebust_block_bubble_model, kDisallowRadioButtonIndex);
...@@ -197,8 +195,7 @@ IN_PROC_BROWSER_TEST_F(FramebustBlockBrowserTest, DisallowRadioButtonSelected) { ...@@ -197,8 +195,7 @@ IN_PROC_BROWSER_TEST_F(FramebustBlockBrowserTest, DisallowRadioButtonSelected) {
// Create a content bubble and simulate clicking on the second radio button // Create a content bubble and simulate clicking on the second radio button
// before closing it. // before closing it.
ContentSettingFramebustBlockBubbleModel framebust_block_bubble_model( ContentSettingFramebustBlockBubbleModel framebust_block_bubble_model(
browser()->content_setting_bubble_model_delegate(), GetWebContents(), browser()->content_setting_bubble_model_delegate(), GetWebContents());
browser()->profile());
std::unique_ptr<FakeOwner> owner = std::unique_ptr<FakeOwner> owner =
FakeOwner::Create(framebust_block_bubble_model, kAllowRadioButtonIndex); FakeOwner::Create(framebust_block_bubble_model, kAllowRadioButtonIndex);
...@@ -223,8 +220,7 @@ IN_PROC_BROWSER_TEST_F(FramebustBlockBrowserTest, ManageButtonClicked) { ...@@ -223,8 +220,7 @@ IN_PROC_BROWSER_TEST_F(FramebustBlockBrowserTest, ManageButtonClicked) {
// Create a content bubble and simulate clicking on the second radio button // Create a content bubble and simulate clicking on the second radio button
// before closing it. // before closing it.
ContentSettingFramebustBlockBubbleModel framebust_block_bubble_model( ContentSettingFramebustBlockBubbleModel framebust_block_bubble_model(
browser()->content_setting_bubble_model_delegate(), GetWebContents(), browser()->content_setting_bubble_model_delegate(), GetWebContents());
browser()->profile());
content::TestNavigationObserver navigation_observer(nullptr); content::TestNavigationObserver navigation_observer(nullptr);
navigation_observer.StartWatchingNewWebContents(); navigation_observer.StartWatchingNewWebContents();
......
...@@ -383,6 +383,7 @@ ContentSettingBubbleContents::~ContentSettingBubbleContents() { ...@@ -383,6 +383,7 @@ ContentSettingBubbleContents::~ContentSettingBubbleContents() {
} }
void ContentSettingBubbleContents::WindowClosing() { void ContentSettingBubbleContents::WindowClosing() {
if (content_setting_bubble_model_)
content_setting_bubble_model_->CommitChanges(); content_setting_bubble_model_->CommitChanges();
} }
...@@ -424,6 +425,8 @@ void ContentSettingBubbleContents::OnNativeThemeChanged( ...@@ -424,6 +425,8 @@ void ContentSettingBubbleContents::OnNativeThemeChanged(
} }
base::string16 ContentSettingBubbleContents::GetWindowTitle() const { base::string16 ContentSettingBubbleContents::GetWindowTitle() const {
if (!content_setting_bubble_model_)
return base::string16();
return content_setting_bubble_model_->bubble_content().title; return content_setting_bubble_model_->bubble_content().title;
} }
...@@ -432,6 +435,7 @@ bool ContentSettingBubbleContents::ShouldShowCloseButton() const { ...@@ -432,6 +435,7 @@ bool ContentSettingBubbleContents::ShouldShowCloseButton() const {
} }
void ContentSettingBubbleContents::Init() { void ContentSettingBubbleContents::Init() {
DCHECK(content_setting_bubble_model_);
const ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); const ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
SetLayoutManager(std::make_unique<views::BoxLayout>( SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::kVertical, gfx::Insets(), views::BoxLayout::kVertical, gfx::Insets(),
...@@ -537,6 +541,7 @@ void ContentSettingBubbleContents::Init() { ...@@ -537,6 +541,7 @@ void ContentSettingBubbleContents::Init() {
} }
views::View* ContentSettingBubbleContents::CreateExtraView() { views::View* ContentSettingBubbleContents::CreateExtraView() {
DCHECK(content_setting_bubble_model_);
const auto& bubble_content = content_setting_bubble_model_->bubble_content(); const auto& bubble_content = content_setting_bubble_model_->bubble_content();
const auto* layout = ChromeLayoutProvider::Get(); const auto* layout = ChromeLayoutProvider::Get();
std::vector<View*> extra_views; std::vector<View*> extra_views;
...@@ -589,6 +594,9 @@ int ContentSettingBubbleContents::GetDialogButtons() const { ...@@ -589,6 +594,9 @@ int ContentSettingBubbleContents::GetDialogButtons() const {
base::string16 ContentSettingBubbleContents::GetDialogButtonLabel( base::string16 ContentSettingBubbleContents::GetDialogButtonLabel(
ui::DialogButton button) const { ui::DialogButton button) const {
if (!content_setting_bubble_model_)
return base::string16();
const base::string16& done_text = const base::string16& done_text =
content_setting_bubble_model_->bubble_content().done_button_text; content_setting_bubble_model_->bubble_content().done_button_text;
return done_text.empty() ? l10n_util::GetStringUTF16(IDS_DONE) : done_text; return done_text.empty() ? l10n_util::GetStringUTF16(IDS_DONE) : done_text;
...@@ -620,11 +628,20 @@ void ContentSettingBubbleContents::OnVisibilityChanged( ...@@ -620,11 +628,20 @@ void ContentSettingBubbleContents::OnVisibilityChanged(
} }
void ContentSettingBubbleContents::WebContentsDestroyed() { void ContentSettingBubbleContents::WebContentsDestroyed() {
// Destroy the bubble model to ensure that the underlying WebContents outlives
// it.
content_setting_bubble_model_->CommitChanges();
content_setting_bubble_model_.reset();
// Closing the widget should synchronously hide it (and post a task to delete
// it). Subsequent event listener methods should not be invoked on hidden
// widgets.
GetWidget()->Close(); GetWidget()->Close();
} }
void ContentSettingBubbleContents::ButtonPressed(views::Button* sender, void ContentSettingBubbleContents::ButtonPressed(views::Button* sender,
const ui::Event& event) { const ui::Event& event) {
DCHECK(content_setting_bubble_model_);
if (sender == manage_checkbox_) { if (sender == manage_checkbox_) {
content_setting_bubble_model_->OnManageCheckboxChecked( content_setting_bubble_model_->OnManageCheckboxChecked(
manage_checkbox_->checked()); manage_checkbox_->checked());
...@@ -645,6 +662,7 @@ void ContentSettingBubbleContents::ButtonPressed(views::Button* sender, ...@@ -645,6 +662,7 @@ void ContentSettingBubbleContents::ButtonPressed(views::Button* sender,
void ContentSettingBubbleContents::LinkClicked(views::Link* source, void ContentSettingBubbleContents::LinkClicked(views::Link* source,
int event_flags) { int event_flags) {
DCHECK(content_setting_bubble_model_);
if (source == custom_link_) { if (source == custom_link_) {
content_setting_bubble_model_->OnCustomLinkClicked(); content_setting_bubble_model_->OnCustomLinkClicked();
GetWidget()->Close(); GetWidget()->Close();
...@@ -656,6 +674,7 @@ void ContentSettingBubbleContents::LinkClicked(views::Link* source, ...@@ -656,6 +674,7 @@ void ContentSettingBubbleContents::LinkClicked(views::Link* source,
} }
void ContentSettingBubbleContents::OnPerformAction(views::Combobox* combobox) { void ContentSettingBubbleContents::OnPerformAction(views::Combobox* combobox) {
DCHECK(content_setting_bubble_model_);
MediaComboboxModel* model = MediaComboboxModel* model =
static_cast<MediaComboboxModel*>(combobox->model()); static_cast<MediaComboboxModel*>(combobox->model());
content_setting_bubble_model_->OnMediaMenuClicked( content_setting_bubble_model_->OnMediaMenuClicked(
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <utility> #include <utility>
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
#include "chrome/browser/ui/content_settings/content_setting_image_model.h" #include "chrome/browser/ui/content_settings/content_setting_image_model.h"
...@@ -129,8 +128,7 @@ bool ContentSettingImageView::ShowBubble(const ui::Event& event) { ...@@ -129,8 +128,7 @@ bool ContentSettingImageView::ShowBubble(const ui::Event& event) {
views::View* const anchor = parent(); views::View* const anchor = parent();
bubble_view_ = new ContentSettingBubbleContents( bubble_view_ = new ContentSettingBubbleContents(
content_setting_image_model_->CreateBubbleModel( content_setting_image_model_->CreateBubbleModel(
delegate_->GetContentSettingBubbleModelDelegate(), web_contents, delegate_->GetContentSettingBubbleModelDelegate(), web_contents),
Profile::FromBrowserContext(web_contents->GetBrowserContext())),
web_contents, anchor, views::BubbleBorder::TOP_RIGHT); web_contents, anchor, views::BubbleBorder::TOP_RIGHT);
bubble_view_->SetHighlightedButton(this); bubble_view_->SetHighlightedButton(this);
views::Widget* bubble_widget = views::Widget* bubble_widget =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment