diff options
-rw-r--r-- | ash/ash_strings.grd | 6 | ||||
-rw-r--r-- | ash/display/display_error_dialog.cc | 80 | ||||
-rw-r--r-- | ash/display/display_error_dialog.h | 44 | ||||
-rw-r--r-- | ash/display/display_error_dialog_unittest.cc | 84 | ||||
-rw-r--r-- | ash/display/output_configurator_animation.cc | 4 | ||||
-rw-r--r-- | ash/display/output_configurator_animation.h | 3 | ||||
-rw-r--r-- | ash/shell.cc | 13 | ||||
-rw-r--r-- | ash/shell.h | 5 | ||||
-rw-r--r-- | chromeos/display/output_configurator.cc | 19 | ||||
-rw-r--r-- | chromeos/display/output_configurator.h | 3 |
10 files changed, 59 insertions, 202 deletions
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 4163c3f..4178055 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd @@ -568,12 +568,6 @@ 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 64fe5c3..604d86a 100644 --- a/ash/display/display_error_dialog.cc +++ b/ash/display/display_error_dialog.cc @@ -27,20 +27,28 @@ 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 -DisplayErrorDialog* DisplayErrorDialog::ShowDialog( - chromeos::OutputState new_state) { +void DisplayErrorDialog::ShowDialog() { + if (g_instance) { + DCHECK(g_instance->GetWidget()); + g_instance->GetWidget()->StackAtTop(); + g_instance->GetWidget()->Activate(); + return; + } + gfx::Screen* screen = Shell::GetScreen(); const gfx::Display& target_display = (screen->GetNumDisplays() > 1) ? ScreenAsh::GetSecondaryDisplay() : screen->GetPrimaryDisplay(); - DisplayErrorDialog* dialog = new DisplayErrorDialog(new_state); + g_instance = new DisplayErrorDialog(); views::Widget* widget = new views::Widget; views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); - params.delegate = dialog; + params.delegate = g_instance; // Makes |widget| belong to the target display. Size and location are // fixed by CenterWindow() below. params.bounds = target_display.bounds(); @@ -54,37 +62,12 @@ DisplayErrorDialog* DisplayErrorDialog::ShowDialog( widget->GetNativeView()->SetName("DisplayErrorDialog"); widget->CenterWindow(widget->GetRootView()->GetPreferredSize()); widget->Show(); - return dialog; } -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) { +DisplayErrorDialog::DisplayErrorDialog() { Shell::GetInstance()->display_controller()->AddObserver(this); - label_ = new views::Label(); + label_ = new views::Label( + l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING)); AddChildView(label_); label_->SetMultiLine(true); @@ -94,12 +77,12 @@ DisplayErrorDialog::DisplayErrorDialog(chromeos::OutputState new_state) { kDialogMessageMarginWidthPixel, kDialogMessageMarginWidthPixel, kDialogMessageMarginWidthPixel)); - - UpdateMessageForState(new_state); + label_->SizeToFit(kDialogMessageWidthPixel); } DisplayErrorDialog::~DisplayErrorDialog() { Shell::GetInstance()->display_controller()->RemoveObserver(this); + g_instance = NULL; } int DisplayErrorDialog::GetDialogButtons() const { @@ -118,32 +101,9 @@ void DisplayErrorDialog::OnDisplayConfigurationChanging() { GetWidget()->Close(); } -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; +// static +DisplayErrorDialog* DisplayErrorDialog::GetInstanceForTest() { + return g_instance; } } // namespace internal diff --git a/ash/display/display_error_dialog.h b/ash/display/display_error_dialog.h index 541adc3..cd7829e 100644 --- a/ash/display/display_error_dialog.h +++ b/ash/display/display_error_dialog.h @@ -8,8 +8,7 @@ #include "ash/ash_export.h" #include "ash/display/display_controller.h" #include "base/compiler_specific.h" -#include "chromeos/display/output_configurator.h" -#include "ui/views/widget/widget_observer.h" +#include "base/gtest_prod_util.h" #include "ui/views/window/dialog_delegate.h" namespace aura { @@ -33,14 +32,16 @@ namespace internal { class ASH_EXPORT DisplayErrorDialog : public views::DialogDelegateView, public ash::DisplayController::Observer { public: - // Shows the error dialog for |failed_new_state| and returns it. - static DisplayErrorDialog* ShowDialog(chromeos::OutputState failed_new_state); - - // Update the error message for |failed_new_state|. - void UpdateMessageForState(chromeos::OutputState failed_new_state); + // Shows the error dialog. + static void ShowDialog(); private: - explicit DisplayErrorDialog(chromeos::OutputState failed_new_state); + FRIEND_TEST_ALL_PREFIXES(DisplayErrorDialogTest, Normal); + FRIEND_TEST_ALL_PREFIXES(DisplayErrorDialogTest, CallTwice); + FRIEND_TEST_ALL_PREFIXES(DisplayErrorDialogTest, SingleDisplay); + FRIEND_TEST_ALL_PREFIXES(DisplayErrorDialogTest, DisplayDisconnected); + + DisplayErrorDialog(); virtual ~DisplayErrorDialog(); // views::DialogDelegate overrides: @@ -55,35 +56,14 @@ 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 16ff625..e4d21d5 100644 --- a/ash/display/display_error_dialog_unittest.cc +++ b/ash/display/display_error_dialog_unittest.cc @@ -6,98 +6,39 @@ #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 { -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); -}; - -} +typedef test::AshTestBase 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* dialog = - DisplayErrorDialog::ShowDialog(chromeos::STATE_DUAL_MIRROR); + DisplayErrorDialog::ShowDialog(); + DisplayErrorDialog* dialog = DisplayErrorDialog::GetInstanceForTest(); 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"); - 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(); + DisplayErrorDialog::ShowDialog(); + DisplayErrorDialog* dialog = DisplayErrorDialog::GetInstanceForTest(); EXPECT_TRUE(dialog); - 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)); + DisplayErrorDialog::ShowDialog(); + EXPECT_EQ(dialog, DisplayErrorDialog::GetInstanceForTest()); } TEST_F(DisplayErrorDialogTest, SingleDisplay) { UpdateDisplay("200x200"); - DisplayErrorDialog* dialog = - DisplayErrorDialog::ShowDialog(chromeos::STATE_DUAL_MIRROR); + DisplayErrorDialog::ShowDialog(); + DisplayErrorDialog* dialog = DisplayErrorDialog::GetInstanceForTest(); EXPECT_TRUE(dialog); EXPECT_TRUE(dialog->GetWidget()->IsVisible()); EXPECT_EQ(Shell::GetInstance()->GetPrimaryRootWindow(), @@ -106,14 +47,15 @@ TEST_F(DisplayErrorDialogTest, SingleDisplay) { TEST_F(DisplayErrorDialogTest, DisplayDisconnected) { UpdateDisplay("200x200,300x300"); - observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_MIRROR); - EXPECT_TRUE(observer()->dialog()); + DisplayErrorDialog::ShowDialog(); + DisplayErrorDialog* dialog = DisplayErrorDialog::GetInstanceForTest(); + EXPECT_TRUE(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(observer()->dialog()); + EXPECT_FALSE(DisplayErrorDialog::GetInstanceForTest()); } } // namespace internal diff --git a/ash/display/output_configurator_animation.cc b/ash/display/output_configurator_animation.cc index 6c6d78d..8d47963 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( - chromeos::OutputState failed_new_state) { +void OutputConfiguratorAnimation::OnDisplayModeChangeFailed() { 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 dc70264..9dc99c6 100644 --- a/ash/display/output_configurator_animation.h +++ b/ash/display/output_configurator_animation.h @@ -43,8 +43,7 @@ class ASH_EXPORT OutputConfiguratorAnimation protected: // chromeos::OutputConfigurator::Observer overrides: virtual void OnDisplayModeChanged() OVERRIDE; - virtual void OnDisplayModeChangeFailed( - chromeos::OutputState failed_new_state) OVERRIDE; + virtual void OnDisplayModeChangeFailed() 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 c6965b2..ffa015a 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -106,7 +106,6 @@ #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" @@ -304,19 +303,17 @@ 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 @@ -421,10 +418,8 @@ 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()); - display_error_observer_.reset(new internal::DisplayErrorObserver()); + new internal::OutputConfiguratorAnimation()), 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 5ed4cd7..c6047ea00 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -103,7 +103,6 @@ class ActivationController; class AppListController; class CaptureController; class DisplayChangeObserverX11; -class DisplayErrorObserver; class DisplayManager; class DragDropController; class EventClientImpl; @@ -435,9 +434,6 @@ 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() { @@ -583,7 +579,6 @@ 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 4357b1a..00c0f72 100644 --- a/chromeos/display/output_configurator.cc +++ b/chromeos/display/output_configurator.cc @@ -654,12 +654,10 @@ bool OutputConfigurator::CycleDisplayMode() { XRRFreeScreenResources(screen); XUngrabServer(display); - if (did_change) { + if (did_change) NotifyOnDisplayChanged(); - } else { - FOR_EACH_OBSERVER( - Observer, observers_, OnDisplayModeChangeFailed(next_state)); - } + else + FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChangeFailed()); return did_change; } @@ -761,12 +759,10 @@ 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(new_state)); - } + else + FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChangeFailed()); return true; } @@ -837,9 +833,6 @@ 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 804f856..cd3420a 100644 --- a/chromeos/display/output_configurator.h +++ b/chromeos/display/output_configurator.h @@ -57,8 +57,7 @@ class CHROMEOS_EXPORT OutputConfigurator : public MessageLoop::Dispatcher { virtual void OnDisplayModeChanged() {} // Called when the change of the display mode is issued but failed. - // |failed_new_state| is the new state which the system failed to enter. - virtual void OnDisplayModeChangeFailed(OutputState failed_new_state) {} + virtual void OnDisplayModeChangeFailed() {} }; OutputConfigurator(); |