Show throbber while initializing chooser permission prompt
This change enables the throbber and status message that are used for
the Web Bluetooth device chooser prompt on all of the other APIs which
use this UI. This improves the user experience for users on slower
devices where it can take some time for the set of available options to
be available.
Bug: 1160147
Change-Id: I59a03c1a94f58fdb38bf7c8d2d713680cb21c5aa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2597903
Reviewed-by: Olivier Yiptong <[email protected]>
Reviewed-by: Connie Wan <[email protected]>
Commit-Queue: Reilly Grant <[email protected]>
Cr-Commit-Position: refs/heads/master@{#843207}
diff --git a/chrome/browser/chooser_controller/chooser_controller.cc b/chrome/browser/chooser_controller/chooser_controller.cc
index df95777..f9abcfc 100644
--- a/chrome/browser/chooser_controller/chooser_controller.cc
+++ b/chrome/browser/chooser_controller/chooser_controller.cc
@@ -120,10 +120,6 @@
NOTREACHED();
}
-base::string16 ChooserController::GetStatus() const {
- return base::string16();
-}
-
void ChooserController::OpenAdapterOffHelpUrl() const {
NOTREACHED();
}
diff --git a/chrome/browser/chooser_controller/chooser_controller.h b/chrome/browser/chooser_controller/chooser_controller.h
index 119ee81..99325e3 100644
--- a/chrome/browser/chooser_controller/chooser_controller.h
+++ b/chrome/browser/chooser_controller/chooser_controller.h
@@ -94,6 +94,11 @@
// Returns the label for SelectAll checkbox.
virtual base::string16 GetSelectAllCheckboxLabel() const;
+ // Returns the label for the throbber shown while options are initializing or
+ // a re-scan is in progress.
+ virtual std::pair<base::string16, base::string16> GetThrobberLabelAndTooltip()
+ const = 0;
+
// Returns whether both OK and Cancel buttons are enabled.
//
// For chooser used in Web APIs such as WebBluetooth, WebUSB,
@@ -137,9 +142,6 @@
// Refresh the list of options.
virtual void RefreshOptions();
- // Returns the status text to be shown in the chooser.
- virtual base::string16 GetStatus() const;
-
// These three functions are called just before this object is destroyed:
// Called when the user selects elements from the dialog. |indices| contains
diff --git a/chrome/browser/chooser_controller/fake_bluetooth_chooser_controller.cc b/chrome/browser/chooser_controller/fake_bluetooth_chooser_controller.cc
index c2bff4b..b0e0352 100644
--- a/chrome/browser/chooser_controller/fake_bluetooth_chooser_controller.cc
+++ b/chrome/browser/chooser_controller/fake_bluetooth_chooser_controller.cc
@@ -38,6 +38,14 @@
IDS_BLUETOOTH_DEVICE_CHOOSER_PAIR_BUTTON_TEXT);
}
+std::pair<base::string16, base::string16>
+FakeBluetoothChooserController::GetThrobberLabelAndTooltip() const {
+ return {
+ l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING_LABEL),
+ l10n_util::GetStringUTF16(
+ IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING_LABEL_TOOLTIP)};
+}
+
bool FakeBluetoothChooserController::TableViewAlwaysDisabled() const {
return table_view_always_disabled_;
}
@@ -62,26 +70,12 @@
return devices_.at(index).paired;
}
-base::string16 FakeBluetoothChooserController::GetStatus() const {
- switch (status_) {
- case BluetoothStatus::UNAVAILABLE:
- return base::string16();
- case BluetoothStatus::IDLE:
- return l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN);
- case BluetoothStatus::SCANNING:
- return l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING);
- }
- NOTREACHED();
- return base::string16();
-}
-
void FakeBluetoothChooserController::SetBluetoothStatus(
BluetoothStatus status) {
- status_ = status;
const bool available = status != BluetoothStatus::UNAVAILABLE;
view()->OnAdapterEnabledChanged(available);
if (available)
- view()->OnRefreshStateChanged(status_ == BluetoothStatus::SCANNING);
+ view()->OnRefreshStateChanged(status == BluetoothStatus::SCANNING);
}
void FakeBluetoothChooserController::AddDevice(FakeDevice device) {
diff --git a/chrome/browser/chooser_controller/fake_bluetooth_chooser_controller.h b/chrome/browser/chooser_controller/fake_bluetooth_chooser_controller.h
index f2b3de9..57b2f15 100644
--- a/chrome/browser/chooser_controller/fake_bluetooth_chooser_controller.h
+++ b/chrome/browser/chooser_controller/fake_bluetooth_chooser_controller.h
@@ -55,13 +55,14 @@
bool ShouldShowReScanButton() const override;
base::string16 GetNoOptionsText() const override;
base::string16 GetOkButtonLabel() const override;
+ std::pair<base::string16, base::string16> GetThrobberLabelAndTooltip()
+ const override;
bool TableViewAlwaysDisabled() const override;
size_t NumOptions() const override;
int GetSignalStrengthLevel(size_t index) const override;
base::string16 GetOption(size_t index) const override;
bool IsConnected(size_t index) const override;
bool IsPaired(size_t index) const override;
- base::string16 GetStatus() const override;
MOCK_METHOD0(RefreshOptions, void());
MOCK_METHOD1(Select, void(const std::vector<size_t>& indices));
MOCK_METHOD0(Cancel, void());
@@ -78,7 +79,6 @@
}
private:
- BluetoothStatus status_ = BluetoothStatus::UNAVAILABLE;
std::vector<FakeDevice> devices_;
bool table_view_always_disabled_ = false;
diff --git a/chrome/browser/chooser_controller/fake_usb_chooser_controller.cc b/chrome/browser/chooser_controller/fake_usb_chooser_controller.cc
index c3accb2..c634d2e 100644
--- a/chrome/browser/chooser_controller/fake_usb_chooser_controller.cc
+++ b/chrome/browser/chooser_controller/fake_usb_chooser_controller.cc
@@ -23,6 +23,13 @@
return l10n_util::GetStringUTF16(IDS_USB_DEVICE_CHOOSER_CONNECT_BUTTON_TEXT);
}
+std::pair<base::string16, base::string16>
+FakeUsbChooserController::GetThrobberLabelAndTooltip() const {
+ return {
+ l10n_util::GetStringUTF16(IDS_USB_DEVICE_CHOOSER_LOADING_LABEL),
+ l10n_util::GetStringUTF16(IDS_USB_DEVICE_CHOOSER_LOADING_LABEL_TOOLTIP)};
+}
+
size_t FakeUsbChooserController::NumOptions() const {
return device_count_;
}
diff --git a/chrome/browser/chooser_controller/fake_usb_chooser_controller.h b/chrome/browser/chooser_controller/fake_usb_chooser_controller.h
index 38a6531..5b7e92c 100644
--- a/chrome/browser/chooser_controller/fake_usb_chooser_controller.h
+++ b/chrome/browser/chooser_controller/fake_usb_chooser_controller.h
@@ -19,6 +19,8 @@
// ChooserController:
base::string16 GetNoOptionsText() const override;
base::string16 GetOkButtonLabel() const override;
+ std::pair<base::string16, base::string16> GetThrobberLabelAndTooltip()
+ const override;
size_t NumOptions() const override;
base::string16 GetOption(size_t index) const override;
void Select(const std::vector<size_t>& indices) override {}
diff --git a/chrome/browser/extensions/device_permissions_dialog_controller.cc b/chrome/browser/extensions/device_permissions_dialog_controller.cc
index ab2136d..ba49d70 100644
--- a/chrome/browser/extensions/device_permissions_dialog_controller.cc
+++ b/chrome/browser/extensions/device_permissions_dialog_controller.cc
@@ -41,6 +41,14 @@
return l10n_util::GetStringUTF16(IDS_DEVICE_PERMISSIONS_DIALOG_SELECT);
}
+std::pair<base::string16, base::string16>
+DevicePermissionsDialogController::GetThrobberLabelAndTooltip() const {
+ return {
+ l10n_util::GetStringUTF16(IDS_DEVICE_PERMISSIONS_DIALOG_LOADING_LABEL),
+ l10n_util::GetStringUTF16(
+ IDS_DEVICE_PERMISSIONS_DIALOG_LOADING_LABEL_TOOLTIP)};
+}
+
size_t DevicePermissionsDialogController::NumOptions() const {
return prompt_->GetDeviceCount();
}
@@ -74,6 +82,12 @@
void DevicePermissionsDialogController::OpenHelpCenterUrl() const {}
+void DevicePermissionsDialogController::OnDevicesInitialized() {
+ if (view()) {
+ view()->OnOptionsInitialized();
+ }
+}
+
void DevicePermissionsDialogController::OnDeviceAdded(
size_t index,
const base::string16& device_name) {
diff --git a/chrome/browser/extensions/device_permissions_dialog_controller.h b/chrome/browser/extensions/device_permissions_dialog_controller.h
index c2de2361..eef852d 100644
--- a/chrome/browser/extensions/device_permissions_dialog_controller.h
+++ b/chrome/browser/extensions/device_permissions_dialog_controller.h
@@ -26,6 +26,8 @@
bool AllowMultipleSelection() const override;
base::string16 GetNoOptionsText() const override;
base::string16 GetOkButtonLabel() const override;
+ std::pair<base::string16, base::string16> GetThrobberLabelAndTooltip()
+ const override;
size_t NumOptions() const override;
base::string16 GetOption(size_t index) const override;
void Select(const std::vector<size_t>& indices) override;
@@ -34,6 +36,7 @@
void OpenHelpCenterUrl() const override;
// extensions::DevicePermissionsPrompt::Prompt::Observer:
+ void OnDevicesInitialized() override;
void OnDeviceAdded(size_t index, const base::string16& device_name) override;
void OnDeviceRemoved(size_t index,
const base::string16& device_name) override;
diff --git a/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.cc b/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.cc
index 7cfdf44..266a3c22 100644
--- a/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.cc
+++ b/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.cc
@@ -70,6 +70,14 @@
IDS_BLUETOOTH_DEVICE_CHOOSER_PAIR_BUTTON_TEXT);
}
+std::pair<base::string16, base::string16>
+BluetoothChooserController::GetThrobberLabelAndTooltip() const {
+ return {
+ l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING_LABEL),
+ l10n_util::GetStringUTF16(
+ IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING_LABEL_TOOLTIP)};
+}
+
size_t BluetoothChooserController::NumOptions() const {
return devices_.size();
}
@@ -123,10 +131,6 @@
#endif
}
-base::string16 BluetoothChooserController::GetStatus() const {
- return status_text_;
-}
-
void BluetoothChooserController::Select(const std::vector<size_t>& indices) {
DCHECK_EQ(1u, indices.size());
size_t index = indices[0];
@@ -168,15 +172,12 @@
NOTREACHED();
break;
case content::BluetoothChooser::AdapterPresence::POWERED_OFF:
- status_text_ = base::string16();
if (view()) {
view()->OnAdapterEnabledChanged(
false /* Bluetooth adapter is turned off */);
}
break;
case content::BluetoothChooser::AdapterPresence::POWERED_ON:
- status_text_ =
- l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN);
if (view()) {
view()->OnAdapterEnabledChanged(
true /* Bluetooth adapter is turned on */);
@@ -189,8 +190,6 @@
content::BluetoothChooser::DiscoveryState state) {
switch (state) {
case content::BluetoothChooser::DiscoveryState::DISCOVERING:
- status_text_ =
- l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING);
if (view()) {
view()->OnRefreshStateChanged(
true /* Refreshing options is in progress */);
@@ -198,8 +197,6 @@
break;
case content::BluetoothChooser::DiscoveryState::IDLE:
case content::BluetoothChooser::DiscoveryState::FAILED_TO_START:
- status_text_ =
- l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN);
if (view()) {
view()->OnRefreshStateChanged(
false /* Refreshing options is complete */);
diff --git a/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.h b/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.h
index 3f903572..3898545b 100644
--- a/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.h
+++ b/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.h
@@ -33,6 +33,8 @@
bool ShouldShowReScanButton() const override;
base::string16 GetNoOptionsText() const override;
base::string16 GetOkButtonLabel() const override;
+ std::pair<base::string16, base::string16> GetThrobberLabelAndTooltip()
+ const override;
size_t NumOptions() const override;
int GetSignalStrengthLevel(size_t index) const override;
bool IsConnected(size_t index) const override;
@@ -40,7 +42,6 @@
base::string16 GetOption(size_t index) const override;
void RefreshOptions() override;
void OpenAdapterOffHelpUrl() const override;
- base::string16 GetStatus() const override;
void Select(const std::vector<size_t>& indices) override;
void Cancel() override;
void Close() override;
@@ -91,7 +92,6 @@
std::unordered_map<base::string16, int> device_name_counts_;
content::BluetoothChooser::EventHandler event_handler_;
- base::string16 status_text_;
base::WeakPtrFactory<BluetoothChooserController> weak_factory_{this};
diff --git a/chrome/browser/ui/bluetooth/bluetooth_chooser_controller_unittest.cc b/chrome/browser/ui/bluetooth/bluetooth_chooser_controller_unittest.cc
index 42ce011..fc597fb 100644
--- a/chrome/browser/ui/bluetooth/bluetooth_chooser_controller_unittest.cc
+++ b/chrome/browser/ui/bluetooth/bluetooth_chooser_controller_unittest.cc
@@ -258,70 +258,47 @@
}
TEST_F(BluetoothChooserControllerWithDevicesAddedTest,
- InitialNoOptionsTextAndStatusText) {
- EXPECT_EQ(l10n_util::GetStringUTF16(
- IDS_BLUETOOTH_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT),
- bluetooth_chooser_controller_.GetNoOptionsText());
- EXPECT_EQ(base::string16(), bluetooth_chooser_controller_.GetStatus());
-}
-
-TEST_F(BluetoothChooserControllerWithDevicesAddedTest,
BluetoothAdapterTurnedOff) {
- EXPECT_CALL(
- mock_bluetooth_chooser_view_,
- OnAdapterEnabledChanged(false /* Bluetooth adapter is turned off */))
+ EXPECT_CALL(mock_bluetooth_chooser_view_,
+ OnAdapterEnabledChanged(/*enabled=*/false))
.Times(1);
bluetooth_chooser_controller_.OnAdapterPresenceChanged(
content::BluetoothChooser::AdapterPresence::POWERED_OFF);
EXPECT_EQ(0u, bluetooth_chooser_controller_.NumOptions());
- EXPECT_EQ(base::string16(), bluetooth_chooser_controller_.GetStatus());
}
TEST_F(BluetoothChooserControllerWithDevicesAddedTest,
BluetoothAdapterTurnedOn) {
- EXPECT_CALL(
- mock_bluetooth_chooser_view_,
- OnAdapterEnabledChanged(true /* Bluetooth adapter is turned on */))
+ EXPECT_CALL(mock_bluetooth_chooser_view_,
+ OnAdapterEnabledChanged(/*enabled=*/true))
.Times(1);
bluetooth_chooser_controller_.OnAdapterPresenceChanged(
content::BluetoothChooser::AdapterPresence::POWERED_ON);
EXPECT_EQ(0u, bluetooth_chooser_controller_.NumOptions());
- EXPECT_EQ(l10n_util::GetStringUTF16(
- IDS_BLUETOOTH_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT),
- bluetooth_chooser_controller_.GetNoOptionsText());
- EXPECT_EQ(l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN),
- bluetooth_chooser_controller_.GetStatus());
}
TEST_F(BluetoothChooserControllerWithDevicesAddedTest, DiscoveringState) {
- EXPECT_CALL(
- mock_bluetooth_chooser_view_,
- OnRefreshStateChanged(true /* Refreshing options is in progress */))
+ EXPECT_CALL(mock_bluetooth_chooser_view_,
+ OnRefreshStateChanged(/*refreshing=*/true))
.Times(1);
bluetooth_chooser_controller_.OnDiscoveryStateChanged(
content::BluetoothChooser::DiscoveryState::DISCOVERING);
- EXPECT_EQ(l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING),
- bluetooth_chooser_controller_.GetStatus());
}
TEST_F(BluetoothChooserControllerWithDevicesAddedTest, IdleState) {
EXPECT_CALL(mock_bluetooth_chooser_view_,
- OnRefreshStateChanged(false /* Refreshing options is complete */))
+ OnRefreshStateChanged(/*refreshing=*/false))
.Times(1);
bluetooth_chooser_controller_.OnDiscoveryStateChanged(
content::BluetoothChooser::DiscoveryState::IDLE);
- EXPECT_EQ(l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN),
- bluetooth_chooser_controller_.GetStatus());
}
TEST_F(BluetoothChooserControllerWithDevicesAddedTest, FailedToStartState) {
EXPECT_CALL(mock_bluetooth_chooser_view_,
- OnRefreshStateChanged(false /* Refreshing options is complete */))
+ OnRefreshStateChanged(/*refreshing=*/false))
.Times(1);
bluetooth_chooser_controller_.OnDiscoveryStateChanged(
content::BluetoothChooser::DiscoveryState::FAILED_TO_START);
- EXPECT_EQ(l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN),
- bluetooth_chooser_controller_.GetStatus());
}
TEST_F(BluetoothChooserControllerWithDevicesAddedTest, RefreshOptions) {
diff --git a/chrome/browser/ui/bluetooth/bluetooth_scanning_prompt_controller.cc b/chrome/browser/ui/bluetooth/bluetooth_scanning_prompt_controller.cc
index a4de1df..7e348d62 100644
--- a/chrome/browser/ui/bluetooth/bluetooth_scanning_prompt_controller.cc
+++ b/chrome/browser/ui/bluetooth/bluetooth_scanning_prompt_controller.cc
@@ -39,6 +39,14 @@
IDS_BLUETOOTH_SCANNING_PROMPT_BLOCK_BUTTON_TEXT);
}
+std::pair<base::string16, base::string16>
+BluetoothScanningPromptController::GetThrobberLabelAndTooltip() const {
+ return {
+ l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING_LABEL),
+ l10n_util::GetStringUTF16(
+ IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING_LABEL_TOOLTIP)};
+}
+
bool BluetoothScanningPromptController::BothButtonsAlwaysEnabled() const {
return true;
}
diff --git a/chrome/browser/ui/bluetooth/bluetooth_scanning_prompt_controller.h b/chrome/browser/ui/bluetooth/bluetooth_scanning_prompt_controller.h
index 0f43464..57f0460 100644
--- a/chrome/browser/ui/bluetooth/bluetooth_scanning_prompt_controller.h
+++ b/chrome/browser/ui/bluetooth/bluetooth_scanning_prompt_controller.h
@@ -33,6 +33,8 @@
base::string16 GetNoOptionsText() const override;
base::string16 GetOkButtonLabel() const override;
base::string16 GetCancelButtonLabel() const override;
+ std::pair<base::string16, base::string16> GetThrobberLabelAndTooltip()
+ const override;
bool BothButtonsAlwaysEnabled() const override;
bool TableViewAlwaysDisabled() const override;
size_t NumOptions() const override;
diff --git a/chrome/browser/ui/font_access/font_access_chooser_controller.cc b/chrome/browser/ui/font_access/font_access_chooser_controller.cc
index 46cf49ad..8210f884 100644
--- a/chrome/browser/ui/font_access/font_access_chooser_controller.cc
+++ b/chrome/browser/ui/font_access/font_access_chooser_controller.cc
@@ -60,6 +60,13 @@
return l10n_util::GetStringUTF16(IDS_FONT_ACCESS_CHOOSER_IMPORT_BUTTON_TEXT);
}
+std::pair<base::string16, base::string16>
+FontAccessChooserController::GetThrobberLabelAndTooltip() const {
+ return {
+ l10n_util::GetStringUTF16(IDS_FONT_ACCESS_CHOOSER_LOADING_LABEL),
+ l10n_util::GetStringUTF16(IDS_FONT_ACCESS_CHOOSER_LOADING_LABEL_TOOLTIP)};
+}
+
size_t FontAccessChooserController::NumOptions() const {
return items_.size();
}
diff --git a/chrome/browser/ui/font_access/font_access_chooser_controller.h b/chrome/browser/ui/font_access/font_access_chooser_controller.h
index 2c7bfa0..c6336653 100644
--- a/chrome/browser/ui/font_access/font_access_chooser_controller.h
+++ b/chrome/browser/ui/font_access/font_access_chooser_controller.h
@@ -31,6 +31,8 @@
// ChooserController:
base::string16 GetNoOptionsText() const override;
base::string16 GetOkButtonLabel() const override;
+ std::pair<base::string16, base::string16> GetThrobberLabelAndTooltip()
+ const override;
size_t NumOptions() const override;
base::string16 GetOption(size_t index) const override;
base::string16 GetSelectAllCheckboxLabel() const override;
diff --git a/chrome/browser/ui/hid/hid_chooser_controller.cc b/chrome/browser/ui/hid/hid_chooser_controller.cc
index e7a8322..8db352b 100644
--- a/chrome/browser/ui/hid/hid_chooser_controller.cc
+++ b/chrome/browser/ui/hid/hid_chooser_controller.cc
@@ -74,6 +74,12 @@
return l10n_util::GetStringUTF16(IDS_USB_DEVICE_CHOOSER_CONNECT_BUTTON_TEXT);
}
+std::pair<base::string16, base::string16>
+HidChooserController::GetThrobberLabelAndTooltip() const {
+ return {l10n_util::GetStringUTF16(IDS_HID_CHOOSER_LOADING_LABEL),
+ l10n_util::GetStringUTF16(IDS_HID_CHOOSER_LOADING_LABEL_TOOLTIP)};
+}
+
size_t HidChooserController::NumOptions() const {
return items_.size();
}
diff --git a/chrome/browser/ui/hid/hid_chooser_controller.h b/chrome/browser/ui/hid/hid_chooser_controller.h
index 2671623..dfbd383 100644
--- a/chrome/browser/ui/hid/hid_chooser_controller.h
+++ b/chrome/browser/ui/hid/hid_chooser_controller.h
@@ -46,6 +46,8 @@
bool ShouldShowHelpButton() const override;
base::string16 GetNoOptionsText() const override;
base::string16 GetOkButtonLabel() const override;
+ std::pair<base::string16, base::string16> GetThrobberLabelAndTooltip()
+ const override;
size_t NumOptions() const override;
base::string16 GetOption(size_t index) const override;
bool IsPaired(size_t index) const override;
diff --git a/chrome/browser/ui/serial/serial_chooser_controller.cc b/chrome/browser/ui/serial/serial_chooser_controller.cc
index d6d8c30..2739875 100644
--- a/chrome/browser/ui/serial/serial_chooser_controller.cc
+++ b/chrome/browser/ui/serial/serial_chooser_controller.cc
@@ -57,6 +57,13 @@
return l10n_util::GetStringUTF16(IDS_SERIAL_PORT_CHOOSER_CONNECT_BUTTON_TEXT);
}
+std::pair<base::string16, base::string16>
+SerialChooserController::GetThrobberLabelAndTooltip() const {
+ return {
+ l10n_util::GetStringUTF16(IDS_SERIAL_PORT_CHOOSER_LOADING_LABEL),
+ l10n_util::GetStringUTF16(IDS_SERIAL_PORT_CHOOSER_LOADING_LABEL_TOOLTIP)};
+}
+
size_t SerialChooserController::NumOptions() const {
return ports_.size();
}
diff --git a/chrome/browser/ui/serial/serial_chooser_controller.h b/chrome/browser/ui/serial/serial_chooser_controller.h
index 4d9a2df..ee08d6c2 100644
--- a/chrome/browser/ui/serial/serial_chooser_controller.h
+++ b/chrome/browser/ui/serial/serial_chooser_controller.h
@@ -37,6 +37,8 @@
// ChooserController:
base::string16 GetNoOptionsText() const override;
base::string16 GetOkButtonLabel() const override;
+ std::pair<base::string16, base::string16> GetThrobberLabelAndTooltip()
+ const override;
size_t NumOptions() const override;
base::string16 GetOption(size_t index) const override;
bool IsPaired(size_t index) const override;
diff --git a/chrome/browser/ui/views/device_chooser_content_view.cc b/chrome/browser/ui/views/device_chooser_content_view.cc
index aee5d1e..ea58437 100644
--- a/chrome/browser/ui/views/device_chooser_content_view.cc
+++ b/chrome/browser/ui/views/device_chooser_content_view.cc
@@ -33,85 +33,6 @@
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
-class BluetoothStatusContainer : public views::View {
- public:
- explicit BluetoothStatusContainer(ChooserController* chooser_controller);
-
- void ShowScanningLabelAndThrobber();
- void ShowReScanButton(bool enabled);
-
- private:
- friend class DeviceChooserContentView;
-
- views::LabelButton* re_scan_button_;
- views::Throbber* throbber_;
- views::Label* scanning_label_;
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothStatusContainer);
-};
-
-BluetoothStatusContainer::BluetoothStatusContainer(
- ChooserController* chooser_controller) {
- SetUseDefaultFillLayout(true);
-
- auto* rescan_container = AddChildView(std::make_unique<views::View>());
- rescan_container
- ->SetLayoutManager(std::make_unique<views::BoxLayout>(
- views::BoxLayout::Orientation::kHorizontal))
- ->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kCenter);
-
- auto re_scan_button = std::make_unique<views::MdTextButton>(
- views::Button::PressedCallback(),
- l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN));
- re_scan_button->SetCallback(base::BindRepeating(
- [](views::MdTextButton* button, ChooserController* chooser_controller) {
- // Refreshing will cause the table view to yield focus, which will land
- // on the help button. Instead, briefly let the rescan button take
- // focus. When it hides itself, focus will advance to the "Cancel"
- // button as desired.
- button->RequestFocus();
- chooser_controller->RefreshOptions();
- },
- re_scan_button.get(), chooser_controller));
- re_scan_button->SetTooltipText(
- l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN_TOOLTIP));
- re_scan_button_ = rescan_container->AddChildView(std::move(re_scan_button));
-
- auto* scan_container = AddChildView(std::make_unique<views::View>());
- auto* scan_layout =
- scan_container->SetLayoutManager(std::make_unique<views::BoxLayout>(
- views::BoxLayout::Orientation::kHorizontal));
- scan_layout->set_cross_axis_alignment(
- views::BoxLayout::CrossAxisAlignment::kCenter);
- scan_layout->set_between_child_spacing(
- ChromeLayoutProvider::Get()->GetDistanceMetric(
- views::DISTANCE_RELATED_CONTROL_HORIZONTAL));
-
- throbber_ = scan_container->AddChildView(std::make_unique<views::Throbber>());
-
- auto scanning_label = std::make_unique<views::Label>(
- l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING_LABEL),
- views::style::CONTEXT_LABEL, views::style::STYLE_DISABLED);
- scanning_label->SetTooltipText(l10n_util::GetStringUTF16(
- IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING_LABEL_TOOLTIP));
- scanning_label_ = scan_container->AddChildView(std::move(scanning_label));
-}
-
-void BluetoothStatusContainer::ShowScanningLabelAndThrobber() {
- re_scan_button_->SetVisible(false);
- throbber_->SetVisible(true);
- scanning_label_->SetVisible(true);
- throbber_->Start();
-}
-
-void BluetoothStatusContainer::ShowReScanButton(bool enabled) {
- re_scan_button_->SetVisible(true);
- re_scan_button_->SetEnabled(enabled);
- throbber_->Stop();
- throbber_->SetVisible(false);
- scanning_label_->SetVisible(false);
-}
-
DeviceChooserContentView::DeviceChooserContentView(
views::TableViewObserver* table_view_observer,
std::unique_ptr<ChooserController> chooser_controller)
@@ -247,6 +168,7 @@
is_initialized_ = true;
table_view_->OnModelChanged();
UpdateTableView();
+ HideThrobber();
}
void DeviceChooserContentView::OnOptionAdded(size_t index) {
@@ -273,7 +195,7 @@
adapter_enabled_ = enabled;
UpdateTableView();
- bluetooth_status_container_->ShowReScanButton(enabled);
+ ShowReScanButton(enabled);
if (GetWidget() && GetWidget()->GetRootView())
GetWidget()->GetRootView()->Layout();
@@ -289,9 +211,9 @@
}
if (refreshing)
- bluetooth_status_container_->ShowScanningLabelAndThrobber();
+ ShowThrobber();
else
- bluetooth_status_container_->ShowReScanButton(true /* enabled */);
+ ShowReScanButton(/*enable=*/true);
if (GetWidget() && GetWidget()->GetRootView())
GetWidget()->GetRootView()->Layout();
@@ -302,28 +224,6 @@
}
std::unique_ptr<views::View> DeviceChooserContentView::CreateExtraView() {
- const auto make_help_button = [this]() {
- auto help_button = views::CreateVectorImageButtonWithNativeTheme(
- base::BindRepeating(&ChooserController::OpenHelpCenterUrl,
- base::Unretained(chooser_controller_.get())),
- vector_icons::kHelpOutlineIcon);
- help_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
- return help_button;
- };
-
- const auto make_bluetooth_status_container = [this]() {
- auto bluetooth_status_container =
- std::make_unique<BluetoothStatusContainer>(chooser_controller_.get());
- bluetooth_status_container_ = bluetooth_status_container.get();
- return bluetooth_status_container;
- };
-
- const bool add_bluetooth = chooser_controller_->ShouldShowReScanButton();
- if (!chooser_controller_->ShouldShowHelpButton())
- return add_bluetooth ? make_bluetooth_status_container() : nullptr;
- if (!add_bluetooth)
- return make_help_button();
-
auto container = std::make_unique<views::View>();
auto layout = std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal, gfx::Insets(),
@@ -331,8 +231,67 @@
views::DISTANCE_RELATED_CONTROL_HORIZONTAL));
container->SetLayoutManager(std::move(layout))
->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kCenter);
- container->AddChildView(make_help_button());
- container->AddChildView(make_bluetooth_status_container());
+
+ if (chooser_controller_->ShouldShowHelpButton()) {
+ auto help_button = views::CreateVectorImageButtonWithNativeTheme(
+ base::BindRepeating(&ChooserController::OpenHelpCenterUrl,
+ base::Unretained(chooser_controller_.get())),
+ vector_icons::kHelpOutlineIcon);
+ help_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
+ container->AddChildView(std::move(help_button));
+ }
+
+ auto* throbber_container =
+ container->AddChildView(std::make_unique<views::View>());
+ auto* throbber_layout =
+ throbber_container->SetLayoutManager(std::make_unique<views::BoxLayout>(
+ views::BoxLayout::Orientation::kHorizontal));
+ throbber_layout->set_cross_axis_alignment(
+ views::BoxLayout::CrossAxisAlignment::kCenter);
+ throbber_layout->set_between_child_spacing(
+ ChromeLayoutProvider::Get()->GetDistanceMetric(
+ views::DISTANCE_RELATED_CONTROL_HORIZONTAL));
+
+ throbber_ =
+ throbber_container->AddChildView(std::make_unique<views::Throbber>());
+
+ auto throbber_strings = chooser_controller_->GetThrobberLabelAndTooltip();
+ auto throbber_label = std::make_unique<views::Label>(
+ throbber_strings.first, views::style::CONTEXT_LABEL,
+ views::style::STYLE_DISABLED);
+ throbber_label->SetTooltipText(throbber_strings.second);
+ throbber_label_ = throbber_container->AddChildView(std::move(throbber_label));
+
+ if (chooser_controller_->ShouldShowReScanButton()) {
+ auto* rescan_container =
+ container->AddChildView(std::make_unique<views::View>());
+ rescan_container
+ ->SetLayoutManager(std::make_unique<views::BoxLayout>(
+ views::BoxLayout::Orientation::kHorizontal))
+ ->set_cross_axis_alignment(
+ views::BoxLayout::CrossAxisAlignment::kCenter);
+
+ auto re_scan_button = std::make_unique<views::MdTextButton>(
+ views::Button::PressedCallback(),
+ l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN));
+ re_scan_button->SetCallback(base::BindRepeating(
+ [](views::MdTextButton* button, ChooserController* chooser_controller) {
+ // Refreshing will cause the table view to yield focus, which will
+ // land on the help button. Instead, briefly let the rescan button
+ // take focus. When it hides itself, focus will advance to the
+ // "Cancel" button as desired.
+ button->RequestFocus();
+ chooser_controller->RefreshOptions();
+ },
+ re_scan_button.get(), chooser_controller_.get()));
+ re_scan_button->SetTooltipText(l10n_util::GetStringUTF16(
+ IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN_TOOLTIP));
+ re_scan_button_ = rescan_container->AddChildView(std::move(re_scan_button));
+ }
+
+ // Enable the throbber by default until OnOptionsInitialized() is called.
+ ShowThrobber();
+
return container;
}
@@ -385,14 +344,38 @@
table_view_->SetSelectionAll(/*select=*/select_all_view_->GetChecked());
}
+void DeviceChooserContentView::ShowThrobber() {
+ if (re_scan_button_)
+ re_scan_button_->SetVisible(false);
+
+ throbber_->SetVisible(true);
+ throbber_label_->SetVisible(true);
+ throbber_->Start();
+}
+
+void DeviceChooserContentView::HideThrobber() {
+ throbber_->SetVisible(false);
+ throbber_label_->SetVisible(false);
+ throbber_->Stop();
+}
+
+void DeviceChooserContentView::ShowReScanButton(bool enabled) {
+ DCHECK(re_scan_button_);
+ re_scan_button_->SetVisible(true);
+ re_scan_button_->SetEnabled(enabled);
+ throbber_->Stop();
+ throbber_->SetVisible(false);
+ throbber_label_->SetVisible(false);
+}
+
views::LabelButton* DeviceChooserContentView::ReScanButtonForTesting() {
- return bluetooth_status_container_->re_scan_button_;
+ return re_scan_button_;
}
views::Throbber* DeviceChooserContentView::ThrobberForTesting() {
- return bluetooth_status_container_->throbber_;
+ return throbber_;
}
-views::Label* DeviceChooserContentView::ScanningLabelForTesting() {
- return bluetooth_status_container_->scanning_label_;
+views::Label* DeviceChooserContentView::ThrobberLabelForTesting() {
+ return throbber_label_;
}
diff --git a/chrome/browser/ui/views/device_chooser_content_view.h b/chrome/browser/ui/views/device_chooser_content_view.h
index 9308d67..7894709 100644
--- a/chrome/browser/ui/views/device_chooser_content_view.h
+++ b/chrome/browser/ui/views/device_chooser_content_view.h
@@ -14,7 +14,6 @@
#include "ui/gfx/range/range.h"
#include "ui/views/view.h"
-class BluetoothStatusContainer;
namespace views {
class Checkbox;
class Label;
@@ -64,11 +63,15 @@
void UpdateTableView();
void SelectAllCheckboxChanged();
+ void ShowThrobber();
+ void HideThrobber();
+ void ShowReScanButton(bool enable);
+
// Test-only accessors to children.
views::TableView* table_view_for_testing() { return table_view_; }
views::LabelButton* ReScanButtonForTesting();
views::Throbber* ThrobberForTesting();
- views::Label* ScanningLabelForTesting();
+ views::Label* ThrobberLabelForTesting();
private:
friend class DeviceChooserContentViewTest;
@@ -82,7 +85,9 @@
views::TableView* table_view_ = nullptr;
views::View* no_options_view_ = nullptr;
views::View* adapter_off_view_ = nullptr;
- BluetoothStatusContainer* bluetooth_status_container_ = nullptr;
+ views::LabelButton* re_scan_button_ = nullptr;
+ views::Throbber* throbber_ = nullptr;
+ views::Label* throbber_label_ = nullptr;
bool is_initialized_ = false;
base::CallbackListSubscription select_all_subscription_;
diff --git a/chrome/browser/ui/views/device_chooser_content_view_unittest.cc b/chrome/browser/ui/views/device_chooser_content_view_unittest.cc
index c763304..b8f7c030 100644
--- a/chrome/browser/ui/views/device_chooser_content_view_unittest.cc
+++ b/chrome/browser/ui/views/device_chooser_content_view_unittest.cc
@@ -48,7 +48,7 @@
widget_->SetContentsView(std::make_unique<DeviceChooserContentView>(
table_observer_.get(), std::move(controller)));
- // Also creates |bluetooth_status_container_|.
+ // Forces creation of the throbber and status line.
extra_views_container_ = content_view_->CreateExtraView();
ASSERT_NE(nullptr, table_view());
@@ -56,7 +56,7 @@
ASSERT_NE(nullptr, adapter_off_view());
ASSERT_NE(nullptr, re_scan_button());
ASSERT_NE(nullptr, throbber());
- ASSERT_NE(nullptr, scanning_label());
+ ASSERT_NE(nullptr, throbber_label());
controller_->SetBluetoothStatus(
FakeBluetoothChooserController::BluetoothStatus::IDLE);
@@ -85,8 +85,8 @@
return content_view_->ReScanButtonForTesting();
}
views::Throbber* throbber() { return content_view_->ThrobberForTesting(); }
- views::Label* scanning_label() {
- return content_view_->ScanningLabelForTesting();
+ views::Label* throbber_label() {
+ return content_view_->ThrobberLabelForTesting();
}
void AddUnpairedDevice() {
@@ -149,7 +149,7 @@
ExpectNoDevicesWithMessageHidden();
EXPECT_FALSE(adapter_off_view()->GetVisible());
EXPECT_FALSE(throbber()->GetVisible());
- EXPECT_FALSE(scanning_label()->GetVisible());
+ EXPECT_FALSE(throbber_label()->GetVisible());
EXPECT_TRUE(re_scan_button()->GetVisible());
EXPECT_TRUE(re_scan_button()->GetEnabled());
}
@@ -232,7 +232,7 @@
EXPECT_FALSE(no_options_view()->GetVisible());
EXPECT_TRUE(adapter_off_view()->GetVisible());
EXPECT_FALSE(throbber()->GetVisible());
- EXPECT_FALSE(scanning_label()->GetVisible());
+ EXPECT_FALSE(throbber_label()->GetVisible());
EXPECT_TRUE(re_scan_button()->GetVisible());
EXPECT_FALSE(re_scan_button()->GetEnabled());
@@ -242,7 +242,7 @@
ExpectNoDevicesWithMessageVisible();
EXPECT_FALSE(adapter_off_view()->GetVisible());
EXPECT_FALSE(throbber()->GetVisible());
- EXPECT_FALSE(scanning_label()->GetVisible());
+ EXPECT_FALSE(throbber_label()->GetVisible());
EXPECT_TRUE(re_scan_button()->GetVisible());
EXPECT_TRUE(re_scan_button()->GetEnabled());
}
@@ -254,7 +254,7 @@
EXPECT_FALSE(table_view()->GetEnabled());
EXPECT_FALSE(adapter_off_view()->GetVisible());
EXPECT_TRUE(throbber()->GetVisible());
- EXPECT_TRUE(scanning_label()->GetVisible());
+ EXPECT_TRUE(throbber_label()->GetVisible());
EXPECT_FALSE(re_scan_button()->GetVisible());
AddUnpairedDevice();
@@ -262,7 +262,7 @@
EXPECT_TRUE(table_view()->GetEnabled());
EXPECT_FALSE(adapter_off_view()->GetVisible());
EXPECT_TRUE(throbber()->GetVisible());
- EXPECT_TRUE(scanning_label()->GetVisible());
+ EXPECT_TRUE(throbber_label()->GetVisible());
EXPECT_FALSE(IsDeviceSelected());
EXPECT_FALSE(re_scan_button()->GetVisible());
}
diff --git a/chrome/browser/usb/usb_chooser_controller.cc b/chrome/browser/usb/usb_chooser_controller.cc
index 81e7d0c..3bdd05e 100644
--- a/chrome/browser/usb/usb_chooser_controller.cc
+++ b/chrome/browser/usb/usb_chooser_controller.cc
@@ -122,6 +122,13 @@
return l10n_util::GetStringUTF16(IDS_USB_DEVICE_CHOOSER_CONNECT_BUTTON_TEXT);
}
+std::pair<base::string16, base::string16>
+UsbChooserController::GetThrobberLabelAndTooltip() const {
+ return {
+ l10n_util::GetStringUTF16(IDS_USB_DEVICE_CHOOSER_LOADING_LABEL),
+ l10n_util::GetStringUTF16(IDS_USB_DEVICE_CHOOSER_LOADING_LABEL_TOOLTIP)};
+}
+
size_t UsbChooserController::NumOptions() const {
return devices_.size();
}
diff --git a/chrome/browser/usb/usb_chooser_controller.h b/chrome/browser/usb/usb_chooser_controller.h
index 6f48d4b..c5b5c6b 100644
--- a/chrome/browser/usb/usb_chooser_controller.h
+++ b/chrome/browser/usb/usb_chooser_controller.h
@@ -38,6 +38,8 @@
// ChooserController:
base::string16 GetNoOptionsText() const override;
base::string16 GetOkButtonLabel() const override;
+ std::pair<base::string16, base::string16> GetThrobberLabelAndTooltip()
+ const override;
size_t NumOptions() const override;
base::string16 GetOption(size_t index) const override;
bool IsPaired(size_t index) const override;