| 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 "apps/shell_window.h" | 7 #include "apps/shell_window.h" |
| 8 #include "apps/shell_window_registry.h" | 8 #include "apps/shell_window_registry.h" |
| 9 #include "apps/ui/native_app_window.h" | 9 #include "apps/ui/native_app_window.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 owner_browser = chrome::FindBrowserWithWindow(owner_window); | 288 owner_browser = chrome::FindBrowserWithWindow(owner_window); |
| 289 if (!owner_browser) { | 289 if (!owner_browser) { |
| 290 // If an owner_window was supplied but we couldn't find a browser, this | 290 // If an owner_window was supplied but we couldn't find a browser, this |
| 291 // could be for a shell window. | 291 // could be for a shell window. |
| 292 shell_window = apps::ShellWindowRegistry:: | 292 shell_window = apps::ShellWindowRegistry:: |
| 293 GetShellWindowForNativeWindowAnyProfile(owner_window); | 293 GetShellWindowForNativeWindowAnyProfile(owner_window); |
| 294 } | 294 } |
| 295 } | 295 } |
| 296 | 296 |
| 297 if (shell_window) { | 297 if (shell_window) { |
| 298 if (shell_window->window_type_is_panel()) { | 298 DCHECK(!shell_window->window_type_is_panel()); |
| 299 NOTREACHED() << "File dialog opened by panel."; | |
| 300 return; | |
| 301 } | |
| 302 base_window = shell_window->GetBaseWindow(); | 299 base_window = shell_window->GetBaseWindow(); |
| 303 web_contents = shell_window->web_contents(); | 300 web_contents = shell_window->web_contents(); |
| 304 } else { | 301 } else { |
| 305 // If the owning window is still unknown, this could be a background page or | 302 // If the owning window is still unknown, this could be a background page or |
| 306 // and extension popup. Use the last active browser. | 303 // and extension popup. Use the last active browser. |
| 307 if (!owner_browser) { | 304 if (!owner_browser) { |
| 308 owner_browser = | 305 owner_browser = |
| 309 chrome::FindLastActiveWithHostDesktopType(chrome::GetActiveDesktop()); | 306 chrome::FindLastActiveWithHostDesktopType(chrome::GetActiveDesktop()); |
| 310 } | 307 } |
| 311 DCHECK(owner_browser); | 308 DCHECK(owner_browser); |
| 312 if (!owner_browser) { | |
| 313 LOG(ERROR) << "Could not find browser or shell window for popup."; | |
| 314 return; | |
| 315 } | |
| 316 base_window = owner_browser->window(); | 309 base_window = owner_browser->window(); |
| 317 web_contents = owner_browser->tab_strip_model()->GetActiveWebContents(); | 310 web_contents = owner_browser->tab_strip_model()->GetActiveWebContents(); |
| 318 } | 311 } |
| 319 | 312 |
| 320 DCHECK(base_window); | 313 DCHECK(base_window); |
| 321 DCHECK(web_contents); | 314 DCHECK(web_contents); |
| 322 profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 315 profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 323 DCHECK(profile_); | 316 DCHECK(profile_); |
| 324 | 317 |
| 325 // Check if we have another dialog opened for the contents. It's unlikely, but | 318 // Check if we have another dialog opened for the contents. It's unlikely, but |
| 326 // possible. | 319 // possible. In such situation, discard this request. |
| 327 RoutingID routing_id = GetRoutingIDFromWebContents(web_contents); | 320 RoutingID routing_id = GetRoutingIDFromWebContents(web_contents); |
| 328 if (PendingExists(routing_id)) { | 321 if (PendingExists(routing_id)) |
| 329 DLOG(WARNING) << "Pending dialog exists with id " << routing_id; | |
| 330 return; | 322 return; |
| 331 } | |
| 332 | |
| 333 base::FilePath default_dialog_path; | |
| 334 | 323 |
| 335 const PrefService* pref_service = profile_->GetPrefs(); | 324 const PrefService* pref_service = profile_->GetPrefs(); |
| 325 DCHECK(pref_service); |
| 336 | 326 |
| 337 if (default_path.empty() && pref_service) { | 327 base::FilePath download_default_path( |
| 338 default_dialog_path = | 328 pref_service->GetFilePath(prefs::kDownloadDefaultDirectory)); |
| 339 pref_service->GetFilePath(prefs::kDownloadDefaultDirectory); | 329 |
| 340 } else { | 330 base::FilePath selection_path = default_path.IsAbsolute() ? |
| 341 default_dialog_path = default_path; | 331 default_path : download_default_path.Append(default_path.BaseName()); |
| 332 |
| 333 base::FilePath fallback_path = profile_->last_selected_directory().empty() ? |
| 334 download_default_path : profile_->last_selected_directory(); |
| 335 |
| 336 // Convert the above absolute paths to virtual paths. |
| 337 // TODO(mtomasz): Use URLs instead of paths. |
| 338 base::FilePath selection_virtual_path; |
| 339 if (!file_manager::util::ConvertAbsoluteFilePathToRelativeFileSystemPath( |
| 340 profile_, |
| 341 file_manager::kFileManagerAppId, |
| 342 selection_path, |
| 343 &selection_virtual_path)) { |
| 344 // Due to the current design, an invalid temporal cache file path may passed |
| 345 // as |default_path| (crbug.com/178013 #9-#11). In such a case, we use the |
| 346 // last selected directory as a workaround. Real fix is tracked at |
| 347 // crbug.com/110119. |
| 348 if (!file_manager::util::ConvertAbsoluteFilePathToRelativeFileSystemPath( |
| 349 profile_, |
| 350 file_manager::kFileManagerAppId, |
| 351 fallback_path.Append(default_path.BaseName()), |
| 352 &selection_virtual_path)) { |
| 353 LOG(ERROR) << "Unable to resolve the selection path."; |
| 354 return; |
| 355 } |
| 342 } | 356 } |
| 357 // TODO(mtomasz): Adding a leading separator works, because this code is |
| 358 // executed on Chrome OS only. This trick will be removed, once migration to |
| 359 // URLs is finished. |
| 360 selection_virtual_path = base::FilePath("/").Append(selection_virtual_path); |
| 343 | 361 |
| 344 base::FilePath virtual_path; | 362 base::FilePath current_directory_virtual_path; |
| 345 base::FilePath fallback_path = profile_->last_selected_directory().Append( | 363 base::FilePath current_directory_path = selection_path.DirName(); |
| 346 default_dialog_path.BaseName()); | 364 if (!file_manager::util::ConvertAbsoluteFilePathToRelativeFileSystemPath( |
| 347 // If an absolute path is specified as the default path, convert it to the | 365 profile_, |
| 348 // virtual path in the file browser extension. Due to the current design, | 366 file_manager::kFileManagerAppId, |
| 349 // an invalid temporal cache file path may passed as |default_dialog_path| | 367 current_directory_path, |
| 350 // (crbug.com/178013 #9-#11). In such a case, we use the last selected | 368 ¤t_directory_virtual_path)) { |
| 351 // directory as a workaround. Real fix is tracked at crbug.com/110119. | 369 // Fallback if necessary, see the comment above. |
| 352 using file_manager::kFileManagerAppId; | 370 if (!file_manager::util::ConvertAbsoluteFilePathToRelativeFileSystemPath( |
| 353 if (default_dialog_path.IsAbsolute() && | 371 profile_, |
| 354 (file_manager::util::ConvertAbsoluteFilePathToRelativeFileSystemPath( | 372 file_manager::kFileManagerAppId, |
| 355 profile_, kFileManagerAppId, default_dialog_path, &virtual_path) || | 373 fallback_path, |
| 356 file_manager::util::ConvertAbsoluteFilePathToRelativeFileSystemPath( | 374 ¤t_directory_virtual_path)) { |
| 357 profile_, kFileManagerAppId, fallback_path, &virtual_path))) { | 375 LOG(ERROR) << "Unable to resolve the current directory path: " |
| 358 virtual_path = base::FilePath("/").Append(virtual_path); | 376 << fallback_path.value(); |
| 359 } else { | 377 return; |
| 360 // If the path was relative, or failed to convert, just use the base name, | 378 } |
| 361 virtual_path = default_dialog_path.BaseName(); | |
| 362 } | 379 } |
| 380 current_directory_virtual_path = base::FilePath("/").Append( |
| 381 current_directory_virtual_path); |
| 363 | 382 |
| 364 has_multiple_file_type_choices_ = | 383 has_multiple_file_type_choices_ = |
| 365 file_types ? file_types->extensions.size() > 1 : true; | 384 !file_types || (file_types->extensions.size() > 1); |
| 366 | 385 |
| 367 GURL file_manager_url = | 386 GURL file_manager_url = |
| 368 file_manager::util::GetFileManagerMainPageUrlWithParams( | 387 file_manager::util::GetFileManagerMainPageUrlWithParams( |
| 369 type, title, virtual_path, file_types, file_type_index, | 388 type, |
| 389 title, |
| 390 current_directory_virtual_path, |
| 391 selection_virtual_path, |
| 392 file_types, |
| 393 file_type_index, |
| 370 default_extension); | 394 default_extension); |
| 371 | 395 |
| 372 ExtensionDialog* dialog = ExtensionDialog::Show(file_manager_url, | 396 ExtensionDialog* dialog = ExtensionDialog::Show(file_manager_url, |
| 373 base_window, profile_, web_contents, | 397 base_window, profile_, web_contents, |
| 374 kFileManagerWidth, kFileManagerHeight, | 398 kFileManagerWidth, kFileManagerHeight, |
| 375 kFileManagerMinimumWidth, | 399 kFileManagerMinimumWidth, |
| 376 kFileManagerMinimumHeight, | 400 kFileManagerMinimumHeight, |
| 377 #if defined(USE_AURA) | 401 #if defined(USE_AURA) |
| 378 file_manager::util::GetSelectFileDialogTitle(type), | 402 file_manager::util::GetSelectFileDialogTitle(type), |
| 379 #else | 403 #else |
| 380 // HTML-based header used. | 404 // HTML-based header used. |
| 381 base::string16(), | 405 base::string16(), |
| 382 #endif | 406 #endif |
| 383 this /* ExtensionDialog::Observer */); | 407 this /* ExtensionDialog::Observer */); |
| 384 if (!dialog) { | 408 if (!dialog) { |
| 385 LOG(ERROR) << "Unable to create extension dialog"; | 409 LOG(ERROR) << "Unable to create extension dialog"; |
| 386 return; | 410 return; |
| 387 } | 411 } |
| 388 | 412 |
| 389 // Connect our listener to FileDialogFunction's per-tab callbacks. | 413 // Connect our listener to FileDialogFunction's per-tab callbacks. |
| 390 AddPending(routing_id); | 414 AddPending(routing_id); |
| 391 | 415 |
| 392 extension_dialog_ = dialog; | 416 extension_dialog_ = dialog; |
| 393 params_ = params; | 417 params_ = params; |
| 394 routing_id_ = routing_id; | 418 routing_id_ = routing_id; |
| 395 owner_window_ = owner_window; | 419 owner_window_ = owner_window; |
| 396 } | 420 } |
| OLD | NEW |