BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / chrome / browser / ui / views / certificate_selector.cc
blob645a863984a1fa59db2fd80962e5a2abffdda0d7
1 // Copyright 2015 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.
5 #include "chrome/browser/ui/views/certificate_selector.h"
7 #include <stddef.h> // For size_t.
8 #include <string>
9 #include <vector>
11 #include "base/logging.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/certificate_viewer.h"
15 #include "chrome/grit/generated_resources.h"
16 #include "components/constrained_window/constrained_window_views.h"
17 #include "components/guest_view/browser/guest_view_base.h"
18 #include "components/web_modal/web_contents_modal_dialog_manager.h"
19 #include "content/public/browser/web_contents.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/models/table_model.h"
22 #include "ui/base/models/table_model_observer.h"
23 #include "ui/views/controls/button/label_button.h"
24 #include "ui/views/controls/table/table_view.h"
25 #include "ui/views/layout/grid_layout.h"
26 #include "ui/views/layout/layout_constants.h"
27 #include "ui/views/widget/widget.h"
28 #include "ui/views/window/dialog_client_view.h"
30 #if defined(OS_CHROMEOS)
31 #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h"
32 #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h"
33 #include "extensions/browser/extension_registry.h"
34 #include "extensions/browser/extension_registry_factory.h"
35 #endif
37 namespace chrome {
39 const int CertificateSelector::kTableViewWidth = 400;
40 const int CertificateSelector::kTableViewHeight = 100;
42 class CertificateSelector::CertificateTableModel : public ui::TableModel {
43 public:
44 // |certs| and |provider_names| must have the same size.
45 CertificateTableModel(const net::CertificateList& certs,
46 const std::vector<std::string>& provider_names);
48 // ui::TableModel:
49 int RowCount() override;
50 base::string16 GetText(int index, int column_id) override;
51 void SetObserver(ui::TableModelObserver* observer) override;
53 private:
54 struct Row {
55 base::string16 subject;
56 base::string16 issuer;
57 base::string16 provider;
59 std::vector<Row> rows_;
61 DISALLOW_COPY_AND_ASSIGN(CertificateTableModel);
64 CertificateSelector::CertificateTableModel::CertificateTableModel(
65 const net::CertificateList& certs,
66 const std::vector<std::string>& provider_names) {
67 DCHECK_EQ(certs.size(), provider_names.size());
68 for (size_t i = 0; i < certs.size(); i++) {
69 net::X509Certificate* cert = certs[i].get();
70 Row row;
71 row.subject = base::UTF8ToUTF16(cert->subject().GetDisplayName());
72 row.issuer = base::UTF8ToUTF16(cert->issuer().GetDisplayName());
73 row.provider = base::UTF8ToUTF16(provider_names[i]);
74 rows_.push_back(row);
78 int CertificateSelector::CertificateTableModel::RowCount() {
79 return rows_.size();
82 base::string16 CertificateSelector::CertificateTableModel::GetText(
83 int index,
84 int column_id) {
85 DCHECK_GE(index, 0);
86 DCHECK_LT(static_cast<size_t>(index), rows_.size());
88 const Row& row = rows_[index];
89 switch (column_id) {
90 case IDS_CERT_SELECTOR_SUBJECT_COLUMN:
91 return row.subject;
92 case IDS_CERT_SELECTOR_ISSUER_COLUMN:
93 return row.issuer;
94 case IDS_CERT_SELECTOR_PROVIDER_COLUMN:
95 return row.provider;
96 default:
97 NOTREACHED();
99 return base::string16();
102 void CertificateSelector::CertificateTableModel::SetObserver(
103 ui::TableModelObserver* observer) {}
105 CertificateSelector::CertificateSelector(
106 const net::CertificateList& certificates,
107 content::WebContents* web_contents)
108 : web_contents_(web_contents), table_(nullptr), view_cert_button_(nullptr) {
109 CHECK(web_contents_);
111 // |provider_names| and |certificates_| are parallel arrays.
112 // The entry at index |i| is the provider name for |certificates_[i]|.
113 std::vector<std::string> provider_names;
114 #if defined(OS_CHROMEOS)
115 chromeos::CertificateProviderService* service =
116 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
117 web_contents->GetBrowserContext());
118 extensions::ExtensionRegistry* extension_registry =
119 extensions::ExtensionRegistryFactory::GetForBrowserContext(
120 web_contents->GetBrowserContext());
122 for (const auto& cert : certificates) {
123 std::string provider_name;
124 bool has_extension = false;
125 std::string extension_id;
126 if (service->LookUpCertificate(*cert, &has_extension, &extension_id)) {
127 if (!has_extension) {
128 // This certificate was provided by an extension but isn't provided by
129 // any extension currently. Don't expose it to the user.
130 continue;
132 const auto extension = extension_registry->GetExtensionById(
133 extension_id, extensions::ExtensionRegistry::ENABLED);
134 if (!extension) {
135 // This extension was unloaded in the meantime. Don't show the
136 // certificate.
137 continue;
139 provider_name = extension->short_name();
140 show_provider_column_ = true;
141 } // Otherwise the certificate is provided by the platform.
143 certificates_.push_back(cert);
144 provider_names.push_back(provider_name);
146 #else
147 provider_names.assign(certificates.size(), std::string());
148 certificates_ = certificates;
149 #endif
151 model_.reset(new CertificateTableModel(certificates_, provider_names));
154 CertificateSelector::~CertificateSelector() {
155 table_->SetModel(nullptr);
158 // static
159 bool CertificateSelector::CanShow(content::WebContents* web_contents) {
160 // GetTopLevelWebContents returns |web_contents| if it is not a guest.
161 content::WebContents* top_level_web_contents =
162 guest_view::GuestViewBase::GetTopLevelWebContents(web_contents);
163 return web_modal::WebContentsModalDialogManager::FromWebContents(
164 top_level_web_contents) != nullptr;
167 void CertificateSelector::Show() {
168 constrained_window::ShowWebModalDialogViews(this, web_contents_);
170 // Select the first row automatically. This must be done after the dialog has
171 // been created.
172 table_->Select(0);
175 void CertificateSelector::InitWithText(scoped_ptr<views::View> text_label) {
176 views::GridLayout* const layout = views::GridLayout::CreatePanel(this);
177 SetLayoutManager(layout);
179 const int kColumnSetId = 0;
180 views::ColumnSet* const column_set = layout->AddColumnSet(kColumnSetId);
181 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
182 views::GridLayout::USE_PREF, 0, 0);
184 layout->StartRow(0, kColumnSetId);
185 layout->AddView(text_label.release());
187 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
189 std::vector<ui::TableColumn> columns;
190 columns.push_back(ui::TableColumn(IDS_CERT_SELECTOR_SUBJECT_COLUMN,
191 ui::TableColumn::LEFT, -1, 0.4f));
192 columns.push_back(ui::TableColumn(IDS_CERT_SELECTOR_ISSUER_COLUMN,
193 ui::TableColumn::LEFT, -1, 0.2f));
194 if (show_provider_column_) {
195 columns.push_back(ui::TableColumn(IDS_CERT_SELECTOR_PROVIDER_COLUMN,
196 ui::TableColumn::LEFT, -1, 0.4f));
198 table_ = new views::TableView(model_.get(), columns, views::TEXT_ONLY,
199 true /* single_selection */);
200 table_->SetObserver(this);
201 layout->StartRow(1, kColumnSetId);
202 layout->AddView(table_->CreateParentIfNecessary(), 1, 1,
203 views::GridLayout::FILL, views::GridLayout::FILL,
204 kTableViewWidth, kTableViewHeight);
206 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
209 net::X509Certificate* CertificateSelector::GetSelectedCert() const {
210 const int selected = table_->FirstSelectedRow();
211 if (selected < 0) // Nothing is selected in |table_|.
212 return nullptr;
213 CHECK_LT(static_cast<size_t>(selected), certificates_.size());
214 return certificates_[selected].get();
217 bool CertificateSelector::CanResize() const {
218 return true;
221 base::string16 CertificateSelector::GetWindowTitle() const {
222 return l10n_util::GetStringUTF16(IDS_CLIENT_CERT_DIALOG_TITLE);
225 bool CertificateSelector::IsDialogButtonEnabled(ui::DialogButton button) const {
226 return button != ui::DIALOG_BUTTON_OK || GetSelectedCert() != nullptr;
229 views::View* CertificateSelector::GetInitiallyFocusedView() {
230 DCHECK(table_);
231 return table_;
234 views::View* CertificateSelector::CreateExtraView() {
235 DCHECK(!view_cert_button_);
236 scoped_ptr<views::LabelButton> button(new views::LabelButton(
237 this, l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON)));
238 button->SetStyle(views::Button::STYLE_BUTTON);
239 view_cert_button_ = button.get();
240 return button.release();
243 ui::ModalType CertificateSelector::GetModalType() const {
244 return ui::MODAL_TYPE_CHILD;
247 void CertificateSelector::ButtonPressed(views::Button* sender,
248 const ui::Event& event) {
249 if (sender == view_cert_button_) {
250 net::X509Certificate* const cert = GetSelectedCert();
251 if (cert)
252 ShowCertificateViewer(web_contents_,
253 web_contents_->GetTopLevelNativeWindow(), cert);
257 void CertificateSelector::OnSelectionChanged() {
258 GetDialogClientView()->ok_button()->SetEnabled(GetSelectedCert() != nullptr);
261 void CertificateSelector::OnDoubleClick() {
262 if (GetSelectedCert())
263 GetDialogClientView()->AcceptWindow();
266 } // namespace chrome