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.
5 #include "chrome/browser/ui/views/extensions/device_permissions_dialog_view.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "chrome/browser/extensions/api/chrome_device_permissions_prompt.h"
13 #include "chrome/grit/generated_resources.h"
14 #include "components/constrained_window/constrained_window_views.h"
15 #include "components/web_modal/web_contents_modal_dialog_manager.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "device/usb/usb_device.h"
18 #include "extensions/common/extension.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/models/table_model.h"
21 #include "ui/base/models/table_model_observer.h"
22 #include "ui/views/controls/label.h"
23 #include "ui/views/controls/table/table_view.h"
24 #include "ui/views/layout/box_layout.h"
25 #include "ui/views/layout/layout_constants.h"
27 using device::UsbDevice
;
28 using extensions::DevicePermissionsPrompt
;
30 class DevicePermissionsTableModel
31 : public ui::TableModel
,
32 public DevicePermissionsPrompt::Prompt::Observer
{
34 explicit DevicePermissionsTableModel(
35 scoped_refptr
<DevicePermissionsPrompt::Prompt
> prompt
)
37 prompt_
->SetObserver(this);
40 ~DevicePermissionsTableModel() override
{ prompt_
->SetObserver(nullptr); }
43 int RowCount() override
;
44 base::string16
GetText(int row
, int column
) override
;
45 void SetObserver(ui::TableModelObserver
* observer
) override
;
47 // extensions::DevicePermissionsPrompt::Prompt::Observer
48 void OnDevicesChanged() override
;
51 scoped_refptr
<DevicePermissionsPrompt::Prompt
> prompt_
;
52 ui::TableModelObserver
* observer_
= nullptr;
55 int DevicePermissionsTableModel::RowCount() {
56 return prompt_
->GetDeviceCount();
59 base::string16
DevicePermissionsTableModel::GetText(int row
, int col_id
) {
61 case IDS_DEVICE_PERMISSIONS_DIALOG_DEVICE_NAME_COLUMN
:
62 return prompt_
->GetDeviceName(row
);
63 case IDS_DEVICE_PERMISSIONS_DIALOG_SERIAL_NUMBER_COLUMN
:
64 return prompt_
->GetDeviceSerialNumber(row
);
67 return base::string16();
71 void DevicePermissionsTableModel::SetObserver(
72 ui::TableModelObserver
* observer
) {
76 void DevicePermissionsTableModel::OnDevicesChanged() {
78 observer_
->OnModelChanged();
82 DevicePermissionsDialogView::DevicePermissionsDialogView(
83 scoped_refptr
<DevicePermissionsPrompt::Prompt
> prompt
)
85 views::BoxLayout
* layout
=
86 new views::BoxLayout(views::BoxLayout::kVertical
,
87 views::kButtonHEdgeMarginNew
,
89 views::kRelatedControlVerticalSpacing
);
90 SetLayoutManager(layout
);
92 views::Label
* label
= new views::Label(prompt_
->GetPromptMessage());
93 label
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
94 label
->SetMultiLine(true);
97 std::vector
<ui::TableColumn
> table_columns
;
98 table_columns
.push_back(
99 ui::TableColumn(IDS_DEVICE_PERMISSIONS_DIALOG_DEVICE_NAME_COLUMN
,
100 ui::TableColumn::LEFT
,
103 table_columns
.back().title
= l10n_util::GetStringUTF16(
104 IDS_DEVICE_PERMISSIONS_DIALOG_DEVICE_NAME_COLUMN
);
105 table_columns
.push_back(
106 ui::TableColumn(IDS_DEVICE_PERMISSIONS_DIALOG_SERIAL_NUMBER_COLUMN
,
107 ui::TableColumn::LEFT
,
110 table_columns
.back().title
= l10n_util::GetStringUTF16(
111 IDS_DEVICE_PERMISSIONS_DIALOG_SERIAL_NUMBER_COLUMN
);
113 table_model_
.reset(new DevicePermissionsTableModel(prompt_
));
114 table_view_
= new views::TableView(table_model_
.get(),
117 !prompt_
->multiple());
119 views::View
* table_parent
= table_view_
->CreateParentIfNecessary();
120 AddChildView(table_parent
);
121 layout
->SetFlexForView(table_parent
, 1);
124 DevicePermissionsDialogView::~DevicePermissionsDialogView() {
125 RemoveAllChildViews(true);
128 void DevicePermissionsDialogView::DeleteDelegate() {
129 // Calling prompt_->Dismissed() here ensures it will be called regardless of
130 // how the view is closed, including shutdown of the entire view hierarchy.
131 prompt_
->Dismissed();
135 bool DevicePermissionsDialogView::Accept() {
136 for (int index
: table_view_
->selection_model().selected_indices()) {
137 prompt_
->GrantDevicePermission(index
);
142 base::string16
DevicePermissionsDialogView::GetDialogButtonLabel(
143 ui::DialogButton button
) const {
144 if (button
== ui::DIALOG_BUTTON_OK
) {
145 return l10n_util::GetStringUTF16(IDS_DEVICE_PERMISSIONS_DIALOG_SELECT
);
147 return views::DialogDelegateView::GetDialogButtonLabel(button
);
150 ui::ModalType
DevicePermissionsDialogView::GetModalType() const {
151 return ui::MODAL_TYPE_CHILD
;
154 base::string16
DevicePermissionsDialogView::GetWindowTitle() const {
155 return prompt_
->GetHeading();
158 gfx::Size
DevicePermissionsDialogView::GetPreferredSize() const {
159 return gfx::Size(500, 250);
162 void ChromeDevicePermissionsPrompt::ShowDialog() {
163 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
165 web_modal::WebContentsModalDialogManager
* manager
=
166 web_modal::WebContentsModalDialogManager::FromWebContents(web_contents());
168 constrained_window::ShowWebModalDialogViews(
169 new DevicePermissionsDialogView(prompt()), web_contents());
171 base::ThreadTaskRunnerHandle::Get()->PostTask(
173 base::Bind(&DevicePermissionsPrompt::Prompt::Dismissed
, prompt()));