Commit 2c60346f authored by Takumi Fujimoto's avatar Takumi Fujimoto Committed by Commit Bot

[Mirroring Service] Show tab capture indicator icon

When mirroring a tab using the Mirroring Service, show an indicator
icon on the tabstrip.

Bug: 889942
Change-Id: I3e95484e01d84ac94d3afd400703ccc19119bb9c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1550637Reviewed-by: default avatarYuri Wiitala <miu@chromium.org>
Commit-Queue: Takumi Fujimoto <takumif@chromium.org>
Cr-Commit-Position: refs/heads/master@{#649251}
parent f24c956a
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/media/cast_remoting_connector.h" #include "chrome/browser/media/cast_remoting_connector.h"
#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
#include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
#include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/net/system_network_context_manager.h"
#include "components/mirroring/browser/single_client_video_capture_host.h" #include "components/mirroring/browser/single_client_video_capture_host.h"
#include "components/mirroring/mojom/cast_message_channel.mojom.h" #include "components/mirroring/mojom/cast_message_channel.mojom.h"
...@@ -210,6 +212,8 @@ void CastMirroringServiceHost::Start( ...@@ -210,6 +212,8 @@ void CastMirroringServiceHost::Start(
std::move(session_params), GetCaptureResolutionConstraint(), std::move(session_params), GetCaptureResolutionConstraint(),
std::move(observer), std::move(provider), std::move(outbound_channel), std::move(observer), std::move(provider), std::move(outbound_channel),
std::move(inbound_channel)); std::move(inbound_channel));
ShowCaptureIndicator();
} }
void CastMirroringServiceHost::GetVideoCaptureHost( void CastMirroringServiceHost::GetVideoCaptureHost(
...@@ -281,6 +285,20 @@ void CastMirroringServiceHost::WebContentsDestroyed() { ...@@ -281,6 +285,20 @@ void CastMirroringServiceHost::WebContentsDestroyed() {
mirroring_service_.reset(); mirroring_service_.reset();
} }
void CastMirroringServiceHost::ShowCaptureIndicator() {
if (source_media_id_.type != content::DesktopMediaID::TYPE_WEB_CONTENTS ||
!web_contents()) {
return;
}
const blink::MediaStreamDevice device(
ConvertVideoStreamType(source_media_id_.type),
source_media_id_.ToString(), /* name */ std::string());
media_stream_ui_ = MediaCaptureDevicesDispatcher::GetInstance()
->GetMediaStreamCaptureIndicator()
->RegisterMediaStream(web_contents(), {device});
media_stream_ui_->OnStarted(base::OnceClosure(), base::RepeatingClosure());
}
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
void CastMirroringServiceHost::RequestMediaAccessPermission( void CastMirroringServiceHost::RequestMediaAccessPermission(
const content::MediaStreamRequest& request, const content::MediaStreamRequest& request,
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "components/mirroring/mojom/mirroring_service_host.mojom.h" #include "components/mirroring/mojom/mirroring_service_host.mojom.h"
#include "components/mirroring/mojom/resource_provider.mojom.h" #include "components/mirroring/mojom/resource_provider.mojom.h"
#include "content/public/browser/desktop_media_id.h" #include "content/public/browser/desktop_media_id.h"
#include "content/public/browser/media_stream_request.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
#include "extensions/buildflags/buildflags.h" #include "extensions/buildflags/buildflags.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
...@@ -81,6 +82,10 @@ class CastMirroringServiceHost final : public mojom::MirroringServiceHost, ...@@ -81,6 +82,10 @@ class CastMirroringServiceHost final : public mojom::MirroringServiceHost,
// content::WebContentsObserver implementation. // content::WebContentsObserver implementation.
void WebContentsDestroyed() override; void WebContentsDestroyed() override;
// Registers the media stream to show a capture indicator icon on the
// tabstrip.
void ShowCaptureIndicator();
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
// OffscreenTab::Owner implementation. // OffscreenTab::Owner implementation.
void RequestMediaAccessPermission( void RequestMediaAccessPermission(
...@@ -107,6 +112,10 @@ class CastMirroringServiceHost final : public mojom::MirroringServiceHost, ...@@ -107,6 +112,10 @@ class CastMirroringServiceHost final : public mojom::MirroringServiceHost,
// Used to create an audio loopback stream through the Audio Service. // Used to create an audio loopback stream through the Audio Service.
std::unique_ptr<content::AudioLoopbackStreamCreator> audio_stream_creator_; std::unique_ptr<content::AudioLoopbackStreamCreator> audio_stream_creator_;
// The lifetime of the capture indicator icon on the tabstrip is tied to that
// of |media_stream_ui_|.
std::unique_ptr<content::MediaStreamUI> media_stream_ui_;
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
std::unique_ptr<OffscreenTab> offscreen_tab_; std::unique_ptr<OffscreenTab> offscreen_tab_;
#endif // BUILDFLAG(ENABLE_EXTENSIONS) #endif // BUILDFLAG(ENABLE_EXTENSIONS)
......
...@@ -7,9 +7,12 @@ ...@@ -7,9 +7,12 @@
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/browser/ui/tabs/tab_utils.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "components/mirroring/mojom/cast_message_channel.mojom.h" #include "components/mirroring/mojom/cast_message_channel.mojom.h"
#include "components/mirroring/mojom/session_observer.mojom.h" #include "components/mirroring/mojom/session_observer.mojom.h"
...@@ -259,4 +262,67 @@ IN_PROC_BROWSER_TEST_F(CastMirroringServiceHostBrowserTest, CaptureTabAudio) { ...@@ -259,4 +262,67 @@ IN_PROC_BROWSER_TEST_F(CastMirroringServiceHostBrowserTest, CaptureTabAudio) {
StopMirroring(); StopMirroring();
} }
IN_PROC_BROWSER_TEST_F(CastMirroringServiceHostBrowserTest, TabIndicator) {
ASSERT_EQ(TabAlertState::NONE,
chrome::GetTabAlertStateForContents(
browser()->tab_strip_model()->GetActiveWebContents()));
// A TabStripModelObserver that quits the MessageLoop whenever the UI's model
// is sent an event that changes the indicator status.
class IndicatorChangeObserver : public TabStripModelObserver {
public:
explicit IndicatorChangeObserver(Browser* browser)
: browser_(browser),
last_alert_state_(chrome::GetTabAlertStateForContents(
browser->tab_strip_model()->GetActiveWebContents())) {
browser_->tab_strip_model()->AddObserver(this);
}
~IndicatorChangeObserver() override {
browser_->tab_strip_model()->RemoveObserver(this);
}
TabAlertState last_alert_state() const { return last_alert_state_; }
void TabChangedAt(content::WebContents* contents,
int index,
TabChangeType change_type) override {
const TabAlertState alert_state =
chrome::GetTabAlertStateForContents(contents);
if (alert_state != last_alert_state_) {
last_alert_state_ = alert_state;
if (on_tab_changed_)
std::move(on_tab_changed_).Run();
}
}
void WaitForTabChange() {
base::RunLoop run_loop;
on_tab_changed_ = run_loop.QuitClosure();
run_loop.Run();
}
private:
Browser* const browser_;
TabAlertState last_alert_state_;
base::OnceClosure on_tab_changed_;
};
IndicatorChangeObserver observer(browser());
ASSERT_EQ(TabAlertState::NONE, observer.last_alert_state());
StartTabMirroring();
// Run the browser until the indicator turns on.
const base::TimeTicks start_time = base::TimeTicks::Now();
while (observer.last_alert_state() != TabAlertState::TAB_CAPTURING) {
if (base::TimeTicks::Now() - start_time >
TestTimeouts::action_max_timeout()) {
EXPECT_EQ(TabAlertState::TAB_CAPTURING, observer.last_alert_state());
return;
}
observer.WaitForTabChange();
}
StopMirroring();
}
} // namespace mirroring } // namespace mirroring
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