Commit f7c8453d authored by Steven Bennetts's avatar Steven Bennetts Committed by Commit Bot

SystemWebDialogDelegate: Track instances

This CL tracks SystemWebDialogDelegate instances so that derived
classes can check for an existing instance and focus that instead
of opening a new instance.

Bug: 855344
Change-Id: I688f2e09bd280a511d4ab53463beccfdd10f5371
Reviewed-on: https://chromium-review.googlesource.com/c/1366793Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Reviewed-by: default avatarToni Baržić <tbarzic@chromium.org>
Commit-Queue: Steven Bennetts <stevenjb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#616061}
parent fc7335b9
...@@ -28,7 +28,9 @@ void AddBluetoothStrings(content::WebUIDataSource* html_source) { ...@@ -28,7 +28,9 @@ void AddBluetoothStrings(content::WebUIDataSource* html_source) {
const char* name; const char* name;
int id; int id;
} localized_strings[] = { } localized_strings[] = {
{"ok", IDS_OK}, {"cancel", IDS_CANCEL}, {"close", IDS_CLOSE}, {"ok", IDS_OK},
{"cancel", IDS_CANCEL},
{"close", IDS_CLOSE},
}; };
for (const auto& entry : localized_strings) for (const auto& entry : localized_strings)
html_source->AddLocalizedString(entry.name, entry.id); html_source->AddLocalizedString(entry.name, entry.id);
...@@ -38,7 +40,7 @@ void AddBluetoothStrings(content::WebUIDataSource* html_source) { ...@@ -38,7 +40,7 @@ void AddBluetoothStrings(content::WebUIDataSource* html_source) {
} // namespace } // namespace
// static // static
BluetoothPairingDialog* BluetoothPairingDialog::ShowDialog( SystemWebDialogDelegate* BluetoothPairingDialog::ShowDialog(
const std::string& address, const std::string& address,
const base::string16& name_for_display, const base::string16& name_for_display,
bool paired, bool paired,
...@@ -49,6 +51,12 @@ BluetoothPairingDialog* BluetoothPairingDialog::ShowDialog( ...@@ -49,6 +51,12 @@ BluetoothPairingDialog* BluetoothPairingDialog::ShowDialog(
LOG(ERROR) << "BluetoothPairingDialog: Invalid address: " << address; LOG(ERROR) << "BluetoothPairingDialog: Invalid address: " << address;
return nullptr; return nullptr;
} }
auto* instance = SystemWebDialogDelegate::FindInstance(cannonical_address);
if (instance) {
instance->Focus();
return instance;
}
BluetoothPairingDialog* dialog = new BluetoothPairingDialog( BluetoothPairingDialog* dialog = new BluetoothPairingDialog(
cannonical_address, name_for_display, paired, connected); cannonical_address, name_for_display, paired, connected);
dialog->ShowSystemDialog(); dialog->ShowSystemDialog();
...@@ -62,7 +70,8 @@ BluetoothPairingDialog::BluetoothPairingDialog( ...@@ -62,7 +70,8 @@ BluetoothPairingDialog::BluetoothPairingDialog(
bool connected) bool connected)
: SystemWebDialogDelegate( : SystemWebDialogDelegate(
GURL(chrome::kChromeUIBluetoothPairingURL), GURL(chrome::kChromeUIBluetoothPairingURL),
l10n_util::GetStringUTF16(IDS_SETTINGS_BLUETOOTH_PAIR_DEVICE_TITLE)) { l10n_util::GetStringUTF16(IDS_SETTINGS_BLUETOOTH_PAIR_DEVICE_TITLE)),
address_(address) {
device_data_.SetString("address", address); device_data_.SetString("address", address);
device_data_.SetString("name", name_for_display); device_data_.SetString("name", name_for_display);
device_data_.SetBoolean("paired", paired); device_data_.SetBoolean("paired", paired);
...@@ -71,6 +80,10 @@ BluetoothPairingDialog::BluetoothPairingDialog( ...@@ -71,6 +80,10 @@ BluetoothPairingDialog::BluetoothPairingDialog(
BluetoothPairingDialog::~BluetoothPairingDialog() = default; BluetoothPairingDialog::~BluetoothPairingDialog() = default;
const std::string& BluetoothPairingDialog::Id() {
return address_;
}
void BluetoothPairingDialog::GetDialogSize(gfx::Size* size) const { void BluetoothPairingDialog::GetDialogSize(gfx::Size* size) const {
size->SetSize(SystemWebDialogDelegate::kDialogWidth, size->SetSize(SystemWebDialogDelegate::kDialogWidth,
kBluetoothPairingDialogHeight); kBluetoothPairingDialogHeight);
...@@ -95,9 +108,9 @@ BluetoothPairingDialogUI::BluetoothPairingDialogUI(content::WebUI* web_ui) ...@@ -95,9 +108,9 @@ BluetoothPairingDialogUI::BluetoothPairingDialogUI(content::WebUI* web_ui)
#if BUILDFLAG(OPTIMIZE_WEBUI) #if BUILDFLAG(OPTIMIZE_WEBUI)
source->UseGzip(); source->UseGzip();
source->SetDefaultResource( source->SetDefaultResource(
base::FeatureList::IsEnabled(features::kWebUIPolymer2) ? base::FeatureList::IsEnabled(features::kWebUIPolymer2)
IDR_BLUETOOTH_PAIRING_DIALOG_VULCANIZED_P2_HTML : ? IDR_BLUETOOTH_PAIRING_DIALOG_VULCANIZED_P2_HTML
IDR_BLUETOOTH_PAIRING_DIALOG_VULCANIZED_HTML); : IDR_BLUETOOTH_PAIRING_DIALOG_VULCANIZED_HTML);
source->AddResourcePath("crisper.js", source->AddResourcePath("crisper.js",
IDR_BLUETOOTH_PAIRING_DIALOG_CRISPER_JS); IDR_BLUETOOTH_PAIRING_DIALOG_CRISPER_JS);
#else #else
......
...@@ -15,7 +15,7 @@ namespace chromeos { ...@@ -15,7 +15,7 @@ namespace chromeos {
class BluetoothPairingDialog : public SystemWebDialogDelegate { class BluetoothPairingDialog : public SystemWebDialogDelegate {
public: public:
// Shows a bluetooth pairing dialog. The dialog is returned for testing. // Shows a bluetooth pairing dialog. The dialog is returned for testing.
static BluetoothPairingDialog* ShowDialog( static SystemWebDialogDelegate* ShowDialog(
const std::string& address, const std::string& address,
const base::string16& name_for_display, const base::string16& name_for_display,
bool paired, bool paired,
...@@ -28,11 +28,15 @@ class BluetoothPairingDialog : public SystemWebDialogDelegate { ...@@ -28,11 +28,15 @@ class BluetoothPairingDialog : public SystemWebDialogDelegate {
bool connected); bool connected);
~BluetoothPairingDialog() override; ~BluetoothPairingDialog() override;
// SystemWebDialogDelegate
const std::string& Id() override;
// ui::WebDialogDelegate // ui::WebDialogDelegate
void GetDialogSize(gfx::Size* size) const override; void GetDialogSize(gfx::Size* size) const override;
std::string GetDialogArgs() const override; std::string GetDialogArgs() const override;
private: private:
std::string address_;
base::DictionaryValue device_data_; base::DictionaryValue device_data_;
DISALLOW_COPY_AND_ASSIGN(BluetoothPairingDialog); DISALLOW_COPY_AND_ASSIGN(BluetoothPairingDialog);
......
...@@ -51,7 +51,7 @@ void BluetoothPairingDialogTest::ShowDialog() { ...@@ -51,7 +51,7 @@ void BluetoothPairingDialogTest::ShowDialog() {
EXPECT_CALL(*mock_adapter_, GetDevice(testing::_)) EXPECT_CALL(*mock_adapter_, GetDevice(testing::_))
.WillOnce(testing::Return(mock_device_.get())); .WillOnce(testing::Return(mock_device_.get()));
chromeos::BluetoothPairingDialog* dialog = chromeos::SystemWebDialogDelegate* dialog =
chromeos::BluetoothPairingDialog::ShowDialog( chromeos::BluetoothPairingDialog::ShowDialog(
mock_device_->GetAddress(), mock_device_->GetNameForDisplay(), mock_device_->GetAddress(), mock_device_->GetNameForDisplay(),
mock_device_->IsPaired(), mock_device_->IsConnected()); mock_device_->IsPaired(), mock_device_->IsConnected());
......
...@@ -48,6 +48,16 @@ void AddInternetStrings(content::WebUIDataSource* html_source) { ...@@ -48,6 +48,16 @@ void AddInternetStrings(content::WebUIDataSource* html_source) {
html_source->AddLocalizedString(entry.name, entry.id); html_source->AddLocalizedString(entry.name, entry.id);
} }
std::string GetId(const std::string& network_type,
const std::string& network_id) {
std::string result = chrome::kChromeUIIntenetConfigDialogURL + network_type;
if (!network_id.empty()) {
result += ".";
result += network_id;
}
return result;
}
} // namespace } // namespace
// static // static
...@@ -62,26 +72,46 @@ void InternetConfigDialog::ShowDialogForNetworkId( ...@@ -62,26 +72,46 @@ void InternetConfigDialog::ShowDialogForNetworkId(
} }
std::string network_type = std::string network_type =
chromeos::network_util::TranslateShillTypeToONC(network_state->type()); chromeos::network_util::TranslateShillTypeToONC(network_state->type());
std::string id = GetId(network_type, network_id);
auto* instance = SystemWebDialogDelegate::FindInstance(id);
if (instance) {
instance->Focus();
return;
}
InternetConfigDialog* dialog = InternetConfigDialog* dialog =
new InternetConfigDialog(network_type, network_id); new InternetConfigDialog(id, network_type, network_id);
dialog->ShowSystemDialog(); dialog->ShowSystemDialog();
} }
// static // static
void InternetConfigDialog::ShowDialogForNetworkType( void InternetConfigDialog::ShowDialogForNetworkType(
const std::string& network_type) { const std::string& network_type) {
InternetConfigDialog* dialog = new InternetConfigDialog(network_type, ""); std::string id = GetId(network_type, "");
auto* instance = SystemWebDialogDelegate::FindInstance(id);
if (instance) {
instance->Focus();
return;
}
InternetConfigDialog* dialog = new InternetConfigDialog(id, network_type, "");
dialog->ShowSystemDialog(); dialog->ShowSystemDialog();
} }
InternetConfigDialog::InternetConfigDialog(const std::string& network_type, InternetConfigDialog::InternetConfigDialog(const std::string& dialog_id,
const std::string& network_type,
const std::string& network_id) const std::string& network_id)
: SystemWebDialogDelegate(GURL(chrome::kChromeUIIntenetConfigDialogURL), : SystemWebDialogDelegate(GURL(chrome::kChromeUIIntenetConfigDialogURL),
base::string16() /* title */), base::string16() /* title */),
dialog_id_(dialog_id),
network_type_(network_type), network_type_(network_type),
network_id_(network_id) {} network_id_(network_id) {}
InternetConfigDialog::~InternetConfigDialog() {} InternetConfigDialog::~InternetConfigDialog() = default;
const std::string& InternetConfigDialog::Id() {
return dialog_id_;
}
void InternetConfigDialog::GetDialogSize(gfx::Size* size) const { void InternetConfigDialog::GetDialogSize(gfx::Size* size) const {
const NetworkState* network = const NetworkState* network =
...@@ -117,9 +147,9 @@ InternetConfigDialogUI::InternetConfigDialogUI(content::WebUI* web_ui) ...@@ -117,9 +147,9 @@ InternetConfigDialogUI::InternetConfigDialogUI(content::WebUI* web_ui)
#if BUILDFLAG(OPTIMIZE_WEBUI) #if BUILDFLAG(OPTIMIZE_WEBUI)
source->UseGzip(); source->UseGzip();
source->SetDefaultResource( source->SetDefaultResource(
base::FeatureList::IsEnabled(features::kWebUIPolymer2) ? base::FeatureList::IsEnabled(features::kWebUIPolymer2)
IDR_INTERNET_CONFIG_DIALOG_VULCANIZED_P2_HTML : ? IDR_INTERNET_CONFIG_DIALOG_VULCANIZED_P2_HTML
IDR_INTERNET_CONFIG_DIALOG_VULCANIZED_HTML); : IDR_INTERNET_CONFIG_DIALOG_VULCANIZED_HTML);
source->AddResourcePath("crisper.js", IDR_INTERNET_CONFIG_DIALOG_CRISPER_JS); source->AddResourcePath("crisper.js", IDR_INTERNET_CONFIG_DIALOG_CRISPER_JS);
#else #else
source->SetDefaultResource(IDR_INTERNET_CONFIG_DIALOG_HTML); source->SetDefaultResource(IDR_INTERNET_CONFIG_DIALOG_HTML);
......
...@@ -25,15 +25,22 @@ class InternetConfigDialog : public SystemWebDialogDelegate { ...@@ -25,15 +25,22 @@ class InternetConfigDialog : public SystemWebDialogDelegate {
static void ShowDialogForNetworkType(const std::string& network_type); static void ShowDialogForNetworkType(const std::string& network_type);
protected: protected:
InternetConfigDialog(const std::string& network_type, // |dialog_id| provides a pre-calculated identifier for the dialog based on
// the network type and the network id.
InternetConfigDialog(const std::string& dialog_id,
const std::string& network_type,
const std::string& network_id); const std::string& network_id);
~InternetConfigDialog() override; ~InternetConfigDialog() override;
// SystemWebDialogDelegate
const std::string& Id() override;
// ui::WebDialogDelegate // ui::WebDialogDelegate
void GetDialogSize(gfx::Size* size) const override; void GetDialogSize(gfx::Size* size) const override;
std::string GetDialogArgs() const override; std::string GetDialogArgs() const override;
private: private:
std::string dialog_id_;
std::string network_type_; std::string network_type_;
std::string network_id_; std::string network_id_;
......
...@@ -88,6 +88,12 @@ void InternetDetailDialog::ShowDialog(const std::string& network_id) { ...@@ -88,6 +88,12 @@ void InternetDetailDialog::ShowDialog(const std::string& network_id) {
LOG(ERROR) << "Network not found: " << network_id; LOG(ERROR) << "Network not found: " << network_id;
return; return;
} }
auto* instance = SystemWebDialogDelegate::FindInstance(network->guid());
if (instance) {
instance->Focus();
return;
}
InternetDetailDialog* dialog = new InternetDetailDialog(*network); InternetDetailDialog* dialog = new InternetDetailDialog(*network);
dialog->ShowSystemDialog(); dialog->ShowSystemDialog();
} }
...@@ -105,6 +111,10 @@ InternetDetailDialog::~InternetDetailDialog() { ...@@ -105,6 +111,10 @@ InternetDetailDialog::~InternetDetailDialog() {
--s_internet_detail_dialog_count; --s_internet_detail_dialog_count;
} }
const std::string& InternetDetailDialog::Id() {
return network_id_;
}
void InternetDetailDialog::GetDialogSize(gfx::Size* size) const { void InternetDetailDialog::GetDialogSize(gfx::Size* size) const {
size->SetSize(kInternetDetailDialogWidth, size->SetSize(kInternetDetailDialogWidth,
SystemWebDialogDelegate::kDialogHeight); SystemWebDialogDelegate::kDialogHeight);
...@@ -133,9 +143,9 @@ InternetDetailDialogUI::InternetDetailDialogUI(content::WebUI* web_ui) ...@@ -133,9 +143,9 @@ InternetDetailDialogUI::InternetDetailDialogUI(content::WebUI* web_ui)
#if BUILDFLAG(OPTIMIZE_WEBUI) #if BUILDFLAG(OPTIMIZE_WEBUI)
source->UseGzip(); source->UseGzip();
source->SetDefaultResource( source->SetDefaultResource(
base::FeatureList::IsEnabled(features::kWebUIPolymer2) ? base::FeatureList::IsEnabled(features::kWebUIPolymer2)
IDR_INTERNET_DETAIL_DIALOG_VULCANIZED_P2_HTML : ? IDR_INTERNET_DETAIL_DIALOG_VULCANIZED_P2_HTML
IDR_INTERNET_DETAIL_DIALOG_VULCANIZED_HTML); : IDR_INTERNET_DETAIL_DIALOG_VULCANIZED_HTML);
source->AddResourcePath("crisper.js", IDR_INTERNET_DETAIL_DIALOG_CRISPER_JS); source->AddResourcePath("crisper.js", IDR_INTERNET_DETAIL_DIALOG_CRISPER_JS);
#else #else
source->SetDefaultResource(IDR_INTERNET_DETAIL_DIALOG_HTML); source->SetDefaultResource(IDR_INTERNET_DETAIL_DIALOG_HTML);
......
...@@ -26,6 +26,9 @@ class InternetDetailDialog : public SystemWebDialogDelegate { ...@@ -26,6 +26,9 @@ class InternetDetailDialog : public SystemWebDialogDelegate {
explicit InternetDetailDialog(const NetworkState& network); explicit InternetDetailDialog(const NetworkState& network);
~InternetDetailDialog() override; ~InternetDetailDialog() override;
// SystemWebDialogDelegate
const std::string& Id() override;
// ui::WebDialogDelegate // ui::WebDialogDelegate
void GetDialogSize(gfx::Size* size) const override; void GetDialogSize(gfx::Size* size) const override;
std::string GetDialogArgs() const override; std::string GetDialogArgs() const override;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "chrome/browser/chromeos/login/login_manager_test.h" #include "chrome/browser/chromeos/login/login_manager_test.h"
#include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/login/startup_utils.h"
#include "chrome/common/webui_url_constants.h" #include "chrome/common/webui_url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/account_id/account_id.h" #include "components/account_id/account_id.h"
#include "content/public/common/service_manager_connection.h" #include "content/public/common/service_manager_connection.h"
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
...@@ -41,45 +42,50 @@ bool IsSystemModalWindowOpen() { ...@@ -41,45 +42,50 @@ bool IsSystemModalWindowOpen() {
return modal_open; return modal_open;
} }
class SystemWebDialogTest : public LoginManagerTest {
public:
SystemWebDialogTest()
: LoginManagerTest(false, true /* should_initialize_webui */) {}
~SystemWebDialogTest() override = default;
private:
DISALLOW_COPY_AND_ASSIGN(SystemWebDialogTest);
};
class MockSystemWebDialog : public SystemWebDialogDelegate { class MockSystemWebDialog : public SystemWebDialogDelegate {
public: public:
MockSystemWebDialog() explicit MockSystemWebDialog(const char* id = nullptr)
: SystemWebDialogDelegate(GURL(chrome::kChromeUIVersionURL), : SystemWebDialogDelegate(GURL(chrome::kChromeUIVersionURL),
base::string16()) {} base::string16()) {
if (id)
id_ = std::string(id);
}
~MockSystemWebDialog() override = default; ~MockSystemWebDialog() override = default;
const std::string& Id() override { return id_; }
std::string GetDialogArgs() const override { return std::string(); } std::string GetDialogArgs() const override { return std::string(); }
private: private:
std::string id_;
DISALLOW_COPY_AND_ASSIGN(MockSystemWebDialog); DISALLOW_COPY_AND_ASSIGN(MockSystemWebDialog);
}; };
} // namespace } // namespace
class SystemWebDialogLoginTest : public LoginManagerTest {
public:
SystemWebDialogLoginTest()
: LoginManagerTest(false, true /* should_initialize_webui */) {}
~SystemWebDialogLoginTest() override = default;
private:
DISALLOW_COPY_AND_ASSIGN(SystemWebDialogLoginTest);
};
// Verifies that system dialogs are modal before login (e.g. during OOBE). // Verifies that system dialogs are modal before login (e.g. during OOBE).
IN_PROC_BROWSER_TEST_F(SystemWebDialogTest, ModalTest) { IN_PROC_BROWSER_TEST_F(SystemWebDialogLoginTest, ModalTest) {
auto* dialog = new MockSystemWebDialog(); auto* dialog = new MockSystemWebDialog();
dialog->ShowSystemDialog(); dialog->ShowSystemDialog();
EXPECT_TRUE(IsSystemModalWindowOpen()); EXPECT_TRUE(IsSystemModalWindowOpen());
} }
IN_PROC_BROWSER_TEST_F(SystemWebDialogTest, PRE_NonModalTest) { IN_PROC_BROWSER_TEST_F(SystemWebDialogLoginTest, PRE_NonModalTest) {
RegisterUser(AccountId::FromUserEmailGaiaId(kTestUser, kTestUserGaiaId)); RegisterUser(AccountId::FromUserEmailGaiaId(kTestUser, kTestUserGaiaId));
StartupUtils::MarkOobeCompleted(); StartupUtils::MarkOobeCompleted();
} }
// Verifies that system dialogs are not modal and always-on-top after login. // Verifies that system dialogs are not modal and always-on-top after login.
IN_PROC_BROWSER_TEST_F(SystemWebDialogTest, NonModalTest) { IN_PROC_BROWSER_TEST_F(SystemWebDialogLoginTest, NonModalTest) {
LoginUser(AccountId::FromUserEmailGaiaId(kTestUser, kTestUserGaiaId)); LoginUser(AccountId::FromUserEmailGaiaId(kTestUser, kTestUserGaiaId));
auto* dialog = new MockSystemWebDialog(); auto* dialog = new MockSystemWebDialog();
dialog->ShowSystemDialog(); dialog->ShowSystemDialog();
...@@ -91,4 +97,18 @@ IN_PROC_BROWSER_TEST_F(SystemWebDialogTest, NonModalTest) { ...@@ -91,4 +97,18 @@ IN_PROC_BROWSER_TEST_F(SystemWebDialogTest, NonModalTest) {
EXPECT_TRUE(window_to_test->GetProperty(aura::client::kAlwaysOnTopKey)); EXPECT_TRUE(window_to_test->GetProperty(aura::client::kAlwaysOnTopKey));
} }
using SystemWebDialogTest = InProcessBrowserTest;
IN_PROC_BROWSER_TEST_F(SystemWebDialogTest, InstanceTest) {
const char* kDialogId = "dialog_id";
SystemWebDialogDelegate* dialog = new MockSystemWebDialog(kDialogId);
dialog->ShowSystemDialog();
SystemWebDialogDelegate* found_dialog =
SystemWebDialogDelegate::FindInstance(kDialogId);
EXPECT_EQ(dialog, found_dialog);
// Closing (deleting) the dialog causes a crash in WebDialogView when the main
// loop is run. TODO(stevenjb): Investigate, fix, and test closing the dialog.
// https://crbug.com/855344.
}
} // namespace chromeos } // namespace chromeos
...@@ -3,14 +3,40 @@ ...@@ -3,14 +3,40 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h" #include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h"
#include <list>
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "base/no_destructor.h"
#include "base/stl_util.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/views/chrome_web_dialog_view.h" #include "chrome/browser/ui/views/chrome_web_dialog_view.h"
#include "components/session_manager/core/session_manager.h" #include "components/session_manager/core/session_manager.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "ui/aura/window.h"
namespace chromeos { namespace chromeos {
namespace {
// Track all open system web dialog instances. This should be a small list.
std::list<SystemWebDialogDelegate*>* GetInstances() {
static base::NoDestructor<std::list<SystemWebDialogDelegate*>> instances;
return instances.get();
}
} // namespace
// static
SystemWebDialogDelegate* SystemWebDialogDelegate::FindInstance(
const std::string& id) {
auto* instances = GetInstances();
auto iter =
std::find_if(instances->begin(), instances->end(),
[id](SystemWebDialogDelegate* i) { return i->Id() == id; });
return iter == instances->end() ? nullptr : *iter;
}
SystemWebDialogDelegate::SystemWebDialogDelegate(const GURL& gurl, SystemWebDialogDelegate::SystemWebDialogDelegate(const GURL& gurl,
const base::string16& title) const base::string16& title)
: gurl_(gurl), title_(title), modal_type_(ui::MODAL_TYPE_NONE) { : gurl_(gurl), title_(title), modal_type_(ui::MODAL_TYPE_NONE) {
...@@ -28,9 +54,26 @@ SystemWebDialogDelegate::SystemWebDialogDelegate(const GURL& gurl, ...@@ -28,9 +54,26 @@ SystemWebDialogDelegate::SystemWebDialogDelegate(const GURL& gurl,
modal_type_ = ui::MODAL_TYPE_SYSTEM; modal_type_ = ui::MODAL_TYPE_SYSTEM;
break; break;
} }
GetInstances()->push_back(this);
}
SystemWebDialogDelegate::~SystemWebDialogDelegate() {
base::EraseIf(*GetInstances(),
[this](SystemWebDialogDelegate* i) { return i == this; });
} }
SystemWebDialogDelegate::~SystemWebDialogDelegate() {} const std::string& SystemWebDialogDelegate::Id() {
return gurl_.spec();
}
void SystemWebDialogDelegate::Focus() {
// Focusing a modal dialog does not make it the topmost dialog and does not
// enable interaction. It does however remove focus from the current dialog,
// preventing interaction with any dialog. TODO(stevenjb): Investigate and
// fix, https://crbug.com/914133.
if (modal_type_ == ui::MODAL_TYPE_NONE)
dialog_window()->Focus();
}
ui::ModalType SystemWebDialogDelegate::GetDialogModalType() const { ui::ModalType SystemWebDialogDelegate::GetDialogModalType() const {
return modal_type_; return modal_type_;
......
...@@ -24,11 +24,24 @@ namespace chromeos { ...@@ -24,11 +24,24 @@ namespace chromeos {
class SystemWebDialogDelegate : public ui::WebDialogDelegate { class SystemWebDialogDelegate : public ui::WebDialogDelegate {
public: public:
// Returns the instance whose Id() matches |id|. If more than one instance
// matches, the first matching instance created is returned.
static SystemWebDialogDelegate* FindInstance(const std::string& id);
// |gurl| is the HTML file path for the dialog content and must be set. // |gurl| is the HTML file path for the dialog content and must be set.
// |title| may be empty in which case ShouldShowDialogTitle() returns false. // |title| may be empty in which case ShouldShowDialogTitle() returns false.
SystemWebDialogDelegate(const GURL& gurl, const base::string16& title); SystemWebDialogDelegate(const GURL& gurl, const base::string16& title);
~SystemWebDialogDelegate() override; ~SystemWebDialogDelegate() override;
// Returns an identifier used for matching an instance in FindInstance.
// By default returns gurl_.spec() which should be sufficient for dialogs
// that only support a single instance.
virtual const std::string& Id();
// Focuses the dialog window. Note: No-op for modal dialogs, see
// implementation for details.
void Focus();
// ui::WebDialogDelegate // ui::WebDialogDelegate
ui::ModalType GetDialogModalType() const override; ui::ModalType GetDialogModalType() const override;
base::string16 GetDialogTitle() const override; base::string16 GetDialogTitle() const override;
...@@ -58,7 +71,7 @@ class SystemWebDialogDelegate : public ui::WebDialogDelegate { ...@@ -58,7 +71,7 @@ class SystemWebDialogDelegate : public ui::WebDialogDelegate {
static constexpr int kDialogHeight = 480; static constexpr int kDialogHeight = 480;
protected: protected:
FRIEND_TEST_ALL_PREFIXES(SystemWebDialogTest, NonModalTest); FRIEND_TEST_ALL_PREFIXES(SystemWebDialogLoginTest, NonModalTest);
gfx::NativeWindow dialog_window() const { return dialog_window_; } gfx::NativeWindow dialog_window() const { return dialog_window_; }
private: private:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment