| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/views/external_protocol_dialog.h" | 5 #include "chrome/browser/views/external_protocol_dialog.h" |
| 6 | 6 |
| 7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
| 8 #include "app/message_box_flags.h" | 8 #include "app/message_box_flags.h" |
| 9 #include "base/histogram.h" | 9 #include "base/histogram.h" |
| 10 #include "base/registry.h" | 10 #include "base/registry.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "base/thread.h" | 12 #include "base/thread.h" |
| 13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 14 #include "chrome/browser/external_protocol_handler.h" | 14 #include "chrome/browser/external_protocol_handler.h" |
| 15 #include "chrome/browser/tab_contents/tab_contents.h" |
| 15 #include "chrome/browser/tab_contents/tab_util.h" | 16 #include "chrome/browser/tab_contents/tab_util.h" |
| 16 #include "chrome/browser/tab_contents/tab_contents.h" | |
| 17 #include "grit/chromium_strings.h" | 17 #include "grit/chromium_strings.h" |
| 18 #include "grit/generated_resources.h" | 18 #include "grit/generated_resources.h" |
| 19 #include "views/controls/message_box_view.h" | 19 #include "views/controls/message_box_view.h" |
| 20 #include "views/window/window.h" | 20 #include "views/window/window.h" |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 const int kMessageWidth = 400; | 24 const int kMessageWidth = 400; |
| 25 | 25 |
| 26 } // namespace | 26 } // namespace |
| 27 | 27 |
| 28 /////////////////////////////////////////////////////////////////////////////// | 28 /////////////////////////////////////////////////////////////////////////////// |
| 29 // ExternalProtocolDialog, public: | 29 // ExternalProtocolHandler |
| 30 | 30 |
| 31 // static | 31 // static |
| 32 void ExternalProtocolDialog::RunExternalProtocolDialog( | 32 void ExternalProtocolHandler::RunExternalProtocolDialog( |
| 33 const GURL& url, const std::wstring& command, int render_process_host_id, | 33 const GURL& url, int render_process_host_id, int routing_id) { |
| 34 int routing_id) { | 34 std::wstring command = |
| 35 ExternalProtocolDialog::GetApplicationForProtocol(url); |
| 36 if (command.empty()) { |
| 37 // ShellExecute won't do anything. Don't bother warning the user. |
| 38 return; |
| 39 } |
| 35 TabContents* tab_contents = tab_util::GetTabContentsByID( | 40 TabContents* tab_contents = tab_util::GetTabContentsByID( |
| 36 render_process_host_id, routing_id); | 41 render_process_host_id, routing_id); |
| 37 ExternalProtocolDialog* handler = | 42 ExternalProtocolDialog* handler = |
| 38 new ExternalProtocolDialog(tab_contents, url, command); | 43 new ExternalProtocolDialog(tab_contents, url, command); |
| 39 } | 44 } |
| 40 | 45 |
| 46 /////////////////////////////////////////////////////////////////////////////// |
| 47 // ExternalProtocolDialog |
| 48 |
| 41 ExternalProtocolDialog::~ExternalProtocolDialog() { | 49 ExternalProtocolDialog::~ExternalProtocolDialog() { |
| 42 } | 50 } |
| 43 | 51 |
| 44 ////////////////////////////////////////////////////////////////////////////// | 52 ////////////////////////////////////////////////////////////////////////////// |
| 45 // ExternalProtocolDialog, views::DialogDelegate implementation: | 53 // ExternalProtocolDialog, views::DialogDelegate implementation: |
| 46 | 54 |
| 47 int ExternalProtocolDialog::GetDefaultDialogButton() const { | 55 int ExternalProtocolDialog::GetDefaultDialogButton() const { |
| 48 return MessageBoxFlags::DIALOGBUTTON_CANCEL; | 56 return MessageBoxFlags::DIALOGBUTTON_CANCEL; |
| 49 } | 57 } |
| 50 | 58 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 65 delete this; | 73 delete this; |
| 66 } | 74 } |
| 67 | 75 |
| 68 bool ExternalProtocolDialog::Accept() { | 76 bool ExternalProtocolDialog::Accept() { |
| 69 // We record how long it takes the user to accept an external protocol. If | 77 // We record how long it takes the user to accept an external protocol. If |
| 70 // users start accepting these dialogs too quickly, we should worry about | 78 // users start accepting these dialogs too quickly, we should worry about |
| 71 // clickjacking. | 79 // clickjacking. |
| 72 UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url", | 80 UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url", |
| 73 base::Time::Now() - creation_time_); | 81 base::Time::Now() - creation_time_); |
| 74 | 82 |
| 75 MessageLoop* io_loop = g_browser_process->io_thread()->message_loop(); | 83 ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url_); |
| 76 if (io_loop == NULL) { | 84 // Returning true closes the dialog. |
| 77 // Returning true closes the dialog. | |
| 78 return true; | |
| 79 } | |
| 80 | |
| 81 // Attempt to launch the application on the IO loop. | |
| 82 io_loop->PostTask(FROM_HERE, | |
| 83 NewRunnableFunction( | |
| 84 &ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck, url_)); | |
| 85 return true; | 85 return true; |
| 86 } | 86 } |
| 87 | 87 |
| 88 views::View* ExternalProtocolDialog::GetContentsView() { | 88 views::View* ExternalProtocolDialog::GetContentsView() { |
| 89 return message_box_view_; | 89 return message_box_view_; |
| 90 } | 90 } |
| 91 | 91 |
| 92 /////////////////////////////////////////////////////////////////////////////// | 92 /////////////////////////////////////////////////////////////////////////////// |
| 93 // ExternalProtocolDialog, private: | 93 // ExternalProtocolDialog, private: |
| 94 | 94 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 116 if (tab_contents_) { | 116 if (tab_contents_) { |
| 117 root_hwnd = GetAncestor(tab_contents_->GetContentNativeView(), GA_ROOT); | 117 root_hwnd = GetAncestor(tab_contents_->GetContentNativeView(), GA_ROOT); |
| 118 } else { | 118 } else { |
| 119 // Dialog is top level if we don't have a tab_contents associated with us. | 119 // Dialog is top level if we don't have a tab_contents associated with us. |
| 120 root_hwnd = NULL; | 120 root_hwnd = NULL; |
| 121 } | 121 } |
| 122 | 122 |
| 123 views::Window::CreateChromeWindow(root_hwnd, gfx::Rect(), this)->Show(); | 123 views::Window::CreateChromeWindow(root_hwnd, gfx::Rect(), this)->Show(); |
| 124 } | 124 } |
| 125 | 125 |
| 126 /* static */ | 126 // static |
| 127 std::wstring ExternalProtocolDialog::GetApplicationForProtocol( | 127 std::wstring ExternalProtocolDialog::GetApplicationForProtocol( |
| 128 const GURL& url) { | 128 const GURL& url) { |
| 129 std::wstring url_spec = ASCIIToWide(url.possibly_invalid_spec()); | 129 std::wstring url_spec = ASCIIToWide(url.possibly_invalid_spec()); |
| 130 std::wstring cmd_key_path = | 130 std::wstring cmd_key_path = |
| 131 ASCIIToWide(url.scheme() + "\\shell\\open\\command"); | 131 ASCIIToWide(url.scheme() + "\\shell\\open\\command"); |
| 132 RegKey cmd_key(HKEY_CLASSES_ROOT, cmd_key_path.c_str(), KEY_READ); | 132 RegKey cmd_key(HKEY_CLASSES_ROOT, cmd_key_path.c_str(), KEY_READ); |
| 133 size_t split_offset = url_spec.find(L':'); | 133 size_t split_offset = url_spec.find(L':'); |
| 134 if (split_offset == std::wstring::npos) | 134 if (split_offset == std::wstring::npos) |
| 135 return std::wstring(); | 135 return std::wstring(); |
| 136 std::wstring parameters = url_spec.substr(split_offset + 1, | 136 std::wstring parameters = url_spec.substr(split_offset + 1, |
| 137 url_spec.length() - 1); | 137 url_spec.length() - 1); |
| 138 std::wstring application_to_launch; | 138 std::wstring application_to_launch; |
| 139 if (cmd_key.ReadValue(NULL, &application_to_launch)) { | 139 if (cmd_key.ReadValue(NULL, &application_to_launch)) { |
| 140 ReplaceSubstringsAfterOffset(&application_to_launch, 0, L"%1", parameters); | 140 ReplaceSubstringsAfterOffset(&application_to_launch, 0, L"%1", parameters); |
| 141 return application_to_launch; | 141 return application_to_launch; |
| 142 } else { | 142 } else { |
| 143 return std::wstring(); | 143 return std::wstring(); |
| 144 } | 144 } |
| 145 } | 145 } |
| OLD | NEW |