summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/download/drag_download_item_views.cc10
-rw-r--r--chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc54
-rw-r--r--chrome/browser/ui/views/tabs/browser_tab_strip_controller.h8
-rw-r--r--chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc4
-rw-r--r--chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h1
-rw-r--r--chrome/browser/ui/views/tabs/tab_strip.cc32
-rw-r--r--chrome/browser/ui/views/tabs/tab_strip.h9
-rw-r--r--chrome/browser/ui/views/tabs/tab_strip_controller.h4
8 files changed, 111 insertions, 11 deletions
diff --git a/chrome/browser/download/drag_download_item_views.cc b/chrome/browser/download/drag_download_item_views.cc
index 7b94718..e7e5df5 100644
--- a/chrome/browser/download/drag_download_item_views.cc
+++ b/chrome/browser/download/drag_download_item_views.cc
@@ -46,15 +46,9 @@ void DragDownloadItem(const content::DownloadItem* download,
const base::FilePath full_path = download->GetTargetFilePath();
data.SetFilename(full_path);
- std::string mime_type = download->GetMimeType();
- if (mime_type.empty())
- net::GetMimeTypeFromFile(full_path, &mime_type);
-
// Add URL so that we can load supported files when dragged to WebContents.
- if (net::IsSupportedMimeType(mime_type)) {
- data.SetURL(net::FilePathToFileURL(full_path),
- download->GetFileNameToReportUser().LossyDisplayName());
- }
+ data.SetURL(net::FilePathToFileURL(full_path),
+ download->GetFileNameToReportUser().LossyDisplayName());
#if !defined(TOOLKIT_GTK)
#if defined(USE_AURA)
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
index 90083b0..0db3239 100644
--- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
+++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -7,6 +7,8 @@
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/prefs/pref_service.h"
+#include "base/task_runner_util.h"
+#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/autocomplete/autocomplete_classifier.h"
#include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
@@ -29,9 +31,14 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
+#include "content/public/browser/plugin_service.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/webplugininfo.h"
+#include "ipc/ipc_message.h"
+#include "net/base/net_util.h"
#include "ui/base/layout.h"
#include "ui/base/models/list_selection_model.h"
#include "ui/gfx/image/image.h"
@@ -79,6 +86,20 @@ TabStripLayoutType DetermineTabStripLayout(
}
}
+// Get the MIME type of the file pointed to by the url, based on the file's
+// extension. Must be called on a thread that allows IO.
+std::string FindURLMimeType(const GURL& url) {
+ DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ base::FilePath full_path;
+ net::FileURLToFilePath(url, &full_path);
+
+ // Get the MIME type based on the filename.
+ std::string mime_type;
+ net::GetMimeTypeFromFile(full_path, &mime_type);
+
+ return mime_type;
+}
+
} // namespace
class BrowserTabStripController::TabContextMenuContents
@@ -177,7 +198,8 @@ BrowserTabStripController::BrowserTabStripController(Browser* browser,
: model_(model),
tabstrip_(NULL),
browser_(browser),
- hover_tab_selector_(model) {
+ hover_tab_selector_(model),
+ weak_ptr_factory_(this) {
model_->AddObserver(this);
local_pref_registrar_.Init(g_browser_process->local_state());
@@ -401,6 +423,16 @@ void BrowserTabStripController::OnStoppedDraggingTabs() {
immersive_reveal_lock_.reset();
}
+void BrowserTabStripController::CheckFileSupported(const GURL& url) {
+ base::PostTaskAndReplyWithResult(
+ content::BrowserThread::GetBlockingPool(),
+ FROM_HERE,
+ base::Bind(&FindURLMimeType, url),
+ base::Bind(&BrowserTabStripController::OnFindURLMimeTypeCompleted,
+ weak_ptr_factory_.GetWeakPtr(),
+ url));
+}
+
////////////////////////////////////////////////////////////////////////////////
// BrowserTabStripController, TabStripModelObserver implementation:
@@ -546,3 +578,23 @@ void BrowserTabStripController::UpdateLayoutType() {
browser_->host_desktop_type(), &adjust_layout);
tabstrip_->SetLayoutType(layout_type, adjust_layout);
}
+
+void BrowserTabStripController::OnFindURLMimeTypeCompleted(
+ const GURL& url,
+ const std::string& mime_type) {
+ // Check whether the mime type, if given, is known to be supported or 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.
+ content::WebPluginInfo plugin;
+ tabstrip_->FileSupported(
+ url,
+ mime_type.empty() ||
+ net::IsSupportedMimeType(mime_type) ||
+ content::PluginService::GetInstance()->GetPluginInfo(
+ -1, // process ID
+ MSG_ROUTING_NONE, // routing ID
+ model_->profile()->GetResourceContext(),
+ url, GURL(), mime_type, false,
+ NULL, &plugin, NULL));
+}
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h
index 06da492..35e8940 100644
--- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h
+++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h
@@ -74,6 +74,7 @@ class BrowserTabStripController : public TabStripController,
virtual void LayoutTypeMaybeChanged() OVERRIDE;
virtual void OnStartedDraggingTabs() OVERRIDE;
virtual void OnStoppedDraggingTabs() OVERRIDE;
+ virtual void CheckFileSupported(const GURL& url) OVERRIDE;
// TabStripModelObserver implementation:
virtual void TabInsertedAt(content::WebContents* contents,
@@ -139,6 +140,11 @@ class BrowserTabStripController : public TabStripController,
// Resets the tabstrips layout type from prefs.
void UpdateLayoutType();
+ // Notifies the tabstrip whether |url| is supported once a MIME type request
+ // has completed.
+ void OnFindURLMimeTypeCompleted(const GURL& url,
+ const std::string& mime_type);
+
TabStripModel* model_;
TabStrip* tabstrip_;
@@ -159,6 +165,8 @@ class BrowserTabStripController : public TabStripController,
PrefChangeRegistrar local_pref_registrar_;
+ base::WeakPtrFactory<BrowserTabStripController> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserTabStripController);
};
diff --git a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc
index 2ac9e82d..1489ac2 100644
--- a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc
+++ b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc
@@ -124,3 +124,7 @@ void FakeBaseTabStripController::OnStartedDraggingTabs() {
void FakeBaseTabStripController::OnStoppedDraggingTabs() {
}
+
+void FakeBaseTabStripController::CheckFileSupported(const GURL& url) {
+ tab_strip_->FileSupported(url, true);
+}
diff --git a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h
index 68a4b39..374cf58 100644
--- a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h
+++ b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h
@@ -51,6 +51,7 @@ class FakeBaseTabStripController : public TabStripController {
virtual void LayoutTypeMaybeChanged() OVERRIDE;
virtual void OnStartedDraggingTabs() OVERRIDE;
virtual void OnStoppedDraggingTabs() OVERRIDE;
+ virtual void CheckFileSupported(const GURL& url) OVERRIDE;
private:
TabStrip* tab_strip_;
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index 94b1afe..eafc48d 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -992,6 +992,11 @@ void TabStrip::StopAnimating(bool layout) {
DoLayout();
}
+void TabStrip::FileSupported(const GURL& url, bool supported) {
+ if (drop_info_.get() && drop_info_->url == url)
+ drop_info_->file_supported = supported;
+}
+
const ui::ListSelectionModel& TabStrip::GetSelectionModel() {
return controller_->GetSelectionModel();
}
@@ -1402,10 +1407,28 @@ void TabStrip::OnDragEntered(const DropTargetEvent& event) {
StopAnimating(true);
UpdateDropIndex(event);
+
+ GURL url;
+ string16 title;
+
+ // Check whether the event data includes supported drop data.
+ if (event.data().GetURLAndTitle(&url, &title) && url.is_valid()) {
+ drop_info_->url = url;
+
+ // For file:// URLs, kick off a MIME type request in case they're dropped.
+ if (url.SchemeIsFile())
+ controller()->CheckFileSupported(url);
+ }
}
int TabStrip::OnDragUpdated(const DropTargetEvent& event) {
+ // Update the drop index even if the file is unsupported, to allow
+ // dragging a file to the contents of another tab.
UpdateDropIndex(event);
+
+ if (!drop_info_->file_supported)
+ return ui::DragDropTypes::DRAG_NONE;
+
return GetDropEffect(event);
}
@@ -1419,13 +1442,17 @@ int TabStrip::OnPerformDrop(const DropTargetEvent& event) {
const int drop_index = drop_info_->drop_index;
const bool drop_before = drop_info_->drop_before;
+ const bool file_supported = drop_info_->file_supported;
// Hide the drop indicator.
SetDropIndex(-1, false);
+ // Do nothing if the file was unsupported or the URL is invalid. The URL may
+ // have been changed after |drop_info_| was created.
GURL url;
string16 title;
- if (!event.data().GetURLAndTitle(&url, &title) || !url.is_valid())
+ if (!file_supported ||
+ !event.data().GetURLAndTitle(&url, &title) || !url.is_valid())
return ui::DragDropTypes::DRAG_NONE;
controller()->PerformDrop(drop_before, drop_index, url);
@@ -2434,7 +2461,8 @@ TabStrip::DropInfo::DropInfo(int drop_index,
views::Widget* context)
: drop_index(drop_index),
drop_before(drop_before),
- point_down(point_down) {
+ point_down(point_down),
+ file_supported(true) {
arrow_view = new views::ImageView;
arrow_view->SetImage(GetDropArrowImage(point_down));
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h
index 8de46e8..7e01033 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.h
+++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -182,6 +182,9 @@ class TabStrip : public views::View,
// ongoing this does a layout.
void StopAnimating(bool layout);
+ // Called to indicate whether the given URL is a supported file.
+ void FileSupported(const GURL& url, bool supported);
+
// TabController overrides:
virtual const ui::ListSelectionModel& GetSelectionModel() OVERRIDE;
virtual bool SupportsMultipleSelection() OVERRIDE;
@@ -295,6 +298,12 @@ class TabStrip : public views::View,
views::Widget* arrow_window;
views::ImageView* arrow_view;
+ // The URL for the drop event.
+ GURL url;
+
+ // Whether the MIME type of the file pointed to by |url| is supported.
+ bool file_supported;
+
private:
DISALLOW_COPY_AND_ASSIGN(DropInfo);
};
diff --git a/chrome/browser/ui/views/tabs/tab_strip_controller.h b/chrome/browser/ui/views/tabs/tab_strip_controller.h
index afe7a23..95940f11 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_strip_controller.h
@@ -112,6 +112,10 @@ class TabStripController {
// This is also called when the tabs that the user is dragging were detached
// from this tabstrip but the user is still dragging the tabs.
virtual void OnStoppedDraggingTabs() = 0;
+
+ // Determines if the file type of the URL is supported. Should invoke
+ // TabStrip::FileSupported to report the result.
+ virtual void CheckFileSupported(const GURL& url) = 0;
};
#endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_CONTROLLER_H_