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

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: nits + todo 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 // static 88 // static
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_browser_(NULL),
99 owner_window_(NULL),
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(
133 ExtensionDialog* dialog) {
134 LOG(ERROR) << "Select File Dialog Extension crashed.";
Peter Kasting 2012/02/10 21:09:27 Don't LOG unless you really need it. Logs are gen
rkc 2012/02/10 21:33:11 Done.
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 //
143 // TODO(rkc): This is ugly. The ideal solution is that we shouldn't need to
144 // reload the extension at all - when we try to open the extension the next
145 // time, the extension subsystem would automatically reload it for us. At
146 // this time though this is broken because of some faulty wiring in
147 // ExtensionProcessManager::CreateViewHost. Once that is fixed, remove this.
148 if (owner_browser_) {
149 MessageLoop::current()->PostTask(
Peter Kasting 2012/02/10 21:09:27 Nit: Wrapping is kinda crazy. Just do: Messa
rkc 2012/02/10 21:33:11 Done.
150 FROM_HERE,
151 base::Bind(
152 &ExtensionService::ReloadExtension,
153 base::Unretained(owner_browser_->profile()->
154 GetExtensionService()),
155 extension_id));
156 }
157
158 dialog->Close();
159 }
160
126 // static 161 // static
127 void SelectFileDialogExtension::OnFileSelected( 162 void SelectFileDialogExtension::OnFileSelected(
128 int32 tab_id, const FilePath& path, int index) { 163 int32 tab_id, const FilePath& path, int index) {
129 scoped_refptr<SelectFileDialogExtension> dialog = 164 scoped_refptr<SelectFileDialogExtension> dialog =
130 PendingDialog::GetInstance()->Find(tab_id); 165 PendingDialog::GetInstance()->Find(tab_id);
131 if (!dialog) 166 if (!dialog)
132 return; 167 return;
133 dialog->selection_type_ = SINGLE_FILE; 168 dialog->selection_type_ = SINGLE_FILE;
134 dialog->selection_files_.clear(); 169 dialog->selection_files_.clear();
135 dialog->selection_files_.push_back(path); 170 dialog->selection_files_.push_back(path);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 const FileTypeInfo* file_types, 239 const FileTypeInfo* file_types,
205 int file_type_index, 240 int file_type_index,
206 const FilePath::StringType& default_extension, 241 const FilePath::StringType& default_extension,
207 gfx::NativeWindow owner_window, 242 gfx::NativeWindow owner_window,
208 void* params) { 243 void* params) {
209 if (owner_window_) { 244 if (owner_window_) {
210 LOG(ERROR) << "File dialog already in use!"; 245 LOG(ERROR) << "File dialog already in use!";
211 return; 246 return;
212 } 247 }
213 // Extension background pages may not supply an owner_window. 248 // Extension background pages may not supply an owner_window.
214 Browser* owner_browser = (owner_window ? 249 owner_browser_ = (owner_window ?
215 BrowserList::FindBrowserWithWindow(owner_window) : 250 BrowserList::FindBrowserWithWindow(owner_window) :
216 BrowserList::GetLastActive()); 251 BrowserList::GetLastActive());
217 if (!owner_browser) { 252 if (!owner_browser_) {
218 NOTREACHED() << "Can't find owning browser"; 253 NOTREACHED() << "Can't find owning browser";
219 return; 254 return;
220 } 255 }
221 256
222 TabContentsWrapper* tab = owner_browser->GetSelectedTabContentsWrapper(); 257 TabContentsWrapper* tab = owner_browser_->GetSelectedTabContentsWrapper();
223 258
224 // Check if we have another dialog opened in the tab. It's unlikely, but 259 // Check if we have another dialog opened in the tab. It's unlikely, but
225 // possible. 260 // possible.
226 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0; 261 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0;
227 if (PendingExists(tab_id)) { 262 if (PendingExists(tab_id)) {
228 DLOG(WARNING) << "Pending dialog exists with id " << tab_id; 263 DLOG(WARNING) << "Pending dialog exists with id " << tab_id;
229 return; 264 return;
230 } 265 }
231 266
232 FilePath virtual_path; 267 FilePath virtual_path;
233 if (!file_manager_util::ConvertFileToRelativeFileSystemPath( 268 if (!file_manager_util::ConvertFileToRelativeFileSystemPath(
234 owner_browser->profile(), default_path, &virtual_path)) { 269 owner_browser_->profile(), default_path, &virtual_path)) {
235 virtual_path = default_path.BaseName(); 270 virtual_path = default_path.BaseName();
236 } 271 }
237 272
238 has_multiple_file_type_choices_ = 273 has_multiple_file_type_choices_ =
239 file_types ? file_types->extensions.size() > 1 : true; 274 file_types ? file_types->extensions.size() > 1 : true;
240 275
241 GURL file_browser_url = file_manager_util::GetFileBrowserUrlWithParams( 276 GURL file_browser_url = file_manager_util::GetFileBrowserUrlWithParams(
242 type, title, virtual_path, file_types, file_type_index, 277 type, title, virtual_path, file_types, file_type_index,
243 default_extension); 278 default_extension);
244 279
245 ExtensionDialog* dialog = ExtensionDialog::Show(file_browser_url, 280 ExtensionDialog* dialog = ExtensionDialog::Show(file_browser_url,
246 owner_browser, tab->web_contents(), 281 owner_browser_, tab->web_contents(),
247 kFileManagerWidth, kFileManagerHeight, 282 kFileManagerWidth, kFileManagerHeight,
248 #if defined(USE_AURA) 283 #if defined(USE_AURA)
249 file_manager_util::GetTitleFromType(type), 284 file_manager_util::GetTitleFromType(type),
250 #else 285 #else
251 // HTML-based header used. 286 // HTML-based header used.
252 string16(), 287 string16(),
253 #endif 288 #endif
254 this /* ExtensionDialog::Observer */); 289 this /* ExtensionDialog::Observer */);
255 if (!dialog) { 290 if (!dialog) {
256 LOG(ERROR) << "Unable to create extension dialog"; 291 LOG(ERROR) << "Unable to create extension dialog";
257 return; 292 return;
258 } 293 }
259 294
260 // Connect our listener to FileDialogFunction's per-tab callbacks. 295 // Connect our listener to FileDialogFunction's per-tab callbacks.
261 AddPending(tab_id); 296 AddPending(tab_id);
262 297
263 extension_dialog_ = dialog; 298 extension_dialog_ = dialog;
264 params_ = params; 299 params_ = params;
265 tab_id_ = tab_id; 300 tab_id_ = tab_id;
266 owner_window_ = owner_window; 301 owner_window_ = owner_window;
267 } 302 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698