Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Side by Side Diff: chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc

Issue 2474783002: Fix memory leak for extension uninstall dialog. (Closed)
Patch Set: Add test coverage. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <memory> 5 #include <memory>
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 26 matching lines...) Expand all
37 class ExtensionUninstallDialogViews 37 class ExtensionUninstallDialogViews
38 : public extensions::ExtensionUninstallDialog { 38 : public extensions::ExtensionUninstallDialog {
39 public: 39 public:
40 ExtensionUninstallDialogViews( 40 ExtensionUninstallDialogViews(
41 Profile* profile, 41 Profile* profile,
42 gfx::NativeWindow parent, 42 gfx::NativeWindow parent,
43 extensions::ExtensionUninstallDialog::Delegate* delegate); 43 extensions::ExtensionUninstallDialog::Delegate* delegate);
44 ~ExtensionUninstallDialogViews() override; 44 ~ExtensionUninstallDialogViews() override;
45 45
46 // Called when the ExtensionUninstallDialogDelegate has been destroyed to make 46 // Called when the ExtensionUninstallDialogDelegate has been destroyed to make
47 // sure we invalidate pointers. 47 // sure we invalidate pointers. This object will also be freed.
48 void DialogDelegateDestroyed() { view_ = NULL; } 48 void DialogDelegateDestroyed();
49 49
50 // Forwards the accept and cancels to the delegate. 50 // Forwards the accept and cancels to the delegate.
51 void DialogAccepted(bool handle_report_abuse); 51 void DialogAccepted(bool handle_report_abuse);
52 void DialogCanceled(); 52 void DialogCanceled();
53 53
54 private: 54 private:
55 void Show() override; 55 void Show() override;
56 56
57 ExtensionUninstallDialogDelegateView* view_; 57 ExtensionUninstallDialogDelegateView* view_;
58 58
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 112
113 ExtensionUninstallDialogViews::ExtensionUninstallDialogViews( 113 ExtensionUninstallDialogViews::ExtensionUninstallDialogViews(
114 Profile* profile, 114 Profile* profile,
115 gfx::NativeWindow parent, 115 gfx::NativeWindow parent,
116 extensions::ExtensionUninstallDialog::Delegate* delegate) 116 extensions::ExtensionUninstallDialog::Delegate* delegate)
117 : extensions::ExtensionUninstallDialog(profile, delegate), 117 : extensions::ExtensionUninstallDialog(profile, delegate),
118 view_(NULL), 118 view_(NULL),
119 parent_(parent) { 119 parent_(parent) {
120 if (parent_) 120 if (parent_)
121 parent_window_tracker_ = NativeWindowTracker::Create(parent_); 121 parent_window_tracker_ = NativeWindowTracker::Create(parent_);
122 LOG(ERROR) << this << " Dialog Created";
122 } 123 }
123 124
124 ExtensionUninstallDialogViews::~ExtensionUninstallDialogViews() { 125 ExtensionUninstallDialogViews::~ExtensionUninstallDialogViews() {
125 // Close the widget (the views framework will delete view_). 126 // Close the widget (the views framework will delete view_).
126 if (view_) { 127 if (view_) {
127 view_->DialogDestroyed(); 128 view_->DialogDestroyed();
128 view_->GetWidget()->CloseNow(); 129 view_->GetWidget()->CloseNow();
129 } 130 }
131 LOG(ERROR) << this << " Dialog Died";
130 } 132 }
131 133
132 void ExtensionUninstallDialogViews::Show() { 134 void ExtensionUninstallDialogViews::Show() {
133 if (parent_ && parent_window_tracker_->WasNativeWindowClosed()) { 135 if (parent_ && parent_window_tracker_->WasNativeWindowClosed()) {
134 OnDialogClosed(CLOSE_ACTION_CANCELED); 136 OnDialogClosed(CLOSE_ACTION_CANCELED);
135 return; 137 return;
136 } 138 }
137 139
138 view_ = new ExtensionUninstallDialogDelegateView( 140 view_ = new ExtensionUninstallDialogDelegateView(
139 this, triggering_extension() != nullptr, &icon()); 141 this, triggering_extension() != nullptr, &icon());
140 constrained_window::CreateBrowserModalDialogViews(view_, parent_)->Show(); 142 constrained_window::CreateBrowserModalDialogViews(view_, parent_)->Show();
141 } 143 }
142 144
145 void ExtensionUninstallDialogViews::DialogDelegateDestroyed() {
146 view_ = NULL;
147 OnDialogClosed(CLOSE_ACTION_CANCELED);
Devlin 2016/11/05 06:26:18 It seems like there's a potential that this could
lgcheng 2016/11/10 21:39:51 Thanks for pointing out the potential issue. But a
148 }
149
143 void ExtensionUninstallDialogViews::DialogAccepted(bool report_abuse_checked) { 150 void ExtensionUninstallDialogViews::DialogAccepted(bool report_abuse_checked) {
144 // The widget gets destroyed when the dialog is accepted. 151 // The widget gets destroyed when the dialog is accepted.
145 view_->DialogDestroyed(); 152 view_->DialogDestroyed();
146 view_ = nullptr; 153 view_ = nullptr;
147 OnDialogClosed(report_abuse_checked ? 154 OnDialogClosed(report_abuse_checked ?
148 CLOSE_ACTION_UNINSTALL_AND_REPORT_ABUSE : CLOSE_ACTION_UNINSTALL); 155 CLOSE_ACTION_UNINSTALL_AND_REPORT_ABUSE : CLOSE_ACTION_UNINSTALL);
149 } 156 }
150 157
151 void ExtensionUninstallDialogViews::DialogCanceled() { 158 void ExtensionUninstallDialogViews::DialogCanceled() {
152 // The widget gets destroyed when the dialog is canceled. 159 // The widget gets destroyed when the dialog is canceled.
(...skipping 16 matching lines...) Expand all
169 icon_ = new views::ImageView(); 176 icon_ = new views::ImageView();
170 icon_->SetImageSize(size); 177 icon_->SetImageSize(size);
171 icon_->SetImage(*image); 178 icon_->SetImage(*image);
172 AddChildView(icon_); 179 AddChildView(icon_);
173 180
174 heading_ = new views::Label(base::UTF8ToUTF16(dialog_->GetHeadingText())); 181 heading_ = new views::Label(base::UTF8ToUTF16(dialog_->GetHeadingText()));
175 heading_->SetMultiLine(true); 182 heading_->SetMultiLine(true);
176 heading_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 183 heading_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
177 heading_->SetAllowCharacterBreak(true); 184 heading_->SetAllowCharacterBreak(true);
178 AddChildView(heading_); 185 AddChildView(heading_);
186 LOG(ERROR) << this << " Dialog View Created";
179 } 187 }
180 188
181 ExtensionUninstallDialogDelegateView::~ExtensionUninstallDialogDelegateView() { 189 ExtensionUninstallDialogDelegateView::~ExtensionUninstallDialogDelegateView() {
182 // If we're here, 2 things could have happened. Either the user closed the 190 // If we're here, 2 things could have happened. Either the user closed the
183 // dialog nicely and one of the installed/canceled methods has been called 191 // dialog nicely and one of the installed/canceled methods has been called
184 // (in which case dialog_ will be null), *or* neither of them have been 192 // (in which case dialog_ will be null), *or* neither of them have been
185 // called and we are being forced closed by our parent widget. In this case, 193 // called and we are being forced closed by our parent widget. In this case,
186 // we need to make sure to notify dialog_ not to call us again, since we're 194 // we need to make sure to notify dialog_ not to call us again, since we're
187 // about to be freed by the Widget framework. 195 // about to be freed by the Widget framework.
188 if (dialog_) 196 if (dialog_)
189 dialog_->DialogDelegateDestroyed(); 197 dialog_->DialogDelegateDestroyed();
198 LOG(ERROR) << this << " Dialog View Died";
190 } 199 }
191 200
192 views::View* ExtensionUninstallDialogDelegateView::CreateExtraView() { 201 views::View* ExtensionUninstallDialogDelegateView::CreateExtraView() {
193 if (dialog_->ShouldShowReportAbuseCheckbox()) { 202 if (dialog_->ShouldShowReportAbuseCheckbox()) {
194 report_abuse_checkbox_ = new views::Checkbox( 203 report_abuse_checkbox_ = new views::Checkbox(
195 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_UNINSTALL_REPORT_ABUSE)); 204 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_UNINSTALL_REPORT_ABUSE));
196 } 205 }
197 return report_abuse_checkbox_; 206 return report_abuse_checkbox_;
198 } 207 }
199 208
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 278
270 } // namespace 279 } // namespace
271 280
272 // static 281 // static
273 extensions::ExtensionUninstallDialog* 282 extensions::ExtensionUninstallDialog*
274 extensions::ExtensionUninstallDialog::Create(Profile* profile, 283 extensions::ExtensionUninstallDialog::Create(Profile* profile,
275 gfx::NativeWindow parent, 284 gfx::NativeWindow parent,
276 Delegate* delegate) { 285 Delegate* delegate) {
277 return new ExtensionUninstallDialogViews(profile, parent, delegate); 286 return new ExtensionUninstallDialogViews(profile, parent, delegate);
278 } 287 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698