OLD | NEW |
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" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
11 #include "base/memory/singleton.h" | 11 #include "base/memory/singleton.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "chrome/browser/browser_process.h" |
13 #include "chrome/browser/chromeos/extensions/file_browser_private_api.h" | 14 #include "chrome/browser/chromeos/extensions/file_browser_private_api.h" |
14 #include "chrome/browser/chromeos/extensions/file_manager_util.h" | 15 #include "chrome/browser/chromeos/extensions/file_manager_util.h" |
15 #include "chrome/browser/extensions/extension_host.h" | 16 #include "chrome/browser/extensions/extension_host.h" |
16 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
| 18 #include "chrome/browser/extensions/shell_window_registry.h" |
| 19 #include "chrome/browser/profiles/profile_manager.h" |
17 #include "chrome/browser/sessions/restore_tab_helper.h" | 20 #include "chrome/browser/sessions/restore_tab_helper.h" |
| 21 #include "chrome/browser/ui/base_window.h" |
18 #include "chrome/browser/ui/browser.h" | 22 #include "chrome/browser/ui/browser.h" |
19 #include "chrome/browser/ui/browser_finder.h" | 23 #include "chrome/browser/ui/browser_finder.h" |
20 #include "chrome/browser/ui/browser_list.h" | 24 #include "chrome/browser/ui/browser_list.h" |
21 #include "chrome/browser/ui/browser_window.h" | 25 #include "chrome/browser/ui/browser_window.h" |
| 26 #include "chrome/browser/ui/extensions/shell_window.h" |
22 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 27 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
23 #include "chrome/browser/ui/views/extensions/extension_dialog.h" | 28 #include "chrome/browser/ui/views/extensions/extension_dialog.h" |
24 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
25 #include "content/public/common/selected_file_info.h" | 30 #include "content/public/common/selected_file_info.h" |
26 | 31 |
27 using content::BrowserThread; | 32 using content::BrowserThread; |
28 | 33 |
29 namespace { | 34 namespace { |
30 | 35 |
31 const int kFileManagerWidth = 954; // pixels | 36 const int kFileManagerWidth = 954; // pixels |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 // static | 94 // static |
90 SelectFileDialogExtension* SelectFileDialogExtension::Create( | 95 SelectFileDialogExtension* SelectFileDialogExtension::Create( |
91 Listener* listener) { | 96 Listener* listener) { |
92 return new SelectFileDialogExtension(listener); | 97 return new SelectFileDialogExtension(listener); |
93 } | 98 } |
94 | 99 |
95 SelectFileDialogExtension::SelectFileDialogExtension(Listener* listener) | 100 SelectFileDialogExtension::SelectFileDialogExtension(Listener* listener) |
96 : SelectFileDialog(listener), | 101 : SelectFileDialog(listener), |
97 has_multiple_file_type_choices_(false), | 102 has_multiple_file_type_choices_(false), |
98 tab_id_(0), | 103 tab_id_(0), |
99 owner_browser_(NULL), | 104 profile_(NULL), |
100 owner_window_(NULL), | 105 owner_window_(NULL), |
101 selection_type_(CANCEL), | 106 selection_type_(CANCEL), |
102 selection_index_(0), | 107 selection_index_(0), |
103 params_(NULL) { | 108 params_(NULL) { |
104 } | 109 } |
105 | 110 |
106 SelectFileDialogExtension::~SelectFileDialogExtension() { | 111 SelectFileDialogExtension::~SelectFileDialogExtension() { |
107 if (extension_dialog_) | 112 if (extension_dialog_) |
108 extension_dialog_->ObserverDestroyed(); | 113 extension_dialog_->ObserverDestroyed(); |
109 } | 114 } |
110 | 115 |
111 bool SelectFileDialogExtension::IsRunning( | 116 bool SelectFileDialogExtension::IsRunning( |
112 gfx::NativeWindow owner_window) const { | 117 gfx::NativeWindow owner_window) const { |
113 return owner_window_ == owner_window; | 118 return owner_window_ == owner_window; |
114 } | 119 } |
115 | 120 |
116 void SelectFileDialogExtension::ListenerDestroyed() { | 121 void SelectFileDialogExtension::ListenerDestroyed() { |
117 listener_ = NULL; | 122 listener_ = NULL; |
118 params_ = NULL; | 123 params_ = NULL; |
119 PendingDialog::GetInstance()->Remove(tab_id_); | 124 PendingDialog::GetInstance()->Remove(tab_id_); |
120 } | 125 } |
121 | 126 |
122 void SelectFileDialogExtension::ExtensionDialogClosing( | 127 void SelectFileDialogExtension::ExtensionDialogClosing( |
123 ExtensionDialog* dialog) { | 128 ExtensionDialog* dialog) { |
124 owner_browser_ = NULL; | 129 profile_ = NULL; |
125 owner_window_ = NULL; | 130 owner_window_ = NULL; |
126 // Release our reference to the dialog to allow it to close. | 131 // Release our reference to the dialog to allow it to close. |
127 extension_dialog_ = NULL; | 132 extension_dialog_ = NULL; |
128 PendingDialog::GetInstance()->Remove(tab_id_); | 133 PendingDialog::GetInstance()->Remove(tab_id_); |
129 // Actually invoke the appropriate callback on our listener. | 134 // Actually invoke the appropriate callback on our listener. |
130 NotifyListener(); | 135 NotifyListener(); |
131 } | 136 } |
132 | 137 |
133 void SelectFileDialogExtension::ExtensionTerminated( | 138 void SelectFileDialogExtension::ExtensionTerminated( |
134 ExtensionDialog* dialog) { | 139 ExtensionDialog* dialog) { |
135 // The extension would have been unloaded because of the termination, | 140 // The extension would have been unloaded because of the termination, |
136 // reload it. | 141 // reload it. |
137 std::string extension_id = dialog->host()->extension()->id(); | 142 std::string extension_id = dialog->host()->extension()->id(); |
138 // Reload the extension after a bit; the extension may not have been unloaded | 143 // Reload the extension after a bit; the extension may not have been unloaded |
139 // yet. We don't want to try to reload the extension only to have the Unload | 144 // yet. We don't want to try to reload the extension only to have the Unload |
140 // code execute after us and re-unload the extension. | 145 // code execute after us and re-unload the extension. |
141 // | 146 // |
142 // TODO(rkc): This is ugly. The ideal solution is that we shouldn't need to | 147 // TODO(rkc): This is ugly. The ideal solution is that we shouldn't need to |
143 // reload the extension at all - when we try to open the extension the next | 148 // reload the extension at all - when we try to open the extension the next |
144 // time, the extension subsystem would automatically reload it for us. At | 149 // time, the extension subsystem would automatically reload it for us. At |
145 // this time though this is broken because of some faulty wiring in | 150 // this time though this is broken because of some faulty wiring in |
146 // ExtensionProcessManager::CreateViewHost. Once that is fixed, remove this. | 151 // ExtensionProcessManager::CreateViewHost. Once that is fixed, remove this. |
147 if (owner_browser_) { | 152 if (profile_) { |
148 MessageLoop::current()->PostTask(FROM_HERE, | 153 MessageLoop::current()->PostTask(FROM_HERE, |
149 base::Bind(&ExtensionService::ReloadExtension, | 154 base::Bind(&ExtensionService::ReloadExtension, |
150 base::Unretained(owner_browser_->profile()->GetExtensionService()), | 155 base::Unretained(profile_->GetExtensionService()), |
151 extension_id)); | 156 extension_id)); |
152 } | 157 } |
153 | 158 |
154 dialog->Close(); | 159 dialog->Close(); |
155 } | 160 } |
156 | 161 |
157 // static | 162 // static |
158 void SelectFileDialogExtension::OnFileSelected( | 163 void SelectFileDialogExtension::OnFileSelected( |
159 int32 tab_id, | 164 int32 tab_id, |
160 const content::SelectedFileInfo& file, | 165 const content::SelectedFileInfo& file, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 const FilePath& default_path, | 244 const FilePath& default_path, |
240 const FileTypeInfo* file_types, | 245 const FileTypeInfo* file_types, |
241 int file_type_index, | 246 int file_type_index, |
242 const FilePath::StringType& default_extension, | 247 const FilePath::StringType& default_extension, |
243 gfx::NativeWindow owner_window, | 248 gfx::NativeWindow owner_window, |
244 void* params) { | 249 void* params) { |
245 if (owner_window_) { | 250 if (owner_window_) { |
246 LOG(ERROR) << "File dialog already in use!"; | 251 LOG(ERROR) << "File dialog already in use!"; |
247 return; | 252 return; |
248 } | 253 } |
249 // Extension background pages may not supply an owner_window. | 254 |
250 owner_browser_ = (owner_window ? | 255 // The base window to associate the dialog with. |
| 256 BaseWindow* base_window = NULL; |
| 257 |
| 258 // The tab contents to associate the dialog with. |
| 259 const TabContents* tab = NULL; |
| 260 |
| 261 // First try to find a Browser using the supplied owner_window. If no owner |
| 262 // window has been supplied, this is running from a background page and should |
| 263 // be associated with the last active browser. |
| 264 Browser* owner_browser = (owner_window ? |
251 browser::FindBrowserWithWindow(owner_window) : | 265 browser::FindBrowserWithWindow(owner_window) : |
252 BrowserList::GetLastActive()); | 266 BrowserList::GetLastActive()); |
253 if (!owner_browser_) { | 267 if (owner_browser) { |
254 NOTREACHED() << "Can't find owning browser"; | 268 base_window = owner_browser->window(); |
| 269 tab = owner_browser->GetActiveTabContents(); |
| 270 profile_ = tab->profile(); |
| 271 } else if (owner_window) { |
| 272 // If an owner_window was supplied but we couldn't find a browser, this |
| 273 // could be for a shell window. |
| 274 // TODO(benwells): Find a better way to get a shell window from a native |
| 275 // window. |
| 276 std::vector<Profile*> profiles = |
| 277 g_browser_process->profile_manager()->GetLoadedProfiles(); |
| 278 for (std::vector<Profile*>::const_iterator iter = profiles.begin(); |
| 279 iter < profiles.end(); iter++) { |
| 280 ShellWindowRegistry* registry = ShellWindowRegistry::Get(*iter); |
| 281 DCHECK(registry); |
| 282 ShellWindow* shell_window = registry->GetShellWindowForNativeWindow( |
| 283 owner_window); |
| 284 if (shell_window) { |
| 285 base_window = shell_window; |
| 286 tab = shell_window->tab_contents(); |
| 287 profile_ = *iter; |
| 288 break; |
| 289 } |
| 290 } |
| 291 } |
| 292 |
| 293 if (!base_window) { |
| 294 NOTREACHED() << "Can't find owning window."; |
255 return; | 295 return; |
256 } | 296 } |
257 | 297 DCHECK(profile_); |
258 TabContents* tab = owner_browser_->GetActiveTabContents(); | |
259 | 298 |
260 // Check if we have another dialog opened in the tab. It's unlikely, but | 299 // Check if we have another dialog opened in the tab. It's unlikely, but |
261 // possible. | 300 // possible. If there is no tab contents use a tab_id of 0. A dialog without |
| 301 // an associated tab contents will be shown fully screen; only one at a time |
| 302 // is allowed in this state. |
262 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0; | 303 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0; |
263 if (PendingExists(tab_id)) { | 304 if (PendingExists(tab_id)) { |
264 DLOG(WARNING) << "Pending dialog exists with id " << tab_id; | 305 DLOG(WARNING) << "Pending dialog exists with id " << tab_id; |
265 return; | 306 return; |
266 } | 307 } |
267 | 308 |
268 FilePath virtual_path; | 309 FilePath virtual_path; |
269 if (!file_manager_util::ConvertFileToRelativeFileSystemPath( | 310 if (!file_manager_util::ConvertFileToRelativeFileSystemPath( |
270 owner_browser_->profile(), default_path, &virtual_path)) { | 311 profile_, default_path, &virtual_path)) { |
271 virtual_path = default_path.BaseName(); | 312 virtual_path = default_path.BaseName(); |
272 } | 313 } |
273 | 314 |
274 has_multiple_file_type_choices_ = | 315 has_multiple_file_type_choices_ = |
275 file_types ? file_types->extensions.size() > 1 : true; | 316 file_types ? file_types->extensions.size() > 1 : true; |
276 | 317 |
277 GURL file_browser_url = file_manager_util::GetFileBrowserUrlWithParams( | 318 GURL file_browser_url = file_manager_util::GetFileBrowserUrlWithParams( |
278 type, title, virtual_path, file_types, file_type_index, | 319 type, title, virtual_path, file_types, file_type_index, |
279 default_extension); | 320 default_extension); |
280 | 321 |
281 ExtensionDialog* dialog = ExtensionDialog::Show(file_browser_url, | 322 ExtensionDialog* dialog = ExtensionDialog::Show(file_browser_url, |
282 owner_browser_, tab->web_contents(), | 323 base_window, profile_, tab->web_contents(), |
283 kFileManagerWidth, kFileManagerHeight, | 324 kFileManagerWidth, kFileManagerHeight, |
284 #if defined(USE_AURA) | 325 #if defined(USE_AURA) |
285 file_manager_util::GetTitleFromType(type), | 326 file_manager_util::GetTitleFromType(type), |
286 #else | 327 #else |
287 // HTML-based header used. | 328 // HTML-based header used. |
288 string16(), | 329 string16(), |
289 #endif | 330 #endif |
290 this /* ExtensionDialog::Observer */); | 331 this /* ExtensionDialog::Observer */); |
291 if (!dialog) { | 332 if (!dialog) { |
292 LOG(ERROR) << "Unable to create extension dialog"; | 333 LOG(ERROR) << "Unable to create extension dialog"; |
293 return; | 334 return; |
294 } | 335 } |
295 | 336 |
296 // Connect our listener to FileDialogFunction's per-tab callbacks. | 337 // Connect our listener to FileDialogFunction's per-tab callbacks. |
297 AddPending(tab_id); | 338 AddPending(tab_id); |
298 | 339 |
299 extension_dialog_ = dialog; | 340 extension_dialog_ = dialog; |
300 params_ = params; | 341 params_ = params; |
301 tab_id_ = tab_id; | 342 tab_id_ = tab_id; |
302 owner_window_ = owner_window; | 343 owner_window_ = owner_window; |
303 } | 344 } |
OLD | NEW |