summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-03 21:33:21 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-03 21:33:21 +0000
commit10f57b9be42b705fd1bed1a97acd90c8c885c396 (patch)
tree77d5fbbace6a41dc28ace3b4f573fc917aae61da /chrome
parentdf891031f2d5bd26eccd180fea4deb4797dd7a60 (diff)
downloadchromium_src-10f57b9be42b705fd1bed1a97acd90c8c885c396.zip
chromium_src-10f57b9be42b705fd1bed1a97acd90c8c885c396.tar.gz
chromium_src-10f57b9be42b705fd1bed1a97acd90c8c885c396.tar.bz2
Add external protocol dialog for Linux.
This exposes a bug where \n in a string resource is rendered literally when it is displayed. I don't know at what point on Windows the '\' + 'n' is translated to a line return, I have filed crbug.com/20943 BUG=20731 Review URL: http://codereview.chromium.org/194002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25373 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/external_protocol_handler.cc48
-rw-r--r--chrome/browser/external_protocol_handler.h24
-rw-r--r--chrome/browser/gtk/external_protocol_dialog_gtk.cc92
-rw-r--r--chrome/browser/gtk/external_protocol_dialog_gtk.h29
-rw-r--r--chrome/browser/views/external_protocol_dialog.cc34
-rw-r--r--chrome/browser/views/external_protocol_dialog.h33
-rw-r--r--chrome/chrome.gyp2
7 files changed, 182 insertions, 80 deletions
diff --git a/chrome/browser/external_protocol_handler.cc b/chrome/browser/external_protocol_handler.cc
index 59f7a23..3bfbb6e6 100644
--- a/chrome/browser/external_protocol_handler.cc
+++ b/chrome/browser/external_protocol_handler.cc
@@ -20,10 +20,6 @@
#include "googleurl/src/gurl.h"
#include "net/base/escape.h"
-#if defined(OS_WIN)
-#include "chrome/browser/views/external_protocol_dialog.h"
-#endif
-
// static
void ExternalProtocolHandler::PrepopulateDictionary(DictionaryValue* win_pref) {
static bool is_warm = false;
@@ -116,36 +112,27 @@ void ExternalProtocolHandler::LaunchUrl(const GURL& url,
if (block_state == BLOCK)
return;
-#if defined(OS_WIN)
if (block_state == UNKNOWN) {
- std::wstring command = ExternalProtocolDialog::GetApplicationForProtocol(
- escaped_url);
- if (command.empty()) {
- // ShellExecute won't do anything. Don't bother warning the user.
- return;
- }
-
+#if !defined(OS_MACOSX)
// Ask the user if they want to allow the protocol. This will call
// LaunchUrlWithoutSecurityCheck if the user decides to accept the protocol.
- ExternalProtocolDialog::RunExternalProtocolDialog(escaped_url,
- command,
- render_process_host_id,
- tab_contents_id);
+ RunExternalProtocolDialog(escaped_url,
+ render_process_host_id,
+ tab_contents_id);
+#endif
+ // For now, allow only whitelisted protocols to fire on Mac.
+ // See http://crbug.com/15546.
return;
}
-#else
- // For now, allow only whitelisted protocols to fire.
- // TODO(port): implement dialog for Mac/Linux.
- // See http://code.google.com/p/chromium/issues/detail?id=20731
- // and http://code.google.com/p/chromium/issues/detail?id=15546.
- if (block_state == UNKNOWN)
- return;
-#endif
- // Otherwise the protocol is white-listed, so go ahead and launch.
+ LaunchUrlWithoutSecurityCheck(escaped_url);
+}
+
+// static
+void ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(const GURL& url) {
#if defined(OS_MACOSX)
// This must run on the main thread on OS X.
- LaunchUrlWithoutSecurityCheck(escaped_url);
+ platform_util::OpenExternal(url);
#else
// Otherwise put this work on the file thread. On Windows ShellExecute may
// block for a significant amount of time, and it shouldn't hurt on Linux.
@@ -155,18 +142,11 @@ void ExternalProtocolHandler::LaunchUrl(const GURL& url,
}
loop->PostTask(FROM_HERE,
- NewRunnableFunction(
- &ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck,
- escaped_url));
+ NewRunnableFunction(&platform_util::OpenExternal, url));
#endif
}
// static
-void ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(const GURL& url) {
- platform_util::OpenExternal(url);
-}
-
-// static
void ExternalProtocolHandler::RegisterPrefs(PrefService* prefs) {
prefs->RegisterDictionaryPref(prefs::kExcludedSchemes);
}
diff --git a/chrome/browser/external_protocol_handler.h b/chrome/browser/external_protocol_handler.h
index 20a1375..5089d2c0 100644
--- a/chrome/browser/external_protocol_handler.h
+++ b/chrome/browser/external_protocol_handler.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_EXTERNAL_PROTOCOL_HANDLER_H__
-#define CHROME_BROWSER_EXTERNAL_PROTOCOL_HANDLER_H__
+#ifndef CHROME_BROWSER_EXTERNAL_PROTOCOL_HANDLER_H_
+#define CHROME_BROWSER_EXTERNAL_PROTOCOL_HANDLER_H_
#include <string>
@@ -33,6 +33,20 @@ class ExternalProtocolHandler {
static void LaunchUrl(const GURL& url, int render_process_host_id,
int tab_contents_id);
+ // Creates and runs a External Protocol dialog box.
+ // |url| - The url of the request.
+ // |render_process_host_id| and |routing_id| are used by
+ // tab_util::GetTabContentsByID to aquire the tab contents associated with
+ // this dialog.
+ // NOTE: There is a race between the Time of Check and the Time Of Use for
+ // the command line. Since the caller (web page) does not have access
+ // to change the command line by itself, we do not do anything special
+ // to protect against this scenario.
+ // This is implemented separately on each platform.
+ static void RunExternalProtocolDialog(const GURL& url,
+ int render_process_host_id,
+ int routing_id);
+
// Register the ExcludedSchemes preference.
static void RegisterPrefs(PrefService* prefs);
@@ -44,7 +58,7 @@ class ExternalProtocolHandler {
// NOTE: You should Not call this function directly unless you are sure the
// url you have has been checked against the blacklist, and has been escaped.
// All calls to this function should originate in some way from LaunchUrl.
- // Must run on the file thread.
+ // This will execute on the file thread.
static void LaunchUrlWithoutSecurityCheck(const GURL& url);
// Prepopulates the dictionary with known protocols to deny or allow, if
@@ -52,4 +66,4 @@ class ExternalProtocolHandler {
static void PrepopulateDictionary(DictionaryValue* win_pref);
};
-#endif // CHROME_BROWSER_EXTERNAL_PROTOCOL_HANDLER_H__
+#endif // CHROME_BROWSER_EXTERNAL_PROTOCOL_HANDLER_H_
diff --git a/chrome/browser/gtk/external_protocol_dialog_gtk.cc b/chrome/browser/gtk/external_protocol_dialog_gtk.cc
new file mode 100644
index 0000000..538579e
--- /dev/null
+++ b/chrome/browser/gtk/external_protocol_dialog_gtk.cc
@@ -0,0 +1,92 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/gtk/external_protocol_dialog_gtk.h"
+
+#include <gtk/gtk.h>
+
+#include "app/l10n_util.h"
+#include "base/histogram.h"
+#include "chrome/browser/external_protocol_handler.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/browser/tab_contents/tab_util.h"
+#include "chrome/common/gtk_util.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+
+namespace {
+
+const int kMessageWidth = 400;
+
+} // namespace
+
+///////////////////////////////////////////////////////////////////////////////
+// ExternalProtocolHandler
+
+// static
+void ExternalProtocolHandler::RunExternalProtocolDialog(
+ const GURL& url, int render_process_host_id, int routing_id) {
+ TabContents* tab_contents = tab_util::GetTabContentsByID(
+ render_process_host_id, routing_id);
+ new ExternalProtocolDialogGtk(url, tab_contents);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// ExternalProtocolDialogGtk
+
+ExternalProtocolDialogGtk::ExternalProtocolDialogGtk(
+ const GURL& url, TabContents* tab_contents)
+ : url_(url),
+ creation_time_(base::Time::Now()) {
+ GtkWindow* parent = tab_contents ?
+ tab_contents->view()->GetTopLevelNativeWindow() : NULL;
+
+ dialog_ = gtk_dialog_new_with_buttons(
+ l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_TITLE).c_str(),
+ parent,
+ (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_REJECT,
+ NULL);
+
+ gtk_util::AddButtonToDialog(dialog_,
+ l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT).c_str(),
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+
+ std::string message_text = l10n_util::GetStringFUTF8(
+ IDS_EXTERNAL_PROTOCOL_INFORMATION,
+ ASCIIToUTF16(url.scheme() + ":"),
+ ASCIIToUTF16(url.possibly_invalid_spec())) + "\n\n";
+
+ message_text += l10n_util::GetStringFUTF8(
+ IDS_EXTERNAL_PROTOCOL_APPLICATION_TO_LAUNCH,
+ ASCIIToUTF16(std::string("xdg-open ") + url.spec())) + "\n\n";
+
+ message_text += l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_WARNING);
+
+ GtkWidget* label = gtk_label_new(message_text.c_str());
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+ gtk_widget_set_size_request(label, kMessageWidth, -1);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), label, TRUE, TRUE, 0);
+
+ g_signal_connect(dialog_, "response",
+ G_CALLBACK(OnDialogResponse), this);
+
+ gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE);
+ gtk_widget_show_all(dialog_);
+}
+
+void ExternalProtocolDialogGtk::OnDialogResponse(GtkWidget* widget,
+ int response, ExternalProtocolDialogGtk* dialog) {
+ if (response == GTK_RESPONSE_ACCEPT) {
+ UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url",
+ base::Time::Now() - dialog->creation_time_);
+
+ ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(dialog->url_);
+ }
+
+ gtk_widget_destroy(widget);
+ delete dialog;
+}
diff --git a/chrome/browser/gtk/external_protocol_dialog_gtk.h b/chrome/browser/gtk/external_protocol_dialog_gtk.h
new file mode 100644
index 0000000..17d9e61
--- /dev/null
+++ b/chrome/browser/gtk/external_protocol_dialog_gtk.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_GTK_EXTERNAL_PROTOCOL_DIALOG_GTK_H_
+#define CHROME_BROWSER_GTK_EXTERNAL_PROTOCOL_DIALOG_GTK_H_
+
+#include "base/time.h"
+#include "googleurl/src/gurl.h"
+
+class TabContents;
+
+typedef struct _GtkWidget GtkWidget;
+
+class ExternalProtocolDialogGtk {
+ public:
+ ExternalProtocolDialogGtk(const GURL& url, TabContents* tab_contents);
+
+ private:
+ static void OnDialogResponse(GtkWidget* widget,
+ int response,
+ ExternalProtocolDialogGtk* dialog);
+
+ GtkWidget* dialog_;
+ GURL url_;
+ base::Time creation_time_;
+};
+
+#endif // CHROME_BROWSER_GTK_EXTERNAL_PROTOCOL_DIALOG_GTK_H_
diff --git a/chrome/browser/views/external_protocol_dialog.cc b/chrome/browser/views/external_protocol_dialog.cc
index 2feb0d7..4240e21 100644
--- a/chrome/browser/views/external_protocol_dialog.cc
+++ b/chrome/browser/views/external_protocol_dialog.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,8 +12,8 @@
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/external_protocol_handler.h"
-#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_util.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "views/controls/message_box_view.h"
@@ -26,18 +26,26 @@ const int kMessageWidth = 400;
} // namespace
///////////////////////////////////////////////////////////////////////////////
-// ExternalProtocolDialog, public:
+// ExternalProtocolHandler
// static
-void ExternalProtocolDialog::RunExternalProtocolDialog(
- const GURL& url, const std::wstring& command, int render_process_host_id,
- int routing_id) {
+void ExternalProtocolHandler::RunExternalProtocolDialog(
+ const GURL& url, int render_process_host_id, int routing_id) {
+ std::wstring command =
+ ExternalProtocolDialog::GetApplicationForProtocol(url);
+ if (command.empty()) {
+ // ShellExecute won't do anything. Don't bother warning the user.
+ return;
+ }
TabContents* tab_contents = tab_util::GetTabContentsByID(
render_process_host_id, routing_id);
ExternalProtocolDialog* handler =
new ExternalProtocolDialog(tab_contents, url, command);
}
+///////////////////////////////////////////////////////////////////////////////
+// ExternalProtocolDialog
+
ExternalProtocolDialog::~ExternalProtocolDialog() {
}
@@ -72,16 +80,8 @@ bool ExternalProtocolDialog::Accept() {
UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url",
base::Time::Now() - creation_time_);
- MessageLoop* io_loop = g_browser_process->io_thread()->message_loop();
- if (io_loop == NULL) {
- // Returning true closes the dialog.
- return true;
- }
-
- // Attempt to launch the application on the IO loop.
- io_loop->PostTask(FROM_HERE,
- NewRunnableFunction(
- &ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck, url_));
+ ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url_);
+ // Returning true closes the dialog.
return true;
}
@@ -123,7 +123,7 @@ ExternalProtocolDialog::ExternalProtocolDialog(TabContents* tab_contents,
views::Window::CreateChromeWindow(root_hwnd, gfx::Rect(), this)->Show();
}
-/* static */
+// static
std::wstring ExternalProtocolDialog::GetApplicationForProtocol(
const GURL& url) {
std::wstring url_spec = ASCIIToWide(url.possibly_invalid_spec());
diff --git a/chrome/browser/views/external_protocol_dialog.h b/chrome/browser/views/external_protocol_dialog.h
index d74df51..c9e5199 100644
--- a/chrome/browser/views/external_protocol_dialog.h
+++ b/chrome/browser/views/external_protocol_dialog.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_EXTERNAL_PROTOCOL_DIALOG_H__
-#define CHROME_BROWSER_EXTERNAL_PROTOCOL_DIALOG_H__
+#ifndef CHROME_BROWSER_EXTERNAL_PROTOCOL_DIALOG_H_
+#define CHROME_BROWSER_EXTERNAL_PROTOCOL_DIALOG_H_
#include "base/time.h"
#include "googleurl/src/gurl.h"
@@ -14,20 +14,10 @@ class TabContents;
class ExternalProtocolDialog : public views::DialogDelegate {
public:
- // Creates and runs a External Protocol dialog box.
- // |url| - The url of the request.
- // |command| - the command that ShellExecute will run.
- // |render_process_host_id| and |routing_id| are used by
- // tab_util::GetTabContentsByID to aquire the tab contents associated with
- // this dialog.
- // NOTE: There is a race between the Time of Check and the Time Of Use for
- // the command line. Since the caller (web page) does not have access
- // to change the command line by itself, we do not do anything special
- // to protect against this scenario.
- static void RunExternalProtocolDialog(const GURL& url,
- const std::wstring& command,
- int render_process_host_id,
- int routing_id);
+ // RunExternalProtocolDialog calls this private constructor.
+ ExternalProtocolDialog(TabContents* tab_contents,
+ const GURL& url,
+ const std::wstring& command);
// Returns the path of the application to be launched given the protocol
// of the requested url. Returns an empty string on failure.
@@ -49,11 +39,6 @@ class ExternalProtocolDialog : public views::DialogDelegate {
virtual bool IsModal() const { return false; }
private:
- // RunExternalProtocolDialog calls this private constructor.
- ExternalProtocolDialog(TabContents* tab_contents,
- const GURL& url,
- const std::wstring& command);
-
// The message box view whose commands we handle.
MessageBoxView* message_box_view_;
@@ -66,7 +51,7 @@ class ExternalProtocolDialog : public views::DialogDelegate {
// The time at which this dialog was created.
base::Time creation_time_;
- DISALLOW_EVIL_CONSTRUCTORS(ExternalProtocolDialog);
+ DISALLOW_COPY_AND_ASSIGN(ExternalProtocolDialog);
};
-#endif // CHROME_BROWSER_EXTERNAL_PROTOCOL_DIALOG_H__
+#endif // CHROME_BROWSER_EXTERNAL_PROTOCOL_DIALOG_H_
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index c7e50f3..6563807 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1246,6 +1246,8 @@
'browser/gtk/extension_shelf_gtk.h',
'browser/gtk/extension_view_gtk.cc',
'browser/gtk/extension_view_gtk.h',
+ 'browser/gtk/external_protocol_dialog_gtk.cc',
+ 'browser/gtk/external_protocol_dialog_gtk.h',
'browser/gtk/find_bar_gtk.cc',
'browser/gtk/find_bar_gtk.h',
'browser/gtk/first_run_bubble.cc',