summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormukai@chromium.org <mukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-01 20:56:23 +0000
committermukai@chromium.org <mukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-01 20:56:23 +0000
commit18b21b2e9aa6cf49d4ee4556461c028f4d74f0cf (patch)
treef023a423afa5942d5ff06e5091fc9e98084a999a
parent7f7c45d5a4a34d36310f41dbe2bfb375056582b4 (diff)
downloadchromium_src-18b21b2e9aa6cf49d4ee4556461c028f4d74f0cf.zip
chromium_src-18b21b2e9aa6cf49d4ee4556461c028f4d74f0cf.tar.gz
chromium_src-18b21b2e9aa6cf49d4ee4556461c028f4d74f0cf.tar.bz2
Provides more types of errors for display status (2nd)
Note that the text message itself is a placeholder. It has to be replaced by real sentences. Previous CL was reverted due to build failures on win aura. BUG=176011 TBR=jamescook@chromium.org,oshima@chromium.org TEST=ash_unittests passes on win_aura Review URL: https://codereview.chromium.org/12387043 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@185592 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/ash.gyp7
-rw-r--r--ash/ash_strings.grd6
-rw-r--r--ash/display/display_error_dialog.cc80
-rw-r--r--ash/display/display_error_dialog.h44
-rw-r--r--ash/display/display_error_dialog_unittest.cc84
-rw-r--r--ash/display/output_configurator_animation.cc4
-rw-r--r--ash/display/output_configurator_animation.h3
-rw-r--r--ash/shell.cc13
-rw-r--r--ash/shell.h5
-rw-r--r--chromeos/display/output_configurator.cc19
-rw-r--r--chromeos/display/output_configurator.h3
11 files changed, 209 insertions, 59 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index ec824a4..6429ed472 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -487,6 +487,8 @@
}, { # else: chromeos!=1
'sources/': [
['exclude', '/chromeos/'],
+ ['exclude', 'display/display_error_dialog.cc'],
+ ['exclude', 'display/display_error_dialog.h'],
['exclude', 'display/output_configurator_animation.cc'],
['exclude', 'display/output_configurator_animation.h'],
],
@@ -687,6 +689,11 @@
# are not referenced in code, but are referenced in nibs.
'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-ObjC']},
}],
+ ['chromeos!=1', {
+ 'sources/': [
+ ['exclude', 'display/display_error_dialog_unittest.cc'],
+ ],
+ }],
],
},
{
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index 4178055..4163c3f 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -568,6 +568,12 @@ Press Shift + Alt to switch.
<message name="IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING" desc="An error message to show that the system failed to enter the mirroring mode.">
Can't duplicate image on attached monitors. No matching resolution found.
</message>
+ <message name="IDS_ASH_DISPLAY_FAILURE_ON_EXTENDED" desc="An error message to show that the system failed to enter the extended desktop mode.">
+ Can't create extended desktop. No output mode found.
+ </message>
+ <message name="IDS_ASH_DISPLAY_FAILURE_UNKNOWN" desc="An error message to show that the system failed to enter a wrong output mode.">
+ Can't enter the new output status.
+ </message>
<message name="IDS_ASH_INTERNAL_DISPLAY_NAME" desc="The name of the internal display which is shown in the display settings.">
Internal Display
</message>
diff --git a/ash/display/display_error_dialog.cc b/ash/display/display_error_dialog.cc
index 604d86a..64fe5c3 100644
--- a/ash/display/display_error_dialog.cc
+++ b/ash/display/display_error_dialog.cc
@@ -27,28 +27,20 @@ const int kDialogMessageWidthPixel = 300;
// The margin width from the error message to the edge of the dialog.
const int kDialogMessageMarginWidthPixel = 5;
-DisplayErrorDialog* g_instance = NULL;
-
} // namespace
// static
-void DisplayErrorDialog::ShowDialog() {
- if (g_instance) {
- DCHECK(g_instance->GetWidget());
- g_instance->GetWidget()->StackAtTop();
- g_instance->GetWidget()->Activate();
- return;
- }
-
+DisplayErrorDialog* DisplayErrorDialog::ShowDialog(
+ chromeos::OutputState new_state) {
gfx::Screen* screen = Shell::GetScreen();
const gfx::Display& target_display =
(screen->GetNumDisplays() > 1) ?
ScreenAsh::GetSecondaryDisplay() : screen->GetPrimaryDisplay();
- g_instance = new DisplayErrorDialog();
+ DisplayErrorDialog* dialog = new DisplayErrorDialog(new_state);
views::Widget* widget = new views::Widget;
views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
- params.delegate = g_instance;
+ params.delegate = dialog;
// Makes |widget| belong to the target display. Size and location are
// fixed by CenterWindow() below.
params.bounds = target_display.bounds();
@@ -62,12 +54,37 @@ void DisplayErrorDialog::ShowDialog() {
widget->GetNativeView()->SetName("DisplayErrorDialog");
widget->CenterWindow(widget->GetRootView()->GetPreferredSize());
widget->Show();
+ return dialog;
}
-DisplayErrorDialog::DisplayErrorDialog() {
+void DisplayErrorDialog::UpdateMessageForState(
+ chromeos::OutputState new_state) {
+ int message_id = -1;
+ switch (new_state) {
+ case chromeos::STATE_DUAL_MIRROR:
+ message_id = IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING;
+ break;
+ case chromeos::STATE_DUAL_EXTENDED:
+ message_id = IDS_ASH_DISPLAY_FAILURE_ON_EXTENDED;
+ break;
+ default:
+ // The error dialog would appear only for mirroring or extended.
+ // It's quite unlikely to happen with other status (single-display /
+ // invalid / unknown status), but set an unknown error message
+ // instead of NOTREACHED() just in case for safety.
+ LOG(ERROR) << "Unexpected failure for new state: " << new_state;
+ message_id = IDS_ASH_DISPLAY_FAILURE_UNKNOWN;
+ break;
+ }
+ label_->SetText(l10n_util::GetStringUTF16(message_id));
+ label_->SizeToFit(kDialogMessageWidthPixel);
+ Layout();
+ SchedulePaint();
+}
+
+DisplayErrorDialog::DisplayErrorDialog(chromeos::OutputState new_state) {
Shell::GetInstance()->display_controller()->AddObserver(this);
- label_ = new views::Label(
- l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING));
+ label_ = new views::Label();
AddChildView(label_);
label_->SetMultiLine(true);
@@ -77,12 +94,12 @@ DisplayErrorDialog::DisplayErrorDialog() {
kDialogMessageMarginWidthPixel,
kDialogMessageMarginWidthPixel,
kDialogMessageMarginWidthPixel));
- label_->SizeToFit(kDialogMessageWidthPixel);
+
+ UpdateMessageForState(new_state);
}
DisplayErrorDialog::~DisplayErrorDialog() {
Shell::GetInstance()->display_controller()->RemoveObserver(this);
- g_instance = NULL;
}
int DisplayErrorDialog::GetDialogButtons() const {
@@ -101,9 +118,32 @@ void DisplayErrorDialog::OnDisplayConfigurationChanging() {
GetWidget()->Close();
}
-// static
-DisplayErrorDialog* DisplayErrorDialog::GetInstanceForTest() {
- return g_instance;
+DisplayErrorObserver::DisplayErrorObserver()
+ : dialog_(NULL) {
+}
+
+DisplayErrorObserver::~DisplayErrorObserver() {
+ DCHECK(!dialog_);
+}
+
+void DisplayErrorObserver::OnDisplayModeChangeFailed(
+ chromeos::OutputState new_state) {
+ if (dialog_) {
+ DCHECK(dialog_->GetWidget());
+ dialog_->UpdateMessageForState(new_state);
+ dialog_->GetWidget()->StackAtTop();
+ dialog_->GetWidget()->Activate();
+ } else {
+ dialog_ = DisplayErrorDialog::ShowDialog(new_state);
+ dialog_->GetWidget()->AddObserver(this);
+ }
+}
+
+void DisplayErrorObserver::OnWidgetClosing(views::Widget* widget) {
+ DCHECK(dialog_);
+ DCHECK_EQ(dialog_->GetWidget(), widget);
+ widget->RemoveObserver(this);
+ dialog_ = NULL;
}
} // namespace internal
diff --git a/ash/display/display_error_dialog.h b/ash/display/display_error_dialog.h
index cd7829e..541adc3 100644
--- a/ash/display/display_error_dialog.h
+++ b/ash/display/display_error_dialog.h
@@ -8,7 +8,8 @@
#include "ash/ash_export.h"
#include "ash/display/display_controller.h"
#include "base/compiler_specific.h"
-#include "base/gtest_prod_util.h"
+#include "chromeos/display/output_configurator.h"
+#include "ui/views/widget/widget_observer.h"
#include "ui/views/window/dialog_delegate.h"
namespace aura {
@@ -32,16 +33,14 @@ namespace internal {
class ASH_EXPORT DisplayErrorDialog : public views::DialogDelegateView,
public ash::DisplayController::Observer {
public:
- // Shows the error dialog.
- static void ShowDialog();
+ // Shows the error dialog for |failed_new_state| and returns it.
+ static DisplayErrorDialog* ShowDialog(chromeos::OutputState failed_new_state);
- private:
- FRIEND_TEST_ALL_PREFIXES(DisplayErrorDialogTest, Normal);
- FRIEND_TEST_ALL_PREFIXES(DisplayErrorDialogTest, CallTwice);
- FRIEND_TEST_ALL_PREFIXES(DisplayErrorDialogTest, SingleDisplay);
- FRIEND_TEST_ALL_PREFIXES(DisplayErrorDialogTest, DisplayDisconnected);
+ // Update the error message for |failed_new_state|.
+ void UpdateMessageForState(chromeos::OutputState failed_new_state);
- DisplayErrorDialog();
+ private:
+ explicit DisplayErrorDialog(chromeos::OutputState failed_new_state);
virtual ~DisplayErrorDialog();
// views::DialogDelegate overrides:
@@ -56,14 +55,35 @@ class ASH_EXPORT DisplayErrorDialog : public views::DialogDelegateView,
// ash::DisplayController::Observer overrides:
virtual void OnDisplayConfigurationChanging() OVERRIDE;
- // Returns the pointer of the current instance of this dialog.
- static DisplayErrorDialog* GetInstanceForTest();
-
views::Label* label_;
DISALLOW_COPY_AND_ASSIGN(DisplayErrorDialog);
};
+// The class to observe the output failures and shows the error dialog when
+// necessary.
+class ASH_EXPORT DisplayErrorObserver
+ : public chromeos::OutputConfigurator::Observer,
+ public views::WidgetObserver {
+ public:
+ DisplayErrorObserver();
+ virtual ~DisplayErrorObserver();
+
+ const DisplayErrorDialog* dialog() const { return dialog_; }
+
+ // chromeos::OutputConfigurator::Observer overrides:
+ virtual void OnDisplayModeChangeFailed(
+ chromeos::OutputState failed_new_state) OVERRIDE;
+
+ // views::WidgetObserver overrides:
+ virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
+
+ private:
+ DisplayErrorDialog* dialog_;
+
+ DISALLOW_COPY_AND_ASSIGN(DisplayErrorObserver);
+};
+
} // namespace internal
} // namespace ash
diff --git a/ash/display/display_error_dialog_unittest.cc b/ash/display/display_error_dialog_unittest.cc
index e4d21d5..16ff625 100644
--- a/ash/display/display_error_dialog_unittest.cc
+++ b/ash/display/display_error_dialog_unittest.cc
@@ -6,39 +6,98 @@
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
+#include "grit/ash_strings.h"
#include "ui/aura/window.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
namespace ash {
namespace internal {
+namespace {
-typedef test::AshTestBase DisplayErrorDialogTest;
+class DisplayErrorDialogTest : public test::AshTestBase {
+ protected:
+ DisplayErrorDialogTest() {
+ }
+
+ virtual ~DisplayErrorDialogTest() {
+ }
+
+ virtual void SetUp() OVERRIDE {
+ test::AshTestBase::SetUp();
+ observer_.reset(new DisplayErrorObserver());
+ }
+
+ virtual void TearDown() OVERRIDE {
+ if (observer_->dialog()) {
+ views::Widget* widget =
+ const_cast<DisplayErrorDialog*>(observer_->dialog())->GetWidget();
+ widget->CloseNow();
+ }
+ observer_.reset();
+ test::AshTestBase::TearDown();
+ }
+
+ DisplayErrorObserver* observer() { return observer_.get(); }
+
+ const string16& GetMessageContents(const DisplayErrorDialog* dialog) {
+ const views::Label* label = static_cast<const views::Label*>(
+ static_cast<const views::View*>(dialog)->child_at(0));
+ return label->text();
+ }
+
+ private:
+ scoped_ptr<DisplayErrorObserver> observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(DisplayErrorDialogTest);
+};
+
+}
// The test cases in this file usually check if the showing dialog doesn't
// cause any crashes, and the code doesn't cause any memory leaks.
TEST_F(DisplayErrorDialogTest, Normal) {
UpdateDisplay("200x200,300x300");
- DisplayErrorDialog::ShowDialog();
- DisplayErrorDialog* dialog = DisplayErrorDialog::GetInstanceForTest();
+ DisplayErrorDialog* dialog =
+ DisplayErrorDialog::ShowDialog(chromeos::STATE_DUAL_MIRROR);
EXPECT_TRUE(dialog);
EXPECT_TRUE(dialog->GetWidget()->IsVisible());
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING),
+ GetMessageContents(dialog));
EXPECT_EQ(Shell::GetAllRootWindows()[1],
dialog->GetWidget()->GetNativeView()->GetRootWindow());
}
TEST_F(DisplayErrorDialogTest, CallTwice) {
UpdateDisplay("200x200,300x300");
- DisplayErrorDialog::ShowDialog();
- DisplayErrorDialog* dialog = DisplayErrorDialog::GetInstanceForTest();
+ observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_MIRROR);
+ const DisplayErrorDialog* dialog = observer()->dialog();
+ EXPECT_TRUE(dialog);
+
+ observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_MIRROR);
+ EXPECT_EQ(dialog, observer()->dialog());
+}
+
+TEST_F(DisplayErrorDialogTest, CallWithDifferentState) {
+ UpdateDisplay("200x200,300x300");
+ observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_MIRROR);
+ const DisplayErrorDialog* dialog = observer()->dialog();
EXPECT_TRUE(dialog);
- DisplayErrorDialog::ShowDialog();
- EXPECT_EQ(dialog, DisplayErrorDialog::GetInstanceForTest());
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING),
+ GetMessageContents(dialog));
+
+ observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_EXTENDED);
+ EXPECT_EQ(dialog, observer()->dialog());
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_FAILURE_ON_EXTENDED),
+ GetMessageContents(dialog));
}
TEST_F(DisplayErrorDialogTest, SingleDisplay) {
UpdateDisplay("200x200");
- DisplayErrorDialog::ShowDialog();
- DisplayErrorDialog* dialog = DisplayErrorDialog::GetInstanceForTest();
+ DisplayErrorDialog* dialog =
+ DisplayErrorDialog::ShowDialog(chromeos::STATE_DUAL_MIRROR);
EXPECT_TRUE(dialog);
EXPECT_TRUE(dialog->GetWidget()->IsVisible());
EXPECT_EQ(Shell::GetInstance()->GetPrimaryRootWindow(),
@@ -47,15 +106,14 @@ TEST_F(DisplayErrorDialogTest, SingleDisplay) {
TEST_F(DisplayErrorDialogTest, DisplayDisconnected) {
UpdateDisplay("200x200,300x300");
- DisplayErrorDialog::ShowDialog();
- DisplayErrorDialog* dialog = DisplayErrorDialog::GetInstanceForTest();
- EXPECT_TRUE(dialog);
+ observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_MIRROR);
+ EXPECT_TRUE(observer()->dialog());
UpdateDisplay("200x200");
// Disconnection will close the dialog but we have to run all pending tasks
// to make the effect of the close.
RunAllPendingInMessageLoop();
- EXPECT_FALSE(DisplayErrorDialog::GetInstanceForTest());
+ EXPECT_FALSE(observer()->dialog());
}
} // namespace internal
diff --git a/ash/display/output_configurator_animation.cc b/ash/display/output_configurator_animation.cc
index 8d47963..6c6d78d 100644
--- a/ash/display/output_configurator_animation.cc
+++ b/ash/display/output_configurator_animation.cc
@@ -209,10 +209,10 @@ void OutputConfiguratorAnimation::OnDisplayModeChanged() {
StartFadeInAnimation();
}
-void OutputConfiguratorAnimation::OnDisplayModeChangeFailed() {
+void OutputConfiguratorAnimation::OnDisplayModeChangeFailed(
+ chromeos::OutputState failed_new_state) {
if (!hiding_layers_.empty())
StartFadeInAnimation();
- DisplayErrorDialog::ShowDialog();
}
void OutputConfiguratorAnimation::ClearHidingLayers() {
diff --git a/ash/display/output_configurator_animation.h b/ash/display/output_configurator_animation.h
index 9dc99c6..dc70264 100644
--- a/ash/display/output_configurator_animation.h
+++ b/ash/display/output_configurator_animation.h
@@ -43,7 +43,8 @@ class ASH_EXPORT OutputConfiguratorAnimation
protected:
// chromeos::OutputConfigurator::Observer overrides:
virtual void OnDisplayModeChanged() OVERRIDE;
- virtual void OnDisplayModeChangeFailed() OVERRIDE;
+ virtual void OnDisplayModeChangeFailed(
+ chromeos::OutputState failed_new_state) OVERRIDE;
private:
// Clears all hiding layers. Note that in case that this method is called
diff --git a/ash/shell.cc b/ash/shell.cc
index ffa015a..c6965b2 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -106,6 +106,7 @@
#if defined(OS_CHROMEOS)
#include "ash/ash_constants.h"
#include "ash/display/display_change_observer_x11.h"
+#include "ash/display/display_error_dialog.h"
#include "ash/display/output_configurator_animation.h"
#include "base/chromeos/chromeos_version.h"
#include "base/message_pump_aurax11.h"
@@ -303,17 +304,19 @@ Shell::~Shell() {
// because they might have registered ActivationChangeObserver.
activation_controller_.reset();
- DCHECK(instance_ == this);
- instance_ = NULL;
-
#if defined(OS_CHROMEOS)
if (display_change_observer_.get())
output_configurator_->RemoveObserver(display_change_observer_.get());
if (output_configurator_animation_.get())
output_configurator_->RemoveObserver(output_configurator_animation_.get());
+ if (display_error_observer_.get())
+ output_configurator_->RemoveObserver(display_error_observer_.get());
base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(
output_configurator());
#endif // defined(OS_CHROMEOS)
+
+ DCHECK(instance_ == this);
+ instance_ = NULL;
}
// static
@@ -418,8 +421,10 @@ void Shell::Init() {
// observer gets invoked after the root windows are configured.
output_configurator_->AddObserver(display_change_observer_.get());
output_configurator_animation_.reset(
- new internal::OutputConfiguratorAnimation()),
+ new internal::OutputConfiguratorAnimation());
+ display_error_observer_.reset(new internal::DisplayErrorObserver());
output_configurator_->AddObserver(output_configurator_animation_.get());
+ output_configurator_->AddObserver(display_error_observer_.get());
display_change_observer_->OnDisplayModeChanged();
}
#endif
diff --git a/ash/shell.h b/ash/shell.h
index c6047ea00..5ed4cd7 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -103,6 +103,7 @@ class ActivationController;
class AppListController;
class CaptureController;
class DisplayChangeObserverX11;
+class DisplayErrorObserver;
class DisplayManager;
class DragDropController;
class EventClientImpl;
@@ -434,6 +435,9 @@ class ASH_EXPORT Shell
internal::OutputConfiguratorAnimation* output_configurator_animation() {
return output_configurator_animation_.get();
}
+ internal::DisplayErrorObserver* display_error_observer() {
+ return display_error_observer_.get();
+ }
#endif // defined(OS_CHROMEOS)
RootWindowHostFactory* root_window_host_factory() {
@@ -579,6 +583,7 @@ class ASH_EXPORT Shell
scoped_ptr<chromeos::OutputConfigurator> output_configurator_;
scoped_ptr<internal::OutputConfiguratorAnimation>
output_configurator_animation_;
+ scoped_ptr<internal::DisplayErrorObserver> display_error_observer_;
// Receives output change events and udpates the display manager.
scoped_ptr<internal::DisplayChangeObserverX11> display_change_observer_;
diff --git a/chromeos/display/output_configurator.cc b/chromeos/display/output_configurator.cc
index 00c0f72..4357b1a 100644
--- a/chromeos/display/output_configurator.cc
+++ b/chromeos/display/output_configurator.cc
@@ -654,10 +654,12 @@ bool OutputConfigurator::CycleDisplayMode() {
XRRFreeScreenResources(screen);
XUngrabServer(display);
- if (did_change)
+ if (did_change) {
NotifyOnDisplayChanged();
- else
- FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChangeFailed());
+ } else {
+ FOR_EACH_OBSERVER(
+ Observer, observers_, OnDisplayModeChangeFailed(next_state));
+ }
return did_change;
}
@@ -759,10 +761,12 @@ bool OutputConfigurator::SetDisplayMode(OutputState new_state) {
XRRFreeScreenResources(screen);
XUngrabServer(display);
- if (output_state_ == new_state)
+ if (output_state_ == new_state) {
NotifyOnDisplayChanged();
- else
- FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChangeFailed());
+ } else {
+ FOR_EACH_OBSERVER(
+ Observer, observers_, OnDisplayModeChangeFailed(new_state));
+ }
return true;
}
@@ -833,6 +837,9 @@ void OutputConfigurator::ConfigureOutputs() {
if (success) {
output_state_ = new_state;
NotifyOnDisplayChanged();
+ } else {
+ FOR_EACH_OBSERVER(
+ Observer, observers_, OnDisplayModeChangeFailed(new_state));
}
chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
SetIsProjecting(is_projecting);
diff --git a/chromeos/display/output_configurator.h b/chromeos/display/output_configurator.h
index cd3420a..804f856 100644
--- a/chromeos/display/output_configurator.h
+++ b/chromeos/display/output_configurator.h
@@ -57,7 +57,8 @@ class CHROMEOS_EXPORT OutputConfigurator : public MessageLoop::Dispatcher {
virtual void OnDisplayModeChanged() {}
// Called when the change of the display mode is issued but failed.
- virtual void OnDisplayModeChangeFailed() {}
+ // |failed_new_state| is the new state which the system failed to enter.
+ virtual void OnDisplayModeChangeFailed(OutputState failed_new_state) {}
};
OutputConfigurator();