diff options
author | hshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-17 23:45:33 +0000 |
---|---|---|
committer | hshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-17 23:45:33 +0000 |
commit | 58868abfc1fe2a7f40e661daab83b0e09e560cbb (patch) | |
tree | efc399a8d3251d7d2badd5847297b027bc7067c4 | |
parent | 1ac72d4dd82a9abfa9185b18089ca9442a6c977a (diff) | |
download | chromium_src-58868abfc1fe2a7f40e661daab83b0e09e560cbb.zip chromium_src-58868abfc1fe2a7f40e661daab83b0e09e560cbb.tar.gz chromium_src-58868abfc1fe2a7f40e661daab83b0e09e560cbb.tar.bz2 |
Chrome OS: avoid suspending on lid close when casting is active.
Treat casting (both tab casting and screen casting) the same as
external display to avoid suspending on lid close.
BUG=268615
TEST=verify that device is not suspended on lid close with casting is active.
Review URL: https://codereview.chromium.org/139053003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245659 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/shell.cc | 7 | ||||
-rw-r--r-- | ash/shell.h | 3 | ||||
-rw-r--r-- | chrome/browser/media/media_capture_devices_dispatcher.cc | 47 | ||||
-rw-r--r-- | chrome/browser/media/media_capture_devices_dispatcher.h | 2 | ||||
-rw-r--r-- | chromeos/display/output_configurator.cc | 49 | ||||
-rw-r--r-- | chromeos/display/output_configurator.h | 9 | ||||
-rw-r--r-- | chromeos/display/output_configurator_unittest.cc | 41 | ||||
-rw-r--r-- | content/browser/renderer_host/media/media_stream_manager.cc | 2 | ||||
-rw-r--r-- | content/browser/renderer_host/media/mock_media_observer.h | 4 | ||||
-rw-r--r-- | content/public/browser/media_observer.h | 1 |
10 files changed, 141 insertions, 24 deletions
diff --git a/ash/shell.cc b/ash/shell.cc index 5e81698..68b3d38 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -389,6 +389,13 @@ void Shell::OnLockStateChanged(bool locked) { #endif } +void Shell::OnCastingSessionStartedOrStopped(bool started) { +#if defined(OS_CHROMEOS) && defined(USE_X11) + if (output_configurator_) + output_configurator_->OnCastingSessionStartedOrStopped(started); +#endif +} + void Shell::CreateShelf() { RootWindowControllerList controllers = GetAllRootWindowControllers(); for (RootWindowControllerList::iterator iter = controllers.begin(); diff --git a/ash/shell.h b/ash/shell.h index d2019f9..1d9dee7 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -286,6 +286,9 @@ class ASH_EXPORT Shell // unlocked. void OnLockStateChanged(bool locked); + // Called when a casting session is started or stopped. + void OnCastingSessionStartedOrStopped(bool started); + // Initializes |shelf_|. Does nothing if it's already initialized. void CreateShelf(); diff --git a/chrome/browser/media/media_capture_devices_dispatcher.cc b/chrome/browser/media/media_capture_devices_dispatcher.cc index 29c7afb..5bdc499 100644 --- a/chrome/browser/media/media_capture_devices_dispatcher.cc +++ b/chrome/browser/media/media_capture_devices_dispatcher.cc @@ -89,22 +89,48 @@ bool IsOriginWhitelistedForScreenCapture(const GURL& origin) { origin.spec() == "chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/" || origin.spec() == "chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/" || origin.spec() == "chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/" || + origin.spec() == "chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/" || origin.spec() == "chrome-extension://gfdkimpbcpahaombhbimeihdjnejgicl/") { return true; } // Check against hashed origins. + // TODO(hshi): remove this when trusted tester becomes public. const std::string origin_hash = base::SHA1HashString(origin.spec()); DCHECK_EQ(origin_hash.length(), base::kSHA1Length); const std::string hexencoded_origin_hash = base::HexEncode(origin_hash.data(), origin_hash.length()); return - hexencoded_origin_hash == "3C2705BC432E7C51CA8553FDC5BEE873FF2468EE" || - hexencoded_origin_hash == "50F02B8A668CAB274527D58356F07C2143080FCC"; + hexencoded_origin_hash == "3C2705BC432E7C51CA8553FDC5BEE873FF2468EE"; #else return false; #endif } +#if defined(OS_CHROMEOS) +// Returns true of the security origin is associated with casting. +bool IsOriginForCasting(const GURL& origin) { +#if defined(OFFICIAL_BUILD) + // Whitelisted tab casting extensions. + if (origin.spec() == "chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/" || + origin.spec() == "chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/" || + origin.spec() == "chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/" || + origin.spec() == "chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/") { + return true; + } + // Check against hashed origins. + // TODO(hshi): remove this when trusted tester becomes public. + const std::string origin_hash = base::SHA1HashString(origin.spec()); + DCHECK_EQ(origin_hash.length(), base::kSHA1Length); + const std::string hexencoded_origin_hash = + base::HexEncode(origin_hash.data(), origin_hash.length()); + return + hexencoded_origin_hash == "3C2705BC432E7C51CA8553FDC5BEE873FF2468EE"; +#else + return false; +#endif +} +#endif + // Helper to get title of the calling application shown in the screen capture // notification. base::string16 GetApplicationTitle(content::WebContents* web_contents, @@ -395,7 +421,7 @@ void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( // display the notification for stream capture. bool display_notification = !component_extension; - ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio, + ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio, display_notification, application_title); } } @@ -657,6 +683,7 @@ void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged( int render_process_id, int render_view_id, int page_request_id, + const GURL& security_origin, const content::MediaStreamDevice& device, content::MediaRequestState state) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); @@ -665,7 +692,7 @@ void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged( base::Bind( &MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread, base::Unretained(this), render_process_id, render_view_id, - page_request_id, device, state)); + page_request_id, security_origin, device, state)); } void MediaCaptureDevicesDispatcher::OnAudioStreamPlayingChanged( @@ -709,6 +736,7 @@ void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread( int render_process_id, int render_view_id, int page_request_id, + const GURL& security_origin, const content::MediaStreamDevice& device, content::MediaRequestState state) { // Track desktop capture sessions. Tracking is necessary to avoid unbalanced @@ -755,6 +783,17 @@ void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread( } } +#if defined(OS_CHROMEOS) + if (IsOriginForCasting(security_origin) && IsVideoMediaType(device.type)) { + // Notify ash that casting state has changed. + if (state == content::MEDIA_REQUEST_STATE_DONE) { + ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(true); + } else if (state == content::MEDIA_REQUEST_STATE_CLOSING) { + ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(false); + } + } +#endif + FOR_EACH_OBSERVER(Observer, observers_, OnRequestUpdate(render_process_id, render_view_id, diff --git a/chrome/browser/media/media_capture_devices_dispatcher.h b/chrome/browser/media/media_capture_devices_dispatcher.h index 2b65ab2..b86d525 100644 --- a/chrome/browser/media/media_capture_devices_dispatcher.h +++ b/chrome/browser/media/media_capture_devices_dispatcher.h @@ -121,6 +121,7 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver, int render_process_id, int render_view_id, int page_request_id, + const GURL& security_origin, const content::MediaStreamDevice& device, content::MediaRequestState state) OVERRIDE; virtual void OnAudioStreamPlayingChanged( @@ -200,6 +201,7 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver, int render_process_id, int render_view_id, int page_request_id, + const GURL& security_origin, const content::MediaStreamDevice& device, content::MediaRequestState state); void OnCreatingAudioStreamOnUIThread(int render_process_id, 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(); diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc index 8a865fc..4b1ea25 100644 --- a/content/browser/renderer_host/media/media_stream_manager.cc +++ b/content/browser/renderer_host/media/media_stream_manager.cc @@ -217,7 +217,7 @@ class MediaStreamManager::DeviceRequest { media_observer->OnMediaRequestStateChanged( ui_request_->render_process_id, ui_request_->render_view_id, - ui_request_->page_request_id, + ui_request_->page_request_id, ui_request_->security_origin, MediaStreamDevice(stream_type, device_id, device_id), new_state); } diff --git a/content/browser/renderer_host/media/mock_media_observer.h b/content/browser/renderer_host/media/mock_media_observer.h index c3543f3..e59352f 100644 --- a/content/browser/renderer_host/media/mock_media_observer.h +++ b/content/browser/renderer_host/media/mock_media_observer.h @@ -24,9 +24,9 @@ class MockMediaObserver : public MediaObserver { void(const MediaStreamDevices& devices)); MOCK_METHOD1(OnVideoCaptureDevicesChanged, void(const MediaStreamDevices& devices)); - MOCK_METHOD5(OnMediaRequestStateChanged, + MOCK_METHOD6(OnMediaRequestStateChanged, void(int render_process_id, int render_view_id, - int page_request_id, + int page_request_id, const GURL& security_origin, const MediaStreamDevice& device, const MediaRequestState state)); MOCK_METHOD6(OnAudioStreamPlayingChanged, diff --git a/content/public/browser/media_observer.h b/content/public/browser/media_observer.h index 1c264aa..c5185ba 100644 --- a/content/public/browser/media_observer.h +++ b/content/public/browser/media_observer.h @@ -27,6 +27,7 @@ class MediaObserver { int render_process_id, int render_view_id, int page_request_id, + const GURL& security_origin, const MediaStreamDevice& device, MediaRequestState state) = 0; |