0

[MSC] Added screen capture usage indicator view.

This CL adds a new view to indicate the usage of the new
getDisplayMediaSet API (indicating that several screens are captured).

Bug: 1300883
Change-Id: Ice0fe91db9a1bdb41a8f3744db667ebc7a73bbf2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3668545
Reviewed-by: Markus Handell <handellm@google.com>
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Simon Hangl <simonha@google.com>
Reviewed-by: Ahmed Fakhry <afakhry@chromium.org>
Reviewed-by: Elad Alon <eladalon@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1036598}
This commit is contained in:
Simon Hangl
2022-08-18 14:26:56 +00:00
committed by Chromium LUCI CQ
parent 26b7d6e73c
commit add76fefd3
24 changed files with 466 additions and 2 deletions

@ -755,6 +755,8 @@ component("ash") {
"metrics/ui_throughput_recorder.h",
"metrics/user_metrics_recorder.cc",
"metrics/user_metrics_recorder.h",
"multi_capture/multi_capture_service_client.cc",
"multi_capture/multi_capture_service_client.h",
"multi_device_setup/multi_device_notification_presenter.cc",
"multi_device_setup/multi_device_notification_presenter.h",
"multi_profile_uma.cc",
@ -1757,6 +1759,8 @@ component("ash") {
"system/unified/page_indicator_view.h",
"system/unified/quiet_mode_feature_pod_controller.cc",
"system/unified/quiet_mode_feature_pod_controller.h",
"system/unified/screen_capture_tray_item_view.cc",
"system/unified/screen_capture_tray_item_view.h",
"system/unified/top_shortcuts_view.cc",
"system/unified/top_shortcuts_view.h",
"system/unified/unified_notifier_settings_controller.cc",

@ -37,6 +37,7 @@ include_rules = [
"+services/device/public",
"+services/data_decoder/public",
"+services/media_session/public",
"+services/video_capture/public/mojom",
"+services/network/public",
"+services/network/test",
"+services/preferences/public",

@ -3897,6 +3897,11 @@ Connect your device to power.
Here are some things you can try to get started.
</message>
<!-- For ScreenCaptureTrayItemView -->
<message name="IDS_ASH_ADMIN_SCREEN_CAPTURE" desc="Tooltip message shown at the systray screen capture indicator when an administrator is capturing the screens.">
Your system administrator is monitoring your screens
</message>
<!-- For CameraMicTrayItemView -->
<message name="IDS_ASH_CAMERA_MIC_VM_USING_CAMERA" desc="Tooltip message shown at the systray camera indicator when a VM is using the camera">
An application is using your camera

@ -0,0 +1 @@
c70af15aa5315a4a10452f7abf7fbedb9bf1fd92

@ -0,0 +1,40 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/multi_capture/multi_capture_service_client.h"
#include "base/logging.h"
namespace ash {
MultiCaptureServiceClient::MultiCaptureServiceClient(
mojo::PendingRemote<video_capture::mojom::MultiCaptureService>
multi_capture_service)
: multi_capture_service_(std::move(multi_capture_service)) {
multi_capture_service_->AddObserver(
multi_capture_service_observer_receiver_.BindNewPipeAndPassRemote());
}
MultiCaptureServiceClient::~MultiCaptureServiceClient() = default;
void MultiCaptureServiceClient::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void MultiCaptureServiceClient::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
void MultiCaptureServiceClient::MultiCaptureStarted(const std::string& label,
const url::Origin& origin) {
for (Observer& observer : observers_)
observer.MultiCaptureStarted(label, origin);
}
void MultiCaptureServiceClient::MultiCaptureStopped(const std::string& label) {
for (Observer& observer : observers_)
observer.MultiCaptureStopped(label);
}
} // namespace ash

@ -0,0 +1,67 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_MULTI_CAPTURE_MULTI_CAPTURE_SERVICE_CLIENT_H_
#define ASH_MULTI_CAPTURE_MULTI_CAPTURE_SERVICE_CLIENT_H_
#include <string>
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/video_capture/public/mojom/multi_capture_service.mojom.h"
#include "url/origin.h"
namespace ash {
// Client of the MultiCaptureService mojo interface. Receives events about
// multi captures being started / stopped and forwards it to ash clients to
// show usage indicators.
class MultiCaptureServiceClient
: public video_capture::mojom::MultiCaptureServiceClient {
public:
class Observer : public base::CheckedObserver {
public:
// Event to inform about a started multi capture. The label is a unique
// identifier that can be used to connect started / stopped events.
// The origin is the capturer's origin.
// TODO(crbug.com/1325750): Consider transferred tracks by either adding
// a MultiCaptureTransferred event or by making sure the label remains
// constant throughout the lifetime of the capture.
virtual void MultiCaptureStarted(const std::string& label,
const url::Origin& origin) = 0;
virtual void MultiCaptureStopped(const std::string& label) = 0;
protected:
~Observer() override = default;
};
explicit MultiCaptureServiceClient(
mojo::PendingRemote<video_capture::mojom::MultiCaptureService>
multi_capture_service);
~MultiCaptureServiceClient() override;
MultiCaptureServiceClient(const MultiCaptureServiceClient&) = delete;
MultiCaptureServiceClient& operator=(const MultiCaptureServiceClient&) =
delete;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// video_capture::mojom::MultiCaptureService:
void MultiCaptureStarted(const std::string& label,
const url::Origin& origin) override;
void MultiCaptureStopped(const std::string& label) override;
private:
mojo::Remote<video_capture::mojom::MultiCaptureService>
multi_capture_service_;
mojo::Receiver<video_capture::mojom::MultiCaptureServiceClient>
multi_capture_service_observer_receiver_{this};
base::ObserverList<Observer> observers_;
};
} // namespace ash
#endif // ASH_VIDEO_CAPTURE_MULTI_CAPTURE_SERVICE_CLIENT_H_

@ -83,6 +83,7 @@
#include "ash/metrics/feature_discovery_duration_reporter_impl.h"
#include "ash/metrics/login_unlock_throughput_recorder.h"
#include "ash/metrics/user_metrics_recorder.h"
#include "ash/multi_capture/multi_capture_service_client.h"
#include "ash/multi_device_setup/multi_device_notification_presenter.h"
#include "ash/policy/policy_recommendation_restorer.h"
#include "ash/projector/projector_controller_impl.h"
@ -211,6 +212,7 @@
#include "components/viz/host/host_frame_sink_manager.h"
#include "dbus/bus.h"
#include "media/capture/video/chromeos/video_capture_features_chromeos.h"
#include "services/video_capture/public/mojom/multi_capture_service.mojom.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
#include "ui/aura/layout_manager.h"
@ -978,6 +980,8 @@ Shell::~Shell() {
shell_delegate_.reset();
multi_capture_service_client_.reset();
UsbguardClient::Shutdown();
// Must be shut down after detachable_base_handler_.
@ -1311,6 +1315,13 @@ void Shell::Init(
std::make_unique<AmbientController>(std::move(fingerprint));
}
mojo::PendingRemote<video_capture::mojom::MultiCaptureService>
multi_capture_service;
shell_delegate_->BindMultiCaptureService(
multi_capture_service.InitWithNewPipeAndPassReceiver());
multi_capture_service_client_ = std::make_unique<MultiCaptureServiceClient>(
std::move(multi_capture_service));
// |tablet_mode_controller_| |mru_window_tracker_|, and
// |assistant_controller_| are put before |app_list_controller_| as they are
// used in its constructor.

@ -223,6 +223,7 @@ class WindowCycleController;
class WindowPositioner;
class WindowTreeHostManager;
class ArcInputMethodBoundsTracker;
class MultiCaptureServiceClient;
enum class LoginStatus;
@ -560,6 +561,9 @@ class ASH_EXPORT Shell : public SessionObserver,
quick_pair::Mediator* quick_pair_mediator() {
return quick_pair_mediator_.get();
}
MultiCaptureServiceClient* multi_capture_service_client() {
return multi_capture_service_client_.get();
}
ResizeShadowController* resize_shadow_controller() {
return resize_shadow_controller_.get();
}
@ -1017,6 +1021,8 @@ class ASH_EXPORT Shell : public SessionObserver,
std::unique_ptr<OcclusionTrackerPauser> occlusion_tracker_pauser_;
std::unique_ptr<MultiCaptureServiceClient> multi_capture_service_client_;
std::unique_ptr<quick_pair::Mediator> quick_pair_mediator_;
base::ObserverList<ShellObserver>::Unchecked shell_observers_;

@ -18,6 +18,7 @@
#include "services/device/public/mojom/fingerprint.mojom-forward.h"
#include "services/media_session/public/cpp/media_session_service.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/video_capture/public/mojom/multi_capture_service.mojom-forward.h"
#include "ui/gfx/native_widget_types.h"
#include "url/gurl.h"
@ -108,6 +109,12 @@ class ASH_EXPORT ShellDelegate {
mojo::PendingReceiver<multidevice_setup::mojom::MultiDeviceSetup>
receiver) = 0;
// Binds a MultiCaptureService receiver to start observing
// MultiCaptureStarted() and MultiCaptureStopped() events.
virtual void BindMultiCaptureService(
mojo::PendingReceiver<video_capture::mojom::MultiCaptureService>
receiver) = 0;
// Returns an interface to the Media Session service, or null if not
// available.
virtual media_session::MediaSessionService* GetMediaSessionService();

@ -0,0 +1,67 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/unified/screen_capture_tray_item_view.h"
#include "ash/multi_capture/multi_capture_service_client.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_provider.h"
#include "ash/system/tray/tray_constants.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/views/controls/image_view.h"
namespace ash {
ScreenCaptureTrayItemView::ScreenCaptureTrayItemView(Shelf* shelf)
: TrayItemView(shelf) {
CreateImageView();
const gfx::VectorIcon* icon = &kSystemTrayRecordingIcon;
image_view()->SetImage(gfx::CreateVectorIcon(gfx::IconDescription(
*icon, kUnifiedTrayIconSize,
AshColorProvider::Get()->GetContentLayerColor(
AshColorProvider::ContentLayerType::kIconColorAlert))));
Shell::Get()->multi_capture_service_client()->AddObserver(this);
Refresh();
}
ScreenCaptureTrayItemView::~ScreenCaptureTrayItemView() {
Shell::Get()->multi_capture_service_client()->RemoveObserver(this);
}
const char* ScreenCaptureTrayItemView::GetClassName() const {
return "ScreenCaptureTrayItemView";
}
views::View* ScreenCaptureTrayItemView::GetTooltipHandlerForPoint(
const gfx::Point& point) {
return HitTestPoint(point) ? this : nullptr;
}
std::u16string ScreenCaptureTrayItemView::GetTooltipText(
const gfx::Point& point) const {
return l10n_util::GetStringUTF16(IDS_ASH_ADMIN_SCREEN_CAPTURE);
}
void ScreenCaptureTrayItemView::Refresh() {
SetVisible(!request_ids_.empty());
}
void ScreenCaptureTrayItemView::MultiCaptureStarted(const std::string& label,
const url::Origin& origin) {
request_ids_.insert(label);
Refresh();
}
void ScreenCaptureTrayItemView::MultiCaptureStopped(const std::string& label) {
request_ids_.erase(label);
Refresh();
}
} // namespace ash

@ -0,0 +1,56 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SYSTEM_UNIFIED_SCREEN_CAPTURE_TRAY_ITEM_VIEW_H_
#define ASH_SYSTEM_UNIFIED_SCREEN_CAPTURE_TRAY_ITEM_VIEW_H_
#include <string>
#include "ash/multi_capture/multi_capture_service_client.h"
#include "ash/system/tray/tray_item_view.h"
#include "base/containers/fixed_flat_set.h"
#include "base/memory/weak_ptr.h"
namespace url {
class Origin;
}
namespace ash {
// An indicator shown in UnifiedSystemTray when a web application is using
// screen capturing.
class ASH_EXPORT ScreenCaptureTrayItemView
: public TrayItemView,
public MultiCaptureServiceClient::Observer {
public:
explicit ScreenCaptureTrayItemView(Shelf* shelf);
ScreenCaptureTrayItemView(const ScreenCaptureTrayItemView&) = delete;
ScreenCaptureTrayItemView& operator=(const ScreenCaptureTrayItemView&) =
delete;
~ScreenCaptureTrayItemView() override;
// views::View:
const char* GetClassName() const override;
views::View* GetTooltipHandlerForPoint(const gfx::Point& point) override;
std::u16string GetTooltipText(const gfx::Point& point) const override;
// TrayItemView:
void HandleLocaleChange() override {}
// MultiCaptureServiceClient::Observer:
void MultiCaptureStarted(const std::string& label,
const url::Origin& origin) override;
void MultiCaptureStopped(const std::string& label) override;
private:
void Refresh();
base::flat_set<std::string> request_ids_;
base::WeakPtrFactory<ScreenCaptureTrayItemView> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_SYSTEM_UNIFIED_SCREEN_CAPTURE_TRAY_ITEM_VIEW_H_

@ -43,6 +43,7 @@
#include "ash/system/unified/managed_device_tray_item_view.h"
#include "ash/system/unified/notification_counter_view.h"
#include "ash/system/unified/notification_icons_controller.h"
#include "ash/system/unified/screen_capture_tray_item_view.h"
#include "ash/system/unified/unified_slider_bubble_controller.h"
#include "ash/system/unified/unified_system_tray_bubble.h"
#include "ash/system/unified/unified_system_tray_model.h"
@ -196,12 +197,12 @@ UnifiedSystemTray::UnifiedSystemTray(Shelf* shelf)
time_view_(new TimeTrayItemView(shelf, TimeView::Type::kTime)),
privacy_indicators_view_(features::IsPrivacyIndicatorsEnabled()
? new PrivacyIndicatorsTrayItemView(shelf)
: nullptr) {
: nullptr),
screen_capture_view_(new ScreenCaptureTrayItemView(shelf)) {
if (media::ShouldEnableAutoFraming()) {
autozoom_toast_controller_ = std::make_unique<AutozoomToastController>(
this, std::make_unique<AutozoomToastController::Delegate>());
}
tray_container()->SetMargin(
kUnifiedTrayContentPadding -
ShelfConfig::Get()->status_area_hit_region_padding(),
@ -216,6 +217,8 @@ UnifiedSystemTray::UnifiedSystemTray(Shelf* shelf)
AddObservedTrayItem(tray_item);
}
AddTrayItemToContainer(screen_capture_view_);
tray_items_.push_back(
notification_icons_controller_->notification_counter_view());
AddObservedTrayItem(

@ -41,6 +41,7 @@ class NotificationGroupingController;
class NotificationIconsController;
class PrivacyIndicatorsTrayItemView;
class PrivacyScreenToastController;
class ScreenCaptureTrayItemView;
class SnoopingProtectionView;
class TimeTrayItemView;
class TrayItemView;
@ -303,6 +304,7 @@ class ASH_EXPORT UnifiedSystemTray
CameraMicTrayItemView* const mic_view_;
TimeTrayItemView* const time_view_;
PrivacyIndicatorsTrayItemView* const privacy_indicators_view_;
ScreenCaptureTrayItemView* const screen_capture_view_;
NetworkTrayView* network_tray_view_ = nullptr;
ChannelIndicatorView* channel_indicator_view_ = nullptr;

@ -87,6 +87,10 @@ void TestShellDelegate::BindMultiDeviceSetup(
multidevice_setup_binder_.Run(std::move(receiver));
}
void TestShellDelegate::BindMultiCaptureService(
mojo::PendingReceiver<video_capture::mojom::MultiCaptureService> receiver) {
}
void TestShellDelegate::SetCanGoBack(bool can_go_back) {
can_go_back_ = can_go_back;
}

@ -56,6 +56,9 @@ class TestShellDelegate : public ShellDelegate {
void BindMultiDeviceSetup(
mojo::PendingReceiver<multidevice_setup::mojom::MultiDeviceSetup>
receiver) override;
void BindMultiCaptureService(
mojo::PendingReceiver<video_capture::mojom::MultiCaptureService> receiver)
override;
bool IsSessionRestoreInProgress() const override;
void SetUpEnvironmentForLockedFullscreen(bool locked) override {}
const GURL& GetLastCommittedURLForWindowIfAny(aura::Window* window) override;

@ -21,6 +21,7 @@ specific_include_rules = {
],
"chrome_shell_delegate\.cc": [
"+cc/input/touch_action.h",
"+content/public/browser/chromeos/multi_capture_service.h",
],
"chrome_shelf_controller_unittest\.cc": [
"+components/viz/test/test_gpu_service_holder.h",

@ -58,6 +58,7 @@
#include "components/user_manager/user_manager.h"
#include "components/version_info/channel.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/chromeos/multi_capture_service.h"
#include "content/public/browser/device_service.h"
#include "content/public/browser/media_session_service.h"
#include "content/public/browser/render_widget_host.h"
@ -219,6 +220,12 @@ void ChromeShellDelegate::BindMultiDeviceSetup(
service->BindMultiDeviceSetup(std::move(receiver));
}
void ChromeShellDelegate::BindMultiCaptureService(
mojo::PendingReceiver<video_capture::mojom::MultiCaptureService> receiver) {
content::GetMultiCaptureService().BindMultiCaptureService(
std::move(receiver));
}
media_session::MediaSessionService*
ChromeShellDelegate::GetMediaSessionService() {
return &content::GetMediaSessionService();

@ -50,6 +50,9 @@ class ChromeShellDelegate : public ash::ShellDelegate {
void BindMultiDeviceSetup(
mojo::PendingReceiver<ash::multidevice_setup::mojom::MultiDeviceSetup>
receiver) override;
void BindMultiCaptureService(
mojo::PendingReceiver<video_capture::mojom::MultiCaptureService> receiver)
override;
media_session::MediaSessionService* GetMediaSessionService() override;
bool IsSessionRestoreInProgress() const override;
void SetUpEnvironmentForLockedFullscreen(bool locked) override;

@ -92,6 +92,7 @@
#include "chromeos/ash/components/audio/cras_audio_handler.h"
#include "content/browser/gpu/chromeos/video_capture_dependencies.h"
#include "content/browser/gpu/gpu_memory_buffer_manager_singleton.h"
#include "content/public/browser/chromeos/multi_capture_service.h"
#include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"
#include "media/capture/video/chromeos/public/cros_features.h"
#include "media/capture/video/chromeos/video_capture_device_factory_chromeos.h"
@ -808,6 +809,10 @@ class MediaStreamManager::DeviceRequest {
state_[static_cast<int>(stream_type)] = new_state;
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
NotifyMultiCaptureStateChanged(new_state);
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
MediaObserver* media_observer =
GetContentClient()->browser()->GetMediaObserver();
if (!media_observer)
@ -919,6 +924,8 @@ class MediaStreamManager::DeviceRequest {
blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET;
}
void SetLabel(const std::string& label) { label_ = label; }
// The render process id that requested this stream to be generated and that
// will receive a handle to the MediaStream. This may be different from
// MediaStreamRequest::render_process_id which in the tab capture case
@ -991,6 +998,43 @@ class MediaStreamManager::DeviceRequest {
PermissionController::SubscriptionId video_subscription_id;
private:
#if BUILDFLAG(IS_CHROMEOS_ASH)
void NotifyMultiCaptureStateChanged(MediaRequestState new_state) {
if (!IsGetDisplayMediaSet())
return;
switch (new_state) {
case MediaRequestState::MEDIA_REQUEST_STATE_OPENING:
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(
[](const std::string& label, const url::Origin& origin) {
content::GetMultiCaptureService().NotifyMultiCaptureStarted(
label, origin);
},
label_, salt_and_origin.origin));
break;
case MediaRequestState::MEDIA_REQUEST_STATE_CLOSING:
case MediaRequestState::MEDIA_REQUEST_STATE_ERROR:
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(
[](const std::string& label) {
content::GetMultiCaptureService().NotifyMultiCaptureStopped(
label);
},
label_));
break;
case MediaRequestState::MEDIA_REQUEST_STATE_NOT_REQUESTED:
case MediaRequestState::MEDIA_REQUEST_STATE_REQUESTED:
case MediaRequestState::MEDIA_REQUEST_STATE_PENDING_APPROVAL:
case MediaRequestState::MEDIA_REQUEST_STATE_DONE:
// Nothing to do as usage indicators only need to shown while the
// capture is active.
break;
}
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
// Mark true if the MediaStreamDevice of |MediaStreamType| type should be
// stopped but can't at the moment because of ongoing transfers.
std::vector<bool> should_stop_in_future_;
@ -1007,6 +1051,7 @@ class MediaStreamManager::DeviceRequest {
MediaStreamType video_type_;
int target_process_id_;
int target_frame_id_;
std::string label_;
};
// static
@ -1861,6 +1906,7 @@ std::string MediaStreamManager::AddRequest(
SendLogMessage(
base::StringPrintf("AddRequest([requester_id=%d]) => (label=%s)",
request->requester_id, unique_label.c_str()));
request->SetLabel(unique_label);
requests_.push_back(std::make_pair(unique_label, std::move(request)));
return unique_label;

@ -623,6 +623,8 @@ source_set("browser_sources") {
if (is_chromeos_ash) {
sources += [
"chromeos/delegate_to_browser_gpu_service_accelerator_factory.h",
"chromeos/multi_capture_service.cc",
"chromeos/multi_capture_service.h",
"tts_controller_delegate.cc",
"tts_controller_delegate.h",
]

@ -0,0 +1,51 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/public/browser/chromeos/multi_capture_service.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "content/public/browser/browser_thread.h"
namespace content {
MultiCaptureService::MultiCaptureService() = default;
MultiCaptureService::~MultiCaptureService() = default;
void MultiCaptureService::BindMultiCaptureService(
mojo::PendingReceiver<video_capture::mojom::MultiCaptureService> receiver) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
multi_capture_service_receiver_set_.Add(this, std::move(receiver));
}
void MultiCaptureService::AddObserver(
mojo::PendingRemote<video_capture::mojom::MultiCaptureServiceClient>
observer) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
observers_.Add(std::move(observer));
}
void MultiCaptureService::NotifyMultiCaptureStarted(const std::string& label,
const url::Origin& origin) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
for (auto& observer : observers_) {
observer->MultiCaptureStarted(label, origin);
}
}
void MultiCaptureService::NotifyMultiCaptureStopped(const std::string& label) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
for (auto& observer : observers_) {
observer->MultiCaptureStopped(label);
}
}
MultiCaptureService& GetMultiCaptureService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
static base::NoDestructor<MultiCaptureService> multi_capture_service;
return *multi_capture_service;
}
} // namespace content

@ -0,0 +1,46 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_PUBLIC_BROWSER_CHROMEOS_MULTI_CAPTURE_SERVICE_H_
#define CONTENT_PUBLIC_BROWSER_CHROMEOS_MULTI_CAPTURE_SERVICE_H_
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "services/video_capture/public/mojom/multi_capture_service.mojom.h"
namespace content {
class CONTENT_EXPORT MultiCaptureService
: public video_capture::mojom::MultiCaptureService {
public:
MultiCaptureService();
MultiCaptureService(const MultiCaptureService&) = delete;
MultiCaptureService& operator=(const MultiCaptureService&) = delete;
~MultiCaptureService() override;
void BindMultiCaptureService(
mojo::PendingReceiver<video_capture::mojom::MultiCaptureService>
receiver);
// video_capture::mojom::MultiCaptureService:
void AddObserver(
mojo::PendingRemote<video_capture::mojom::MultiCaptureServiceClient>
observer) override;
void NotifyMultiCaptureStarted(const std::string& label,
const url::Origin& origin);
void NotifyMultiCaptureStopped(const std::string& label);
private:
mojo::ReceiverSet<video_capture::mojom::MultiCaptureService>
multi_capture_service_receiver_set_;
mojo::RemoteSet<video_capture::mojom::MultiCaptureServiceClient> observers_;
};
CONTENT_EXPORT MultiCaptureService& GetMultiCaptureService();
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_CHROMEOS_MULTI_CAPTURE_SERVICE_H_

@ -10,6 +10,7 @@ mojom("mojom") {
"device.mojom",
"device_factory.mojom",
"devices_changed_observer.mojom",
"multi_capture_service.mojom",
"producer.mojom",
"testing_controls.mojom",
"video_capture_service.mojom",

@ -0,0 +1,30 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module video_capture.mojom;
import "url/mojom/origin.mojom";
// The MultiCaptureService is used as a communication channel between the
// browser process and ash to inform about new / ending
// multi capture events so that appropriate usage indicators can
// be shown to the users.
[EnableIf=is_chromeos_ash]
interface MultiCaptureService {
// Adds an observer for multi capture events.
AddObserver(pending_remote<MultiCaptureServiceClient> observer);
};
// The MultiCaptureServiceClient is used to receive new / ending multi
// capture events in ash.
[EnableIf=is_chromeos_ash]
interface MultiCaptureServiceClient {
// Called when a new multi capture is started. This event provides a unique
// label and the origin that triggered the capture.
MultiCaptureStarted(string label, url.mojom.Origin origin);
// Callend when an existing multi capture is stopped. This event provides a
// unique label. A multi capture is considered to be stopped when all used
// devices are closed.
MultiCaptureStopped(string label);
};