summaryrefslogtreecommitdiffstats
path: root/chromeos
diff options
context:
space:
mode:
Diffstat (limited to 'chromeos')
-rw-r--r--chromeos/display/output_configurator.cc49
-rw-r--r--chromeos/display/output_configurator.h9
-rw-r--r--chromeos/display/output_configurator_unittest.cc41
3 files changed, 82 insertions, 17 deletions
diff --git a/chromeos/display/output_configurator.cc b/chromeos/display/output_configurator.cc
index fb545aa..852b794 100644
--- a/chromeos/display/output_configurator.cc
+++ b/chromeos/display/output_configurator.cc
@@ -106,20 +106,6 @@ int GetOutputPower(
return num_on_outputs;
}
-// Determine if there is an "internal" output and how many outputs are
-// connected.
-bool IsProjecting(
- const std::vector<OutputConfigurator::OutputSnapshot>& outputs) {
- bool has_internal_output = false;
- int connected_output_count = outputs.size();
- for (size_t i = 0; i < outputs.size(); ++i)
- has_internal_output |= outputs[i].type == OUTPUT_TYPE_INTERNAL;
-
- // "Projecting" is defined as having more than 1 output connected while at
- // least one of them is an internal output.
- return has_internal_output && (connected_output_count > 1);
-}
-
} // namespace
OutputConfigurator::ModeInfo::ModeInfo()
@@ -252,7 +238,8 @@ OutputConfigurator::OutputConfigurator()
xrandr_event_base_(0),
output_state_(STATE_INVALID),
power_state_(DISPLAY_POWER_ALL_ON),
- next_output_protection_client_id_(1) {
+ next_output_protection_client_id_(1),
+ casting_session_count_(0) {
}
OutputConfigurator::~OutputConfigurator() {}
@@ -294,7 +281,7 @@ void OutputConfigurator::Start(uint32 background_color_argb) {
// that all displays are on when signing out.
delegate_->ForceDPMSOn();
delegate_->UngrabServer();
- delegate_->SendProjectingStateToPowerManager(IsProjecting(cached_outputs_));
+ SendProjectingStateToPowerManager();
NotifyObservers(success, new_state);
}
@@ -335,6 +322,22 @@ bool OutputConfigurator::ApplyProtections(const DisplayProtections& requests) {
return true;
}
+void OutputConfigurator::SendProjectingStateToPowerManager() {
+ bool has_internal_output = false;
+ int connected_output_count = cached_outputs_.size() + casting_session_count_;
+ for (size_t i = 0; i < cached_outputs_.size(); ++i) {
+ if (cached_outputs_[i].type == OUTPUT_TYPE_INTERNAL) {
+ has_internal_output = true;
+ break;
+ }
+ }
+
+ // "Projecting" is defined as having more than 1 output connected while at
+ // least one of them is an internal output.
+ bool is_projecting = has_internal_output && (connected_output_count > 1);
+ delegate_->SendProjectingStateToPowerManager(is_projecting);
+}
+
OutputConfigurator::OutputProtectionClientId
OutputConfigurator::RegisterOutputProtectionClient() {
if (!configure_display_)
@@ -599,6 +602,18 @@ base::EventStatus OutputConfigurator::WillProcessEvent(
void OutputConfigurator::DidProcessEvent(const base::NativeEvent& event) {
}
+void OutputConfigurator::OnCastingSessionStartedOrStopped(bool started) {
+ if (started) {
+ ++casting_session_count_;
+ } else {
+ DCHECK_GT(casting_session_count_, 0);
+ --casting_session_count_;
+ if (casting_session_count_ < 0)
+ casting_session_count_ = 0;
+ }
+ SendProjectingStateToPowerManager();
+}
+
void OutputConfigurator::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
@@ -777,7 +792,7 @@ void OutputConfigurator::ConfigureOutputs() {
delegate_->UngrabServer();
NotifyObservers(success, new_state);
- delegate_->SendProjectingStateToPowerManager(IsProjecting(cached_outputs_));
+ SendProjectingStateToPowerManager();
}
void OutputConfigurator::NotifyObservers(bool success,
diff --git a/chromeos/display/output_configurator.h b/chromeos/display/output_configurator.h
index 7144d2a..8a8b36d 100644
--- a/chromeos/display/output_configurator.h
+++ b/chromeos/display/output_configurator.h
@@ -379,6 +379,9 @@ class CHROMEOS_EXPORT OutputConfigurator
const base::NativeEvent& event) OVERRIDE;
virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
+ // Called when a casting session is started or stopped.
+ void OnCastingSessionStartedOrStopped(bool started);
+
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
@@ -503,6 +506,9 @@ class CHROMEOS_EXPORT OutputConfigurator
// Applies output protections according to requests.
bool ApplyProtections(const DisplayProtections& requests);
+ // Sends the current projecting state to power manager.
+ void SendProjectingStateToPowerManager();
+
StateController* state_controller_;
SoftwareMirroringController* mirroring_controller_;
scoped_ptr<Delegate> delegate_;
@@ -551,6 +557,9 @@ class CHROMEOS_EXPORT OutputConfigurator
// Output protection requests of each client.
ProtectionRequests client_protection_requests_;
+ // Number of outstanding casting sessions.
+ int casting_session_count_;
+
DISALLOW_COPY_AND_ASSIGN(OutputConfigurator);
};
diff --git a/chromeos/display/output_configurator_unittest.cc b/chromeos/display/output_configurator_unittest.cc
index c253270a..7c74bd3 100644
--- a/chromeos/display/output_configurator_unittest.cc
+++ b/chromeos/display/output_configurator_unittest.cc
@@ -787,6 +787,47 @@ TEST_F(OutputConfiguratorTest, SetDisplayPower) {
EXPECT_EQ(1, observer_.num_changes());
}
+TEST_F(OutputConfiguratorTest, Casting) {
+ InitWithSingleOutput();
+
+ // Notify configurator that casting session is started.
+ configurator_.OnCastingSessionStartedOrStopped(true);
+ EXPECT_EQ(kProjectingOn, delegate_->GetActionsAndClear());
+
+ // Verify that the configurator keeps a count of active casting sessions
+ // instead of treating it as a single global state.
+ configurator_.OnCastingSessionStartedOrStopped(true);
+ EXPECT_EQ(kProjectingOn, delegate_->GetActionsAndClear());
+ configurator_.OnCastingSessionStartedOrStopped(false);
+ EXPECT_EQ(kProjectingOn, delegate_->GetActionsAndClear());
+
+ // Turn all displays off and check that projecting is not turned off.
+ configurator_.SetDisplayPower(DISPLAY_POWER_ALL_OFF,
+ OutputConfigurator::kSetDisplayPowerNoFlags);
+ EXPECT_EQ(JoinActions(kGrab,
+ GetFramebufferAction(kSmallModeWidth, kSmallModeHeight,
+ outputs_[0].crtc, 0).c_str(),
+ GetCrtcAction(outputs_[0].crtc, 0, 0, 0,
+ outputs_[0].output).c_str(),
+ kUngrab, NULL),
+ delegate_->GetActionsAndClear());
+
+ // Turn all displays back on.
+ configurator_.SetDisplayPower(DISPLAY_POWER_ALL_ON,
+ OutputConfigurator::kSetDisplayPowerNoFlags);
+ EXPECT_EQ(JoinActions(kGrab,
+ GetFramebufferAction(kSmallModeWidth, kSmallModeHeight,
+ outputs_[0].crtc, 0).c_str(),
+ GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId,
+ outputs_[0].output).c_str(),
+ kForceDPMS, kUngrab, NULL),
+ delegate_->GetActionsAndClear());
+
+ // Notify configurator that casting session is ended.
+ configurator_.OnCastingSessionStartedOrStopped(false);
+ EXPECT_EQ(kProjectingOff, delegate_->GetActionsAndClear());
+}
+
TEST_F(OutputConfiguratorTest, SuspendAndResume) {
InitWithSingleOutput();