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

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: . 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
« no previous file with comments | « chrome/browser/ui/views/select_file_dialog_extension.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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::ExtensionTerminated(
133 ExtensionDialog* dialog) {
134 // The extension would have been unloaded because of the termination,
135 // reload it.
136 std::string extension_id = dialog->host()->extension()->id();
137 // Reload the extension after a bit; the extension may not have been unloaded
138 // yet. We don't want to try to reload the extension only to have the Unload
139 // code execute after us and re-unload the extension.
140 //
141 // TODO(rkc): This is ugly. The ideal solution is that we shouldn't need to
142 // reload the extension at all - when we try to open the extension the next
143 // time, the extension subsystem would automatically reload it for us. At
144 // this time though this is broken because of some faulty wiring in
145 // ExtensionProcessManager::CreateViewHost. Once that is fixed, remove this.
146 if (owner_browser_) {
147 MessageLoop::current()->PostTask(FROM_HERE,
148 base::Bind(&ExtensionService::ReloadExtension,
149 base::Unretained(owner_browser_->profile()->GetExtensionService()),
150 extension_id));
151 }
152
153 dialog->Close();
154 }
155
126 // static 156 // static
127 void SelectFileDialogExtension::OnFileSelected( 157 void SelectFileDialogExtension::OnFileSelected(
128 int32 tab_id, const FilePath& path, int index) { 158 int32 tab_id, const FilePath& path, int index) {
129 scoped_refptr<SelectFileDialogExtension> dialog = 159 scoped_refptr<SelectFileDialogExtension> dialog =
130 PendingDialog::GetInstance()->Find(tab_id); 160 PendingDialog::GetInstance()->Find(tab_id);
131 if (!dialog) 161 if (!dialog)
132 return; 162 return;
133 dialog->selection_type_ = SINGLE_FILE; 163 dialog->selection_type_ = SINGLE_FILE;
134 dialog->selection_files_.clear(); 164 dialog->selection_files_.clear();
135 dialog->selection_files_.push_back(path); 165 dialog->selection_files_.push_back(path);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 const FileTypeInfo* file_types, 234 const FileTypeInfo* file_types,
205 int file_type_index, 235 int file_type_index,
206 const FilePath::StringType& default_extension, 236 const FilePath::StringType& default_extension,
207 gfx::NativeWindow owner_window, 237 gfx::NativeWindow owner_window,
208 void* params) { 238 void* params) {
209 if (owner_window_) { 239 if (owner_window_) {
210 LOG(ERROR) << "File dialog already in use!"; 240 LOG(ERROR) << "File dialog already in use!";
211 return; 241 return;
212 } 242 }
213 // Extension background pages may not supply an owner_window. 243 // Extension background pages may not supply an owner_window.
214 Browser* owner_browser = (owner_window ? 244 owner_browser_ = (owner_window ?
215 BrowserList::FindBrowserWithWindow(owner_window) : 245 BrowserList::FindBrowserWithWindow(owner_window) :
216 BrowserList::GetLastActive()); 246 BrowserList::GetLastActive());
217 if (!owner_browser) { 247 if (!owner_browser_) {
218 NOTREACHED() << "Can't find owning browser"; 248 NOTREACHED() << "Can't find owning browser";
219 return; 249 return;
220 } 250 }
221 251
222 TabContentsWrapper* tab = owner_browser->GetSelectedTabContentsWrapper(); 252 TabContentsWrapper* tab = owner_browser_->GetSelectedTabContentsWrapper();
223 253
224 // Check if we have another dialog opened in the tab. It's unlikely, but 254 // Check if we have another dialog opened in the tab. It's unlikely, but
225 // possible. 255 // possible.
226 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0; 256 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0;
227 if (PendingExists(tab_id)) { 257 if (PendingExists(tab_id)) {
228 DLOG(WARNING) << "Pending dialog exists with id " << tab_id; 258 DLOG(WARNING) << "Pending dialog exists with id " << tab_id;
229 return; 259 return;
230 } 260 }
231 261
232 FilePath virtual_path; 262 FilePath virtual_path;
233 if (!file_manager_util::ConvertFileToRelativeFileSystemPath( 263 if (!file_manager_util::ConvertFileToRelativeFileSystemPath(
234 owner_browser->profile(), default_path, &virtual_path)) { 264 owner_browser_->profile(), default_path, &virtual_path)) {
235 virtual_path = default_path.BaseName(); 265 virtual_path = default_path.BaseName();
236 } 266 }
237 267
238 has_multiple_file_type_choices_ = 268 has_multiple_file_type_choices_ =
239 file_types ? file_types->extensions.size() > 1 : true; 269 file_types ? file_types->extensions.size() > 1 : true;
240 270
241 GURL file_browser_url = file_manager_util::GetFileBrowserUrlWithParams( 271 GURL file_browser_url = file_manager_util::GetFileBrowserUrlWithParams(
242 type, title, virtual_path, file_types, file_type_index, 272 type, title, virtual_path, file_types, file_type_index,
243 default_extension); 273 default_extension);
244 274
245 ExtensionDialog* dialog = ExtensionDialog::Show(file_browser_url, 275 ExtensionDialog* dialog = ExtensionDialog::Show(file_browser_url,
246 owner_browser, tab->web_contents(), 276 owner_browser_, tab->web_contents(),
247 kFileManagerWidth, kFileManagerHeight, 277 kFileManagerWidth, kFileManagerHeight,
248 #if defined(USE_AURA) 278 #if defined(USE_AURA)
249 file_manager_util::GetTitleFromType(type), 279 file_manager_util::GetTitleFromType(type),
250 #else 280 #else
251 // HTML-based header used. 281 // HTML-based header used.
252 string16(), 282 string16(),
253 #endif 283 #endif
254 this /* ExtensionDialog::Observer */); 284 this /* ExtensionDialog::Observer */);
255 if (!dialog) { 285 if (!dialog) {
256 LOG(ERROR) << "Unable to create extension dialog"; 286 LOG(ERROR) << "Unable to create extension dialog";
257 return; 287 return;
258 } 288 }
259 289
260 // Connect our listener to FileDialogFunction's per-tab callbacks. 290 // Connect our listener to FileDialogFunction's per-tab callbacks.
261 AddPending(tab_id); 291 AddPending(tab_id);
262 292
263 extension_dialog_ = dialog; 293 extension_dialog_ = dialog;
264 params_ = params; 294 params_ = params;
265 tab_id_ = tab_id; 295 tab_id_ = tab_id;
266 owner_window_ = owner_window; 296 owner_window_ = owner_window;
267 } 297 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/select_file_dialog_extension.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698