signed_certificate_timestamps_views.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/views/signed_certificate_timestamps_views.h" 6 7#include "base/strings/stringprintf.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/browser/chrome_notification_types.h" 10#include "chrome/browser/ui/views/constrained_window_views.h" 11#include "chrome/browser/ui/views/signed_certificate_timestamp_info_view.h" 12#include "components/web_modal/web_contents_modal_dialog_host.h" 13#include "components/web_modal/web_contents_modal_dialog_manager.h" 14#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" 15#include "content/public/browser/notification_source.h" 16#include "content/public/browser/signed_certificate_timestamp_store.h" 17#include "content/public/common/signed_certificate_timestamp_id_and_status.h" 18#include "grit/generated_resources.h" 19#include "net/cert/signed_certificate_timestamp.h" 20#include "net/ssl/signed_certificate_timestamp_and_status.h" 21#include "ui/base/l10n/l10n_util.h" 22#include "ui/base/models/combobox_model.h" 23#include "ui/views/controls/combobox/combobox.h" 24#include "ui/views/layout/grid_layout.h" 25#include "ui/views/layout/layout_constants.h" 26#include "ui/views/widget/widget.h" 27 28using web_modal::WebContentsModalDialogManager; 29using web_modal::WebContentsModalDialogManagerDelegate; 30using views::GridLayout; 31 32namespace { 33 34void SignedCertificateTimestampIDsToList( 35 const content::SignedCertificateTimestampIDStatusList& sct_ids_list, 36 net::SignedCertificateTimestampAndStatusList* sct_list) { 37 for (content::SignedCertificateTimestampIDStatusList::const_iterator it = 38 sct_ids_list.begin(); 39 it != sct_ids_list.end(); 40 ++it) { 41 scoped_refptr<net::ct::SignedCertificateTimestamp> sct; 42 content::SignedCertificateTimestampStore::GetInstance()->Retrieve(it->id, 43 &sct); 44 sct_list->push_back( 45 net::SignedCertificateTimestampAndStatus(sct, it->status)); 46 } 47} 48 49} // namespace 50 51namespace chrome { 52 53void ShowSignedCertificateTimestampsViewer( 54 content::WebContents* web_contents, 55 const content::SignedCertificateTimestampIDStatusList& sct_ids_list) { 56 net::SignedCertificateTimestampAndStatusList sct_list; 57 SignedCertificateTimestampIDsToList(sct_ids_list, &sct_list); 58 new SignedCertificateTimestampsViews(web_contents, sct_list); 59} 60 61} // namespace chrome 62 63class SCTListModel : public ui::ComboboxModel { 64 public: 65 explicit SCTListModel( 66 const net::SignedCertificateTimestampAndStatusList& sct_list); 67 virtual ~SCTListModel(); 68 69 // Overridden from ui::ComboboxModel: 70 virtual int GetItemCount() const OVERRIDE; 71 virtual base::string16 GetItemAt(int index) OVERRIDE; 72 73 private: 74 net::SignedCertificateTimestampAndStatusList sct_list_; 75 76 DISALLOW_COPY_AND_ASSIGN(SCTListModel); 77}; 78 79SCTListModel::SCTListModel( 80 const net::SignedCertificateTimestampAndStatusList& sct_list) 81 : sct_list_(sct_list) {} 82 83SCTListModel::~SCTListModel() {} 84 85int SCTListModel::GetItemCount() const { return sct_list_.size(); } 86 87base::string16 SCTListModel::GetItemAt(int index) { 88 DCHECK_LT(static_cast<size_t>(index), sct_list_.size()); 89 std::string origin = l10n_util::GetStringUTF8( 90 chrome::ct::SCTOriginToResourceID(*(sct_list_[index].sct))); 91 92 std::string status = l10n_util::GetStringUTF8( 93 chrome::ct::StatusToResourceID(sct_list_[index].status)); 94 95 // TODO(eranm): Internationalization: If the locale is a RTL one, 96 // format the string so that the index is on the right, status 97 // and origin on the left. Specifically: the format part should be a 98 // localized IDS string where the placeholders get rearranged for RTL locales, 99 // GetStringFUTF16 is used to replace the placeholders with these 100 // origin/status strings and the numbered index. 101 return base::UTF8ToUTF16(base::StringPrintf( 102 "%d: %s, %s", index + 1, origin.c_str(), status.c_str())); 103} 104 105SignedCertificateTimestampsViews::SignedCertificateTimestampsViews( 106 content::WebContents* web_contents, 107 const net::SignedCertificateTimestampAndStatusList& sct_list) 108 : web_contents_(web_contents), sct_info_view_(NULL), sct_list_(sct_list) { 109 WebContentsModalDialogManager* web_contents_modal_dialog_manager = 110 WebContentsModalDialogManager::FromWebContents(web_contents); 111 WebContentsModalDialogManagerDelegate* modal_delegate = 112 web_contents_modal_dialog_manager->delegate(); 113 DCHECK(modal_delegate); 114 views::Widget* window = views::Widget::CreateWindowAsFramelessChild( 115 this, modal_delegate->GetWebContentsModalDialogHost()->GetHostView()); 116 web_contents_modal_dialog_manager->ShowDialog(window->GetNativeView()); 117} 118 119SignedCertificateTimestampsViews::~SignedCertificateTimestampsViews() {} 120 121base::string16 SignedCertificateTimestampsViews::GetWindowTitle() const { 122 return l10n_util::GetStringUTF16(IDS_SCT_VIEWER_TITLE); 123} 124 125int SignedCertificateTimestampsViews::GetDialogButtons() const { 126 return ui::DIALOG_BUTTON_CANCEL; 127} 128 129ui::ModalType SignedCertificateTimestampsViews::GetModalType() const { 130#if defined(USE_ASH) 131 return ui::MODAL_TYPE_CHILD; 132#else 133 return views::WidgetDelegate::GetModalType(); 134#endif 135} 136 137void SignedCertificateTimestampsViews::OnPerformAction( 138 views::Combobox* combobox) { 139 DCHECK_EQ(combobox, sct_selector_box_.get()); 140 DCHECK_LT(combobox->selected_index(), sct_list_model_->GetItemCount()); 141 ShowSCTInfo(combobox->selected_index()); 142} 143 144gfx::Size SignedCertificateTimestampsViews::GetMinimumSize() { 145 // Allow UpdateWebContentsModalDialogPosition to clamp the dialog width. 146 return gfx::Size(View::GetMinimumSize().width() + 300, 147 View::GetMinimumSize().height()); 148} 149 150void SignedCertificateTimestampsViews::ViewHierarchyChanged( 151 const ViewHierarchyChangedDetails& details) { 152 if (details.is_add && details.child == this) 153 Init(); 154} 155 156void SignedCertificateTimestampsViews::Init() { 157 GridLayout* layout = GridLayout::CreatePanel(this); 158 SetLayoutManager(layout); 159 160 const int kSelectorBoxLayoutId = 0; 161 views::ColumnSet* column_set = layout->AddColumnSet(kSelectorBoxLayoutId); 162 column_set->AddColumn( 163 GridLayout::FILL, GridLayout::FILL, 1, GridLayout::USE_PREF, 0, 0); 164 165 layout->StartRow(0, kSelectorBoxLayoutId); 166 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 167 168 // Add SCT selector drop-down list. 169 layout->StartRow(0, kSelectorBoxLayoutId); 170 sct_list_model_.reset(new SCTListModel(sct_list_)); 171 sct_selector_box_.reset(new views::Combobox(sct_list_model_.get())); 172 sct_selector_box_->set_listener(this); 173 sct_selector_box_->set_owned_by_client(); 174 layout->AddView(sct_selector_box_.get()); 175 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 176 177 // Add the SCT info view, displaying information about a specific SCT. 178 layout->StartRow(0, kSelectorBoxLayoutId); 179 sct_info_view_ = new SignedCertificateTimestampInfoView(); 180 layout->AddView(sct_info_view_); 181 182 sct_info_view_->SetSignedCertificateTimestamp(*(sct_list_[0].sct), 183 sct_list_[0].status); 184} 185 186void SignedCertificateTimestampsViews::ShowSCTInfo(int sct_index) { 187 if ((sct_index < 0) || (static_cast<size_t>(sct_index) > sct_list_.size())) 188 return; 189 190 sct_info_view_->SetSignedCertificateTimestamp(*(sct_list_[sct_index].sct), 191 sct_list_[sct_index].status); 192} 193 194void SignedCertificateTimestampsViews::Observe( 195 int type, 196 const content::NotificationSource& source, 197 const content::NotificationDetails& details) { 198 GetWidget()->Close(); 199} 200