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

Side by Side Diff: chrome/browser/ui/views/select_file_dialog_extension.cc

Issue 9360005: Handle termination/crashes of an extension hosted in the ExtensionDialog. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review changes. Created 8 years, 10 months 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 | Annotate | Revision Log
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 "chrome/browser/ui/views/select_file_dialog_extension.h" 5 #include "chrome/browser/ui/views/select_file_dialog_extension.h"
6 6
7 #include "base/bind.h"
8 #include "base/callback.h"
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
9 #include "base/memory/singleton.h" 11 #include "base/memory/singleton.h"
12 #include "base/message_loop.h"
10 #include "chrome/browser/extensions/extension_file_browser_private_api.h" 13 #include "chrome/browser/extensions/extension_file_browser_private_api.h"
11 #include "chrome/browser/extensions/extension_host.h" 14 #include "chrome/browser/extensions/extension_host.h"
15 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/file_manager_util.h" 16 #include "chrome/browser/extensions/file_manager_util.h"
13 #include "chrome/browser/sessions/restore_tab_helper.h" 17 #include "chrome/browser/sessions/restore_tab_helper.h"
14 #include "chrome/browser/ui/browser.h" 18 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_list.h" 19 #include "chrome/browser/ui/browser_list.h"
16 #include "chrome/browser/ui/browser_window.h" 20 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 21 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
18 #include "chrome/browser/ui/views/extensions/extension_dialog.h" 22 #include "chrome/browser/ui/views/extensions/extension_dialog.h"
19 #include "chrome/browser/ui/views/window.h" 23 #include "chrome/browser/ui/views/window.h"
20 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
21 25
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 SelectFileDialogExtension* SelectFileDialogExtension::Create( 89 SelectFileDialogExtension* SelectFileDialogExtension::Create(
86 Listener* listener) { 90 Listener* listener) {
87 return new SelectFileDialogExtension(listener); 91 return new SelectFileDialogExtension(listener);
88 } 92 }
89 93
90 SelectFileDialogExtension::SelectFileDialogExtension(Listener* listener) 94 SelectFileDialogExtension::SelectFileDialogExtension(Listener* listener)
91 : SelectFileDialog(listener), 95 : SelectFileDialog(listener),
92 has_multiple_file_type_choices_(false), 96 has_multiple_file_type_choices_(false),
93 tab_id_(0), 97 tab_id_(0),
94 owner_window_(0), 98 owner_window_(0),
99 owner_browser_(0),
95 selection_type_(CANCEL), 100 selection_type_(CANCEL),
96 selection_index_(0), 101 selection_index_(0),
97 params_(NULL) { 102 params_(NULL) {
98 } 103 }
99 104
100 SelectFileDialogExtension::~SelectFileDialogExtension() { 105 SelectFileDialogExtension::~SelectFileDialogExtension() {
101 if (extension_dialog_) 106 if (extension_dialog_)
102 extension_dialog_->ObserverDestroyed(); 107 extension_dialog_->ObserverDestroyed();
103 } 108 }
104 109
105 bool SelectFileDialogExtension::IsRunning( 110 bool SelectFileDialogExtension::IsRunning(
106 gfx::NativeWindow owner_window) const { 111 gfx::NativeWindow owner_window) const {
107 return owner_window_ == owner_window; 112 return owner_window_ == owner_window;
108 } 113 }
109 114
110 void SelectFileDialogExtension::ListenerDestroyed() { 115 void SelectFileDialogExtension::ListenerDestroyed() {
111 listener_ = NULL; 116 listener_ = NULL;
112 params_ = NULL; 117 params_ = NULL;
113 PendingDialog::GetInstance()->Remove(tab_id_); 118 PendingDialog::GetInstance()->Remove(tab_id_);
114 } 119 }
115 120
116 void SelectFileDialogExtension::ExtensionDialogClosing( 121 void SelectFileDialogExtension::ExtensionDialogClosing(
117 ExtensionDialog* dialog) { 122 ExtensionDialog* dialog) {
123 owner_browser_ = NULL;
118 owner_window_ = NULL; 124 owner_window_ = NULL;
119 // Release our reference to the dialog to allow it to close. 125 // Release our reference to the dialog to allow it to close.
120 extension_dialog_ = NULL; 126 extension_dialog_ = NULL;
121 PendingDialog::GetInstance()->Remove(tab_id_); 127 PendingDialog::GetInstance()->Remove(tab_id_);
122 // Actually invoke the appropriate callback on our listener. 128 // Actually invoke the appropriate callback on our listener.
123 NotifyListener(); 129 NotifyListener();
124 } 130 }
125 131
132 void SelectFileDialogExtension::ExtensionDialogTerminated(
Aaron Boodman 2012/02/09 20:23:23 Why do we need this bit? From looking at the curre
rkc 2012/02/10 00:35:42 So we need to at least close the dialog window, wh
Yoyo Zhou 2012/02/10 00:45:28 Does it work without using PostTask? This seems so
133 ExtensionDialog* dialog) {
134 LOG(ERROR) << "Select File Dialog Extension crashed.";
135
136 // The extension would have been unloaded because of the termination,
137 // reload it.
138 std::string extension_id = dialog->host()->extension()->id();
139 // Reload the extension after a bit; the extension may not have been unloaded
140 // yet. We don't want to try to reload the extension only to have the Unload
141 // code execute after us and re-unload the extension.
142 if (owner_browser_) {
143 MessageLoop::current()->PostTask(
144 FROM_HERE,
145 base::Bind(
146 &ExtensionService::ReloadExtension,
147 base::Unretained(owner_browser_->profile()->
148 GetExtensionService()),
149 extension_id));
150 }
151
152 dialog->Close();
153 }
154
126 // static 155 // static
127 void SelectFileDialogExtension::OnFileSelected( 156 void SelectFileDialogExtension::OnFileSelected(
128 int32 tab_id, const FilePath& path, int index) { 157 int32 tab_id, const FilePath& path, int index) {
129 scoped_refptr<SelectFileDialogExtension> dialog = 158 scoped_refptr<SelectFileDialogExtension> dialog =
130 PendingDialog::GetInstance()->Find(tab_id); 159 PendingDialog::GetInstance()->Find(tab_id);
131 if (!dialog) 160 if (!dialog)
132 return; 161 return;
133 dialog->selection_type_ = SINGLE_FILE; 162 dialog->selection_type_ = SINGLE_FILE;
134 dialog->selection_files_.clear(); 163 dialog->selection_files_.clear();
135 dialog->selection_files_.push_back(path); 164 dialog->selection_files_.push_back(path);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 const FileTypeInfo* file_types, 233 const FileTypeInfo* file_types,
205 int file_type_index, 234 int file_type_index,
206 const FilePath::StringType& default_extension, 235 const FilePath::StringType& default_extension,
207 gfx::NativeWindow owner_window, 236 gfx::NativeWindow owner_window,
208 void* params) { 237 void* params) {
209 if (owner_window_) { 238 if (owner_window_) {
210 LOG(ERROR) << "File dialog already in use!"; 239 LOG(ERROR) << "File dialog already in use!";
211 return; 240 return;
212 } 241 }
213 // Extension background pages may not supply an owner_window. 242 // Extension background pages may not supply an owner_window.
214 Browser* owner_browser = (owner_window ? 243 owner_browser_ = (owner_window ?
215 BrowserList::FindBrowserWithWindow(owner_window) : 244 BrowserList::FindBrowserWithWindow(owner_window) :
216 BrowserList::GetLastActive()); 245 BrowserList::GetLastActive());
217 if (!owner_browser) { 246 if (!owner_browser_) {
218 NOTREACHED() << "Can't find owning browser"; 247 NOTREACHED() << "Can't find owning browser";
219 return; 248 return;
220 } 249 }
221 250
222 TabContentsWrapper* tab = owner_browser->GetSelectedTabContentsWrapper(); 251 TabContentsWrapper* tab = owner_browser_->GetSelectedTabContentsWrapper();
223 252
224 // Check if we have another dialog opened in the tab. It's unlikely, but 253 // Check if we have another dialog opened in the tab. It's unlikely, but
225 // possible. 254 // possible.
226 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0; 255 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0;
227 if (PendingExists(tab_id)) { 256 if (PendingExists(tab_id)) {
228 DLOG(WARNING) << "Pending dialog exists with id " << tab_id; 257 DLOG(WARNING) << "Pending dialog exists with id " << tab_id;
229 return; 258 return;
230 } 259 }
231 260
232 FilePath virtual_path; 261 FilePath virtual_path;
233 if (!file_manager_util::ConvertFileToRelativeFileSystemPath( 262 if (!file_manager_util::ConvertFileToRelativeFileSystemPath(
234 owner_browser->profile(), default_path, &virtual_path)) { 263 owner_browser_->profile(), default_path, &virtual_path)) {
235 virtual_path = default_path.BaseName(); 264 virtual_path = default_path.BaseName();
236 } 265 }
237 266
238 has_multiple_file_type_choices_ = 267 has_multiple_file_type_choices_ =
239 file_types ? file_types->extensions.size() > 1 : true; 268 file_types ? file_types->extensions.size() > 1 : true;
240 269
241 GURL file_browser_url = file_manager_util::GetFileBrowserUrlWithParams( 270 GURL file_browser_url = file_manager_util::GetFileBrowserUrlWithParams(
242 type, title, virtual_path, file_types, file_type_index, 271 type, title, virtual_path, file_types, file_type_index,
243 default_extension); 272 default_extension);
244 273
245 ExtensionDialog* dialog = ExtensionDialog::Show(file_browser_url, 274 ExtensionDialog* dialog = ExtensionDialog::Show(file_browser_url,
246 owner_browser, tab->web_contents(), 275 owner_browser_, tab->web_contents(),
247 kFileManagerWidth, kFileManagerHeight, 276 kFileManagerWidth, kFileManagerHeight,
248 #if defined(USE_AURA) 277 #if defined(USE_AURA)
249 file_manager_util::GetTitleFromType(type), 278 file_manager_util::GetTitleFromType(type),
250 #else 279 #else
251 // HTML-based header used. 280 // HTML-based header used.
252 string16(), 281 string16(),
253 #endif 282 #endif
254 this /* ExtensionDialog::Observer */); 283 this /* ExtensionDialog::Observer */);
255 if (!dialog) { 284 if (!dialog) {
256 LOG(ERROR) << "Unable to create extension dialog"; 285 LOG(ERROR) << "Unable to create extension dialog";
257 return; 286 return;
258 } 287 }
259 288
260 // Connect our listener to FileDialogFunction's per-tab callbacks. 289 // Connect our listener to FileDialogFunction's per-tab callbacks.
261 AddPending(tab_id); 290 AddPending(tab_id);
262 291
263 extension_dialog_ = dialog; 292 extension_dialog_ = dialog;
264 params_ = params; 293 params_ = params;
265 tab_id_ = tab_id; 294 tab_id_ = tab_id;
266 owner_window_ = owner_window; 295 owner_window_ = owner_window;
267 } 296 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698