external_protocol_dialog_gtk.cc revision dc0f95d653279beabeb9817299e2902918ba123e
172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/external_protocol_dialog_gtk.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gtk/gtk.h> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/metrics/histogram.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/external_protocol_handler.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_util.h" 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_util.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/text/text_elider.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kMessageWidth = 400; 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/////////////////////////////////////////////////////////////////////////////// 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExternalProtocolHandler 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExternalProtocolHandler::RunExternalProtocolDialog( 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, int render_process_host_id, int routing_id) { 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new ExternalProtocolDialogGtk(url); 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/////////////////////////////////////////////////////////////////////////////// 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExternalProtocolDialogGtk 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExternalProtocolDialogGtk::ExternalProtocolDialogGtk(const GURL& url) 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : url_(url), 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch creation_time_(base::TimeTicks::Now()) { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog_ = gtk_dialog_new_with_buttons( 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_TITLE).c_str(), 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_DIALOG_NO_SEPARATOR, 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add the response buttons. 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::AddButtonToDialog(dialog_, 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::GetStringUTF8( 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDS_EXTERNAL_PROTOCOL_CANCEL_BUTTON_TEXT).c_str(), 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT); 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::AddButtonToDialog(dialog_, 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT).c_str(), 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the message text. 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kMaxUrlWithoutSchemeSize = 256; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kMaxCommandSize = 256; 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen string16 elided_url_without_scheme; 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen string16 elided_command; 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ui::ElideString(ASCIIToUTF16(url.possibly_invalid_spec()), 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kMaxUrlWithoutSchemeSize, &elided_url_without_scheme); 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ui::ElideString(ASCIIToUTF16(std::string("xdg-open ") + url.spec()), 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kMaxCommandSize, &elided_command); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string message_text = l10n_util::GetStringFUTF8( 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDS_EXTERNAL_PROTOCOL_INFORMATION, 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASCIIToUTF16(url.scheme() + ":"), 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen elided_url_without_scheme) + "\n\n"; 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch message_text += l10n_util::GetStringFUTF8( 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen IDS_EXTERNAL_PROTOCOL_APPLICATION_TO_LAUNCH, elided_command) + "\n\n"; 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch message_text += l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_WARNING); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create the content-holding vbox. 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_set_border_width(GTK_CONTAINER(vbox), 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::kContentAreaBorder); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add the message text. 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* label = gtk_label_new(message_text.c_str()); 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen gtk_util::SetLabelWidth(label, kMessageWidth); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add the checkbox. 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch checkbox_ = gtk_check_button_new_with_label( 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_CHECKBOX_TEXT).c_str()); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(vbox), checkbox_, 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FALSE, FALSE, 0); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add our vbox to the dialog. 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), vbox, 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FALSE, FALSE, 0); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE); 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(dialog_); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 107dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenExternalProtocolDialogGtk::~ExternalProtocolDialogGtk() { 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ExternalProtocolDialogGtk::OnResponse(GtkWidget* dialog, int response_id) { 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox_))) { 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (response_id == GTK_RESPONSE_ACCEPT) { 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExternalProtocolHandler::SetBlockState( 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick url_.scheme(), ExternalProtocolHandler::DONT_BLOCK); 115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else if (response_id == GTK_RESPONSE_REJECT) { 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExternalProtocolHandler::SetBlockState( 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick url_.scheme(), ExternalProtocolHandler::BLOCK); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the response is GTK_RESPONSE_DELETE, triggered by the user closing 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the dialog, do nothing. 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (response_id == GTK_RESPONSE_ACCEPT) { 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url", 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeTicks::Now() - creation_time_); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url_); 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_destroy(dialog_); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete this; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 133