Chromium Code Reviews| Index: chrome/browser/ui/views/tabs/tab_strip.cc |
| diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc |
| index 8a63d2bf7cb711bac84d85a4fb450ba93f695c90..bd9c4a689165e5fc987cfbc5839ea7493b5d092d 100644 |
| --- a/chrome/browser/ui/views/tabs/tab_strip.cc |
| +++ b/chrome/browser/ui/views/tabs/tab_strip.cc |
| @@ -17,7 +17,9 @@ |
| #include "base/metrics/histogram.h" |
| #include "base/stl_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| +#include "base/task_runner_util.h" |
| #include "chrome/browser/defaults.h" |
| +#include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/host_desktop.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/browser/ui/view_ids.h" |
| @@ -27,9 +29,14 @@ |
| #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" |
| #include "chrome/browser/ui/views/tabs/tab_strip_observer.h" |
| #include "chrome/browser/ui/views/touch_uma/touch_uma.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/plugin_service.h" |
| #include "content/public/browser/user_metrics.h" |
| +#include "content/public/common/webplugininfo.h" |
| #include "grit/generated_resources.h" |
| #include "grit/theme_resources.h" |
| +#include "ipc/ipc_message.h" |
| +#include "net/base/net_util.h" |
| #include "ui/base/accessibility/accessible_view_state.h" |
| #include "ui/base/default_theme_provider.h" |
| #include "ui/base/dragdrop/drag_drop_types.h" |
| @@ -290,6 +297,20 @@ TabDragController::EventSource EventSourceFromEvent( |
| TabDragController::EVENT_SOURCE_MOUSE; |
| } |
| +// Get the MIME type of the file pointed to by the url. This must be called |
| +// from an thread that allows IO. |
| +std::string FindURLMimeType(GURL url) { |
| + base::FilePath full_path; |
| + net::FileURLToFilePath(url, &full_path); |
| + |
| + std::string mime_type; |
| + // Get the MIME type based on the file path's extension. |
| + // This may use registry or file IO. |
| + net::GetMimeTypeFromFile(full_path, &mime_type); |
| + |
| + return mime_type; |
| +} |
| + |
| } // namespace |
| /////////////////////////////////////////////////////////////////////////////// |
| @@ -609,13 +630,15 @@ TabStrip::TabStrip(TabStripController* controller) |
| current_selected_width_(Tab::GetStandardSize().width()), |
| available_width_for_tabs_(-1), |
| in_tab_close_(false), |
| + drag_file_supported_(true), |
| animation_container_(new gfx::AnimationContainer()), |
| bounds_animator_(this), |
| layout_type_(TAB_STRIP_LAYOUT_SHRINK), |
| adjust_layout_(false), |
| reset_to_shrink_on_exit_(false), |
| mouse_move_count_(0), |
| - immersive_style_(false) { |
| + immersive_style_(false), |
| + weak_ptr_factory_(this) { |
| Init(); |
| } |
| @@ -1395,6 +1418,27 @@ gfx::Size TabStrip::GetPreferredSize() { |
| } |
| void TabStrip::OnDragEntered(const DropTargetEvent& event) { |
| + // Clear information about previous drag operation. |
| + drag_url_ = GURL(); |
| + drag_file_supported_ = true; |
| + |
| + GURL url; |
| + string16 title; |
| + if (event.data().GetURLAndTitle(&url, &title) && url.is_valid()) { |
|
asanka
2013/11/15 19:15:22
The logic below here only applies to file:// URLs.
sky
2013/11/15 20:46:37
None-the-less there is no point doing the same tes
asanka
2013/11/15 21:01:13
Yup.
michaelpg
2013/11/15 21:08:01
The check here esnures we don't request unnecessar
|
| + // Cache the URL associated with the current drag. |
| + drag_url_ = url; |
| + |
| + // Get the MIME type of the file based on the file path's extension. |
| + // Pass the input URL to be certain which URL the reply is for. |
| + base::PostTaskAndReplyWithResult( |
| + content::BrowserThread::GetBlockingPool(), |
| + FROM_HERE, |
| + base::Bind(&FindURLMimeType, url), |
| + base::Bind(&TabStrip::OnFindURLMimeTypeCompleted, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + url)); |
| + } |
| + |
| // Force animations to stop, otherwise it makes the index calculation tricky. |
| StopAnimating(true); |
| @@ -1403,6 +1447,10 @@ void TabStrip::OnDragEntered(const DropTargetEvent& event) { |
| int TabStrip::OnDragUpdated(const DropTargetEvent& event) { |
| UpdateDropIndex(event); |
| + |
| + if (!drag_file_supported_) |
| + return ui::DragDropTypes::DRAG_NONE; |
| + |
| return GetDropEffect(event); |
| } |
| @@ -1422,7 +1470,8 @@ int TabStrip::OnPerformDrop(const DropTargetEvent& event) { |
| GURL url; |
| string16 title; |
| - if (!event.data().GetURLAndTitle(&url, &title) || !url.is_valid()) |
| + if (!drag_file_supported_ || !event.data().GetURLAndTitle(&url, &title) || |
|
sky
2013/11/15 00:48:54
We shouldn't need to check url/title twice.
michaelpg
2013/11/18 23:24:51
Done, as per above.
|
| + !url.is_valid()) |
| return ui::DragDropTypes::DRAG_NONE; |
| controller()->PerformDrop(drop_before, drop_index, url); |
| @@ -2040,6 +2089,27 @@ void TabStrip::StoppedDraggingTab(Tab* tab, bool* is_first_tab) { |
| tab, new ResetDraggingStateDelegate(tab), true); |
| } |
| +void TabStrip::OnFindURLMimeTypeCompleted(GURL url, |
| + const std::string& mime_type) { |
| + // If this is a reply for the current URL, check if the file is unsupported. |
| + // If the MIME type is empty, we do not have enough info to disallow the drag. |
| + if (url == drag_url_ && !mime_type.empty() && |
| + !net::IsSupportedMimeType(mime_type)) { |
| + // Check whether there is a plugin that supports the mime type (e.g. PDF). |
| + // TODO(bauerb): This possibly uses stale information, but it's guaranteed |
| + // not to do disk access. |
| + bool allow_wildcard = false; |
| + content::WebPluginInfo plugin; |
| + if (!content::PluginService::GetInstance()->GetPluginInfo( |
| + -1, // process ID |
| + MSG_ROUTING_NONE, // routing ID |
| + controller()->GetProfile()->GetResourceContext(), |
| + url, GURL(), mime_type, allow_wildcard, |
| + NULL, &plugin, NULL)) |
| + drag_file_supported_ = false; |
| + } |
| +} |
| + |
| void TabStrip::OwnDragController(TabDragController* controller) { |
| // Typically, ReleaseDragController() and OwnDragController() calls are paired |
| // via corresponding calls to TabDragController::Detach() and |