0

PrivacyIndicators: Refactor screen security observer and controller

ScreenSecurityController is very old code, which now uses the terms
screen capture and screen sharing not correctly. Screen capture in this
class refers to screen is being accessed (i.e. Google meet sharing your
screen), and screen sharing refers to remoting screen share (your screen
is being remotedly shared with Chrome Remote Desktop). This CL changes
the name for the observers used in this class to avoid the current
confusion, in addition to these clean up:
- Merge all observers into one ScreenSecurityObserver
- Simplify OnRemotingScreenShareStart by removing unused parameter
- Remove unnecessary strings used in ScreenSecurityController

Fixed: b:269653827
Change-Id: I2626075b3012c267f87476462eeac2300d28dc4f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4289287
Commit-Queue: Andre Le <leandre@chromium.org>
Reviewed-by: Ahmed Fakhry <afakhry@chromium.org>
Reviewed-by: Joe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1110690}
This commit is contained in:
Andre Le
2023-02-28 00:52:00 +00:00
committed by Chromium LUCI CQ
parent 46529e66ad
commit a4e5cf0ec3
19 changed files with 254 additions and 314 deletions

@ -1737,10 +1737,9 @@ component("ash") {
"system/privacy/privacy_indicators_controller.h",
"system/privacy/privacy_indicators_tray_item_view.cc",
"system/privacy/privacy_indicators_tray_item_view.h",
"system/privacy/screen_capture_observer.h",
"system/privacy/screen_security_controller.cc",
"system/privacy/screen_security_controller.h",
"system/privacy/screen_share_observer.h",
"system/privacy/screen_security_observer.h",
"system/privacy/screen_switch_check_controller.cc",
"system/privacy/screen_switch_check_controller.h",
"system/privacy_hub/camera_privacy_switch_controller.cc",

@ -2600,13 +2600,19 @@ Connect your device to power.
Continue
</message>
<!-- Status tray screen capture strings. -->
<message name="IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_STOP" desc="label used for screen capture stop button">
<!-- Status tray screen security strings. -->
<message name="IDS_ASH_STATUS_TRAY_SCREEN_ACCESS_STOP" desc="label used for screen access or screen sharing stop button">
Stop
</message>
<message name="IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_CHANGE_SOURCE" desc="label used for screen capture change source button">
Change source
</message>
<message name="IDS_ASH_STATUS_TRAY_SCREEN_SHARE_TITLE" desc="The title for screen sharing notification">
You're sharing your screen
</message>
<message name="IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED" desc="label for screen sharing notification">
Sharing control of your screen via Remote Assistance.
</message>
<!-- Status tray media recording state strings. -->
<message name="IDS_ASH_STATUS_TRAY_MEDIA_RECORDING_AUDIO" desc="label used to indicate that the microphone is used by a background user">
@ -2619,20 +2625,6 @@ Connect your device to power.
Camera and microphone are in use.
</message>
<!-- Status tray screen share strings. -->
<message name="IDS_ASH_STATUS_TRAY_SCREEN_SHARE_TITLE" desc="The title for screen sharing notification">
You're sharing your screen
</message>
<message name="IDS_ASH_STATUS_TRAY_SCREEN_SHARE_STOP" desc="label used for screen sharing stop button">
Stop
</message>
<message name="IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED" desc="label for screen sharing notification">
Sharing control of your screen via Remote Assistance.
</message>
<message name="IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED_NAME" desc="label for screen sharing notification with name">
Sharing control of your screen with <ph name="HELPER_NAME">$1<ex>Walder Frey</ex></ph> via Remote Assistance.
</message>
<!-- Status tray audio strings. -->
<message name="IDS_ASH_STATUS_TRAY_AUDIO_FRONT_MIC" desc="label used for front microphone">
Front microphone

@ -0,0 +1 @@
4c79ebaed80c00cd17b26da8ceddf718c924665a

@ -655,7 +655,7 @@ class CanSwitchUserTest : public AshTestBase {
// Accessing the capture session functionality.
// Simulates a screen capture session start.
void StartCaptureSession() {
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStart(
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStart(
base::BindRepeating(&CanSwitchUserTest::StopCaptureCallback,
base::Unretained(this)),
base::RepeatingClosure(), std::u16string());
@ -663,7 +663,7 @@ class CanSwitchUserTest : public AshTestBase {
// The callback which gets called when the screen capture gets stopped.
void StopCaptureSession() {
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStop();
}
// Simulates a screen capture session stop.
@ -672,15 +672,14 @@ class CanSwitchUserTest : public AshTestBase {
// Accessing the share session functionality.
// Simulate a Screen share session start.
void StartShareSession() {
Shell::Get()->system_tray_notifier()->NotifyScreenShareStart(
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStart(
base::BindRepeating(&CanSwitchUserTest::StopShareCallback,
base::Unretained(this)),
std::u16string());
base::Unretained(this)));
}
// Simulates a screen share session stop.
void StopShareSession() {
Shell::Get()->system_tray_notifier()->NotifyScreenShareStop();
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStop();
}
// The callback which gets called when the screen share gets stopped.

@ -1,33 +0,0 @@
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SYSTEM_PRIVACY_SCREEN_CAPTURE_OBSERVER_H_
#define ASH_SYSTEM_PRIVACY_SCREEN_CAPTURE_OBSERVER_H_
#include <string>
#include "base/functional/callback.h"
namespace ash {
class ScreenCaptureObserver {
public:
// Called when screen capture is started.
// |stop_callback| is a callback to stop the stream.
// |source_callback| is a callback to change the desktop capture source.
virtual void OnScreenCaptureStart(
base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& screen_capture_status) = 0;
// Called when screen capture is stopped.
virtual void OnScreenCaptureStop() = 0;
protected:
virtual ~ScreenCaptureObserver() {}
};
} // namespace ash
#endif // ASH_SYSTEM_PRIVACY_SCREEN_CAPTURE_OBSERVER_H_

@ -28,58 +28,59 @@ namespace ash {
// It is possible that we are capturing and sharing screen at the same time, so
// we cannot share the notification IDs for capturing and sharing.
const char kScreenCaptureNotificationId[] = "chrome://screen/capture";
const char kScreenShareNotificationId[] = "chrome://screen/share";
const char kNotifierScreenCapture[] = "ash.screen-capture";
const char kNotifierScreenShare[] = "ash.screen-share";
const char kScreenAccessNotificationId[] = "chrome://screen/access";
const char kRemotingScreenShareNotificationId[] =
"chrome://screen/remoting-share";
const char kNotifierScreenAccess[] = "ash.screen-access";
const char kNotifierRemotingScreenShare[] = "ash.remoting-screen-share";
ScreenSecurityController::ScreenSecurityController() {
Shell::Get()->AddShellObserver(this);
Shell::Get()->system_tray_notifier()->AddScreenCaptureObserver(this);
Shell::Get()->system_tray_notifier()->AddScreenShareObserver(this);
Shell::Get()->system_tray_notifier()->AddScreenSecurityObserver(this);
}
ScreenSecurityController::~ScreenSecurityController() {
Shell::Get()->system_tray_notifier()->RemoveScreenShareObserver(this);
Shell::Get()->system_tray_notifier()->RemoveScreenCaptureObserver(this);
Shell::Get()->system_tray_notifier()->RemoveScreenSecurityObserver(this);
Shell::Get()->RemoveShellObserver(this);
}
void ScreenSecurityController::CreateNotification(const std::u16string& message,
bool is_capture) {
void ScreenSecurityController::CreateNotification(
const std::u16string& message,
bool is_screen_access_notification) {
if (features::IsVideoConferenceEnabled()) {
// Don't send screen share notifications, because the VideoConferenceTray
// serves as the notifier for screen share. As for screen capture, continue
// to show these notifications for now, although they may end up in the
// `VideoConferenceTray` as well. See b/269486186 for details.
DCHECK(is_capture);
DCHECK(is_screen_access_notification);
}
message_center::RichNotificationData data;
data.buttons.push_back(message_center::ButtonInfo(l10n_util::GetStringUTF16(
is_capture ? IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_STOP
: IDS_ASH_STATUS_TRAY_SCREEN_SHARE_STOP)));
data.buttons.emplace_back(
l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_ACCESS_STOP));
// Only add "Change source" button when there is one session, since there
// isn't a good UI to distinguish between the different sessions.
if (is_capture && change_source_callback_ &&
capture_stop_callbacks_.size() == 1) {
data.buttons.push_back(message_center::ButtonInfo(l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_CHANGE_SOURCE)));
if (is_screen_access_notification && change_source_callback_ &&
screen_access_stop_callbacks_.size() == 1) {
data.buttons.emplace_back(l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_CHANGE_SOURCE));
}
auto delegate =
base::MakeRefCounted<message_center::HandleNotificationClickDelegate>(
base::BindRepeating(
[](base::WeakPtr<ScreenSecurityController> controller,
bool is_capture, absl::optional<int> button_index) {
bool is_screen_access_notification,
absl::optional<int> button_index) {
if (!button_index)
return;
if (*button_index == 0) {
controller->StopAllSessions(is_capture);
controller->StopAllSessions(
/*is_screen_access=*/is_screen_access_notification);
} else if (*button_index == 1) {
controller->ChangeSource();
if (is_capture) {
if (is_screen_access_notification) {
base::RecordAction(base::UserMetricsAction(
"StatusArea_ScreenCapture_Change_Source"));
}
@ -87,18 +88,20 @@ void ScreenSecurityController::CreateNotification(const std::u16string& message,
NOTREACHED();
}
},
weak_ptr_factory_.GetWeakPtr(), is_capture));
weak_ptr_factory_.GetWeakPtr(), is_screen_access_notification));
// If the feature is enabled, the notification should have the style of
// privacy indicators notification.
auto* notifier_id =
features::IsPrivacyIndicatorsEnabled()
? kPrivacyIndicatorsNotifierId
: (is_capture ? kNotifierScreenCapture : kNotifierScreenShare);
: (is_screen_access_notification ? kNotifierScreenAccess
: kNotifierRemotingScreenShare);
std::unique_ptr<Notification> notification = CreateSystemNotificationPtr(
message_center::NOTIFICATION_TYPE_SIMPLE,
is_capture ? kScreenCaptureNotificationId : kScreenShareNotificationId,
is_screen_access_notification ? kScreenAccessNotificationId
: kRemotingScreenShareNotificationId,
l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_SHARE_TITLE),
message, std::u16string() /* display_source */, GURL(),
message_center::NotifierId(
@ -122,18 +125,19 @@ void ScreenSecurityController::CreateNotification(const std::u16string& message,
std::move(notification));
}
void ScreenSecurityController::StopAllSessions(bool is_capture) {
if (features::IsVideoConferenceEnabled() && !is_capture) {
void ScreenSecurityController::StopAllSessions(bool is_screen_access) {
if (features::IsVideoConferenceEnabled() && !is_screen_access) {
return;
}
message_center::MessageCenter::Get()->RemoveNotification(
is_capture ? kScreenCaptureNotificationId : kScreenShareNotificationId,
is_screen_access ? kScreenAccessNotificationId
: kRemotingScreenShareNotificationId,
false /* by_user */);
std::vector<base::OnceClosure> callbacks;
std::swap(callbacks,
is_capture ? capture_stop_callbacks_ : share_stop_callbacks_);
std::swap(callbacks, is_screen_access ? screen_access_stop_callbacks_
: remoting_share_stop_callbacks_);
for (base::OnceClosure& callback : callbacks) {
if (callback)
std::move(callback).Run();
@ -143,15 +147,16 @@ void ScreenSecurityController::StopAllSessions(bool is_capture) {
}
void ScreenSecurityController::ChangeSource() {
if (change_source_callback_ && capture_stop_callbacks_.size() == 1)
if (change_source_callback_ && screen_access_stop_callbacks_.size() == 1) {
change_source_callback_.Run();
}
}
void ScreenSecurityController::OnScreenCaptureStart(
void ScreenSecurityController::OnScreenAccessStart(
base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& screen_capture_status) {
capture_stop_callbacks_.emplace_back(std::move(stop_callback));
const std::u16string& access_app_name) {
screen_access_stop_callbacks_.emplace_back(std::move(stop_callback));
change_source_callback_ = source_callback;
// We do not want to show the screen capture notification and the chromecast
@ -164,16 +169,15 @@ void ScreenSecurityController::OnScreenCaptureStart(
if (is_casting_)
return;
CreateNotification(screen_capture_status, true /* is_capture */);
CreateNotification(access_app_name, /*is_screen_access_notification=*/true);
}
void ScreenSecurityController::OnScreenCaptureStop() {
StopAllSessions(true /* is_capture */);
void ScreenSecurityController::OnScreenAccessStop() {
StopAllSessions(/*is_screen_access=*/true);
}
void ScreenSecurityController::OnScreenShareStart(
base::OnceClosure stop_callback,
const std::u16string& helper_name) {
void ScreenSecurityController::OnRemotingScreenShareStart(
base::OnceClosure stop_callback) {
// Don't send screen share notifications, because the VideoConferenceTray
// serves as the notifier for screen share. As for screen capture, continue to
// show these notifications for now, although they may end up in the
@ -182,28 +186,22 @@ void ScreenSecurityController::OnScreenShareStart(
return;
}
share_stop_callbacks_.emplace_back(std::move(stop_callback));
remoting_share_stop_callbacks_.emplace_back(std::move(stop_callback));
std::u16string help_label_text;
if (!helper_name.empty()) {
help_label_text = l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED_NAME, helper_name);
} else {
help_label_text = l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED);
}
CreateNotification(help_label_text, false /* is_capture */);
CreateNotification(
l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED),
/*is_screen_access_notification=*/false);
if (features::IsPrivacyIndicatorsEnabled())
UpdatePrivacyIndicatorsScreenShareStatus(/*is_screen_sharing=*/true);
}
void ScreenSecurityController::OnScreenShareStop() {
void ScreenSecurityController::OnRemotingScreenShareStop() {
if (features::IsVideoConferenceEnabled()) {
return;
}
StopAllSessions(false /* is_capture */);
StopAllSessions(/*is_screen_access=*/false);
if (features::IsPrivacyIndicatorsEnabled())
UpdatePrivacyIndicatorsScreenShareStatus(/*is_screen_sharing=*/false);

@ -9,20 +9,18 @@
#include <vector>
#include "ash/shell_observer.h"
#include "ash/system/privacy/screen_capture_observer.h"
#include "ash/system/privacy/screen_share_observer.h"
#include "ash/system/privacy/screen_security_observer.h"
#include "base/memory/weak_ptr.h"
namespace ash {
extern ASH_EXPORT const char kScreenCaptureNotificationId[];
extern ASH_EXPORT const char kScreenShareNotificationId[];
extern ASH_EXPORT const char kNotifierScreenCapture[];
extern ASH_EXPORT const char kNotifierScreenShare[];
extern ASH_EXPORT const char kScreenAccessNotificationId[];
extern ASH_EXPORT const char kRemotingScreenShareNotificationId[];
extern ASH_EXPORT const char kNotifierScreenAccess[];
extern ASH_EXPORT const char kNotifierRemotingScreenShare[];
// Controller class to manage screen security notifications.
class ASH_EXPORT ScreenSecurityController : public ScreenCaptureObserver,
public ScreenShareObserver,
class ASH_EXPORT ScreenSecurityController : public ScreenSecurityObserver,
public ShellObserver {
public:
ScreenSecurityController();
@ -33,26 +31,28 @@ class ASH_EXPORT ScreenSecurityController : public ScreenCaptureObserver,
~ScreenSecurityController() override;
private:
void CreateNotification(const std::u16string& message, bool is_capture);
// Remove the notification and call all the callbacks in
// |capture_stop_callbacks_| or |share_stop_callbacks_|, depending on
// |is_capture| argument.
void StopAllSessions(bool is_capture);
// Change the source of current capture session by bringing up the picker
// Creates the screen security notification. If
// `is_screen_access_notification`, the notification is created for screen
// access. Otherwise it is for remoting screen share.
void CreateNotification(const std::u16string& message,
bool is_screen_access_notification);
// Removes the notification and calls all the callbacks in
// `screen_access_stop_callbacks_` or `remoting_share_stop_callbacks_`,
// depending on `is_screen_access` argument.
void StopAllSessions(bool is_screen_access);
// Changes the source of current capture session by bringing up the picker
// again, only if there is only one screen capture session.
void ChangeSource();
// ScreenCaptureObserver:
void OnScreenCaptureStart(
base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& screen_capture_status) override;
void OnScreenCaptureStop() override;
// ScreenShareObserver:
void OnScreenShareStart(base::OnceClosure stop_callback,
const std::u16string& helper_name) override;
void OnScreenShareStop() override;
// ScreenSecurityObserver:
void OnScreenAccessStart(base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& access_app_name) override;
void OnScreenAccessStop() override;
void OnRemotingScreenShareStart(base::OnceClosure stop_callback) override;
void OnRemotingScreenShareStop() override;
// ShellObserver:
void OnCastingSessionStartedOrStopped(bool started) override;
@ -60,10 +60,10 @@ class ASH_EXPORT ScreenSecurityController : public ScreenCaptureObserver,
bool is_casting_ = false;
// There can be multiple cast sessions at the same time. If the user hits the
// stop button, stop all sessions since there is not a good UI to distinguish
// stop button, stops all sessions since there is not a good UI to distinguish
// between the different sessions.
std::vector<base::OnceClosure> capture_stop_callbacks_;
std::vector<base::OnceClosure> share_stop_callbacks_;
std::vector<base::OnceClosure> screen_access_stop_callbacks_;
std::vector<base::OnceClosure> remoting_share_stop_callbacks_;
base::RepeatingClosure change_source_callback_;
base::WeakPtrFactory<ScreenSecurityController> weak_ptr_factory_{this};

@ -69,34 +69,34 @@ INSTANTIATE_TEST_SUITE_P(
/*IsPrivacyIndicatorsFeatureEnabled()=*/::testing::Bool());
TEST_P(ScreenSecurityControllerTest, ShowScreenCaptureNotification) {
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStart(
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStart(
base::DoNothing(), base::RepeatingClosure(), std::u16string());
EXPECT_TRUE(FindNotification(kScreenCaptureNotificationId));
EXPECT_TRUE(FindNotification(kScreenAccessNotificationId));
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStop();
EXPECT_FALSE(FindNotification(kScreenCaptureNotificationId));
EXPECT_FALSE(FindNotification(kScreenAccessNotificationId));
}
TEST_P(ScreenSecurityControllerTest, ShowScreenShareNotification) {
Shell::Get()->system_tray_notifier()->NotifyScreenShareStart(
base::DoNothing(), std::u16string());
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStart(
base::DoNothing());
EXPECT_TRUE(FindNotification(kScreenShareNotificationId));
EXPECT_TRUE(FindNotification(kRemotingScreenShareNotificationId));
Shell::Get()->system_tray_notifier()->NotifyScreenShareStop();
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStop();
EXPECT_FALSE(FindNotification(kScreenShareNotificationId));
EXPECT_FALSE(FindNotification(kRemotingScreenShareNotificationId));
}
// Tests that `NotifyScreenShareStop()` does not crash if called with no
// Tests that `NotifyRemotingScreenShareStop()` does not crash if called with no
// notification with VideoConference enabled and disabled.
TEST_P(ScreenSecurityControllerTest, NotifyScreenShareStopNoNotification) {
Shell::Get()->system_tray_notifier()->NotifyScreenShareStop();
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStop();
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(features::kVideoConference);
Shell::Get()->system_tray_notifier()->NotifyScreenShareStop();
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStop();
}
// Tests that screen share notifications do not show when VideoConference is
@ -106,20 +106,20 @@ TEST_P(ScreenSecurityControllerTest,
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(features::kVideoConference);
Shell::Get()->system_tray_notifier()->NotifyScreenShareStart(
base::DoNothing(), std::u16string());
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStart(
base::DoNothing());
EXPECT_FALSE(FindNotification(kScreenShareNotificationId));
EXPECT_FALSE(FindNotification(kRemotingScreenShareNotificationId));
}
// Tests that calling `NotifyScreenCaptureStop()` does not crash if called with
// Tests that calling `NotifyScreenAccessStop()` does not crash if called with
// no notification with VideoConference enabled and disabled.
TEST_P(ScreenSecurityControllerTest, NotifyScreenCaptureStopNoNotification) {
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStop();
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(features::kVideoConference);
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStop();
}
// Tests that screen capture notifications show with video conference enabled.
@ -128,26 +128,26 @@ TEST_P(ScreenSecurityControllerTest,
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(features::kVideoConference);
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStart(
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStart(
base::DoNothing(), base::RepeatingClosure(), std::u16string());
EXPECT_TRUE(FindNotification(kScreenCaptureNotificationId));
EXPECT_TRUE(FindNotification(kScreenAccessNotificationId));
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStop();
EXPECT_FALSE(FindNotification(kScreenCaptureNotificationId));
EXPECT_FALSE(FindNotification(kScreenAccessNotificationId));
}
TEST_P(ScreenSecurityControllerTest,
DoNotShowScreenCaptureNotificationWhenCasting) {
Shell::Get()->OnCastingSessionStartedOrStopped(true /* started */);
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStart(
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStart(
base::DoNothing(), base::RepeatingClosure(), std::u16string());
EXPECT_FALSE(FindNotification(kScreenCaptureNotificationId));
EXPECT_FALSE(FindNotification(kScreenAccessNotificationId));
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStop();
Shell::Get()->OnCastingSessionStartedOrStopped(false /* started */);
EXPECT_FALSE(FindNotification(kScreenCaptureNotificationId));
EXPECT_FALSE(FindNotification(kScreenAccessNotificationId));
}
class PrivacyIndicatorsScreenSecurityTest : public AshTestBase {
@ -173,10 +173,10 @@ class PrivacyIndicatorsScreenSecurityTest : public AshTestBase {
// Tests that the screen share notification is created with proper metadata when
// the `SystemTrayNotifier` notifies observers of screen share start.
TEST_F(PrivacyIndicatorsScreenSecurityTest, ScreenShareNotification) {
Shell::Get()->system_tray_notifier()->NotifyScreenShareStart(
base::DoNothing(), std::u16string());
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStart(
base::DoNothing());
auto* notification = FindNotification(kScreenShareNotificationId);
auto* notification = FindNotification(kRemotingScreenShareNotificationId);
EXPECT_TRUE(notification);
// Notification should have the correct notifier id so that it will be grouped
@ -195,11 +195,11 @@ TEST_F(PrivacyIndicatorsScreenSecurityTest, TrayItemIndicator) {
ExpectPrivacyIndicatorsVisible(/*visible=*/false);
Shell::Get()->system_tray_notifier()->NotifyScreenShareStart(
base::DoNothing(), std::u16string());
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStart(
base::DoNothing());
ExpectPrivacyIndicatorsVisible(/*visible=*/true);
Shell::Get()->system_tray_notifier()->NotifyScreenShareStop();
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStop();
ExpectPrivacyIndicatorsVisible(/*visible=*/false);
}

@ -0,0 +1,42 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SYSTEM_PRIVACY_SCREEN_SECURITY_OBSERVER_H_
#define ASH_SYSTEM_PRIVACY_SCREEN_SECURITY_OBSERVER_H_
#include <string>
#include "base/functional/callback.h"
namespace ash {
class ScreenSecurityObserver {
public:
// Called when the screen starts being accessed (i.e. screen sharing, screen
// capture). Note that this function will not be called during system screen
// capture (please consult the owners of //ash/capture_mode for this) and
// during screen sharing via remoting (see functions below for this).
// `stop_callback` is the callback to stop the stream.
// `source_callback` is the callback to change the desktop capture source.
virtual void OnScreenAccessStart(
base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& access_app_name) {}
// Called when the screen is no longer being accessed.
virtual void OnScreenAccessStop() {}
// Called when screen share via remoting is started.
virtual void OnRemotingScreenShareStart(base::OnceClosure stop_callback) {}
// Called when screen share via remoting is stopped.
virtual void OnRemotingScreenShareStop() {}
protected:
virtual ~ScreenSecurityObserver() = default;
};
} // namespace ash
#endif // ASH_SYSTEM_PRIVACY_SCREEN_SECURITY_OBSERVER_H_

@ -1,29 +0,0 @@
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SYSTEM_PRIVACY_SCREEN_SHARE_OBSERVER_H_
#define ASH_SYSTEM_PRIVACY_SCREEN_SHARE_OBSERVER_H_
#include <string>
#include "base/functional/callback.h"
namespace ash {
class ScreenShareObserver {
public:
// Called when screen share is started.
virtual void OnScreenShareStart(base::OnceClosure stop_callback,
const std::u16string& helper_name) = 0;
// Called when screen share is stopped.
virtual void OnScreenShareStop() = 0;
protected:
virtual ~ScreenShareObserver() = default;
};
} // namespace ash
#endif // ASH_SYSTEM_PRIVACY_SCREEN_SHARE_OBSERVER_H_

@ -9,7 +9,6 @@
#include "ash/system/tray/system_tray_notifier.h"
#include "base/functional/bind.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/controls/message_box_view.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/window/dialog_delegate.h"
@ -46,11 +45,11 @@ class CancelCastingDialog : public views::DialogDelegateView {
void OnDialogCancelled() { std::move(callback_).Run(false); }
void OnDialogAccepted() {
// Stop screen sharing and capturing. When notified, all capture sessions or
// all share sessions will be stopped.
// Currently, the logic is in ScreenSecurityNotificationController.
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
Shell::Get()->system_tray_notifier()->NotifyScreenShareStop();
// Stop all screen access and sharing. When notified, all screen access and
// sharing sessions will be stopped. Currently, the logic is in
// ScreenSecurityNotificationController.
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStop();
Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStop();
std::move(callback_).Run(true);
}
@ -62,20 +61,18 @@ class CancelCastingDialog : public views::DialogDelegateView {
} // namespace
ScreenSwitchCheckController::ScreenSwitchCheckController() {
Shell::Get()->system_tray_notifier()->AddScreenCaptureObserver(this);
Shell::Get()->system_tray_notifier()->AddScreenShareObserver(this);
Shell::Get()->system_tray_notifier()->AddScreenSecurityObserver(this);
}
ScreenSwitchCheckController::~ScreenSwitchCheckController() {
Shell::Get()->system_tray_notifier()->RemoveScreenShareObserver(this);
Shell::Get()->system_tray_notifier()->RemoveScreenCaptureObserver(this);
Shell::Get()->system_tray_notifier()->RemoveScreenSecurityObserver(this);
}
void ScreenSwitchCheckController::CanSwitchAwayFromActiveUser(
base::OnceCallback<void(bool)> callback) {
// If neither screen sharing nor capturing is going on we can immediately
// switch users.
if (!has_capture_ && !has_share_) {
if (!is_screen_accessed_ && !is_remoting_share_) {
std::move(callback).Run(true);
return;
}
@ -86,29 +83,28 @@ void ScreenSwitchCheckController::CanSwitchAwayFromActiveUser(
->Show();
}
void ScreenSwitchCheckController::OnScreenCaptureStart(
void ScreenSwitchCheckController::OnScreenAccessStart(
base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& screen_capture_status) {
has_capture_ = true;
const std::u16string& access_app_name) {
is_screen_accessed_ = true;
}
void ScreenSwitchCheckController::OnScreenCaptureStop() {
void ScreenSwitchCheckController::OnScreenAccessStop() {
// Multiple screen capture sessions can exist, but they are stopped at once
// for simplicity.
has_capture_ = false;
is_screen_accessed_ = false;
}
void ScreenSwitchCheckController::OnScreenShareStart(
base::OnceClosure stop_callback,
const std::u16string& helper_name) {
has_share_ = true;
void ScreenSwitchCheckController::OnRemotingScreenShareStart(
base::OnceClosure stop_callback) {
is_remoting_share_ = true;
}
void ScreenSwitchCheckController::OnScreenShareStop() {
void ScreenSwitchCheckController::OnRemotingScreenShareStop() {
// Multiple screen share sessions can exist, but they are stopped at once for
// simplicity.
has_share_ = false;
is_remoting_share_ = false;
}
} // namespace ash

@ -5,15 +5,13 @@
#ifndef ASH_SYSTEM_PRIVACY_SCREEN_SWITCH_CHECK_CONTROLLER_H_
#define ASH_SYSTEM_PRIVACY_SCREEN_SWITCH_CHECK_CONTROLLER_H_
#include "ash/system/privacy/screen_capture_observer.h"
#include "ash/system/privacy/screen_share_observer.h"
#include "ash/system/privacy/screen_security_observer.h"
namespace ash {
// Controller of a dialog that confirms the user wants to stop screen share/cast
// on user profile switching.
class ScreenSwitchCheckController : public ScreenCaptureObserver,
public ScreenShareObserver {
class ScreenSwitchCheckController : public ScreenSecurityObserver {
public:
ScreenSwitchCheckController();
@ -29,20 +27,16 @@ class ScreenSwitchCheckController : public ScreenCaptureObserver,
void CanSwitchAwayFromActiveUser(base::OnceCallback<void(bool)> callback);
private:
// ScreenCaptureObserver:
void OnScreenCaptureStart(
base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& screen_capture_status) override;
void OnScreenCaptureStop() override;
// ScreenSecurityObserver:
void OnScreenAccessStart(base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& access_app_name) override;
void OnScreenAccessStop() override;
void OnRemotingScreenShareStart(base::OnceClosure stop_callback) override;
void OnRemotingScreenShareStop() override;
// ScreenShareObserver:
void OnScreenShareStart(base::OnceClosure stop_callback,
const std::u16string& helper_name) override;
void OnScreenShareStop() override;
bool has_capture_ = false;
bool has_share_ = false;
bool is_screen_accessed_ = false;
bool is_remoting_share_ = false;
};
} // namespace ash

@ -7,8 +7,7 @@
#include "ash/public/cpp/system_tray_observer.h"
#include "ash/system/ime/ime_observer.h"
#include "ash/system/network/network_observer.h"
#include "ash/system/privacy/screen_capture_observer.h"
#include "ash/system/privacy/screen_share_observer.h"
#include "ash/system/privacy/screen_security_observer.h"
#include "ash/system/virtual_keyboard/virtual_keyboard_observer.h"
namespace ash {
@ -48,49 +47,43 @@ void SystemTrayNotifier::NotifyRequestToggleWifi() {
observer.RequestToggleWifi();
}
void SystemTrayNotifier::AddScreenCaptureObserver(
ScreenCaptureObserver* observer) {
screen_capture_observers_.AddObserver(observer);
void SystemTrayNotifier::AddScreenSecurityObserver(
ScreenSecurityObserver* observer) {
screen_security_observers_.AddObserver(observer);
}
void SystemTrayNotifier::RemoveScreenCaptureObserver(
ScreenCaptureObserver* observer) {
screen_capture_observers_.RemoveObserver(observer);
void SystemTrayNotifier::RemoveScreenSecurityObserver(
ScreenSecurityObserver* observer) {
screen_security_observers_.RemoveObserver(observer);
}
void SystemTrayNotifier::NotifyScreenCaptureStart(
void SystemTrayNotifier::NotifyScreenAccessStart(
base::RepeatingClosure stop_callback,
base::RepeatingClosure source_callback,
const std::u16string& sharing_app_name) {
for (auto& observer : screen_capture_observers_)
observer.OnScreenCaptureStart(stop_callback, source_callback,
sharing_app_name);
const std::u16string& access_app_name) {
for (auto& observer : screen_security_observers_) {
observer.OnScreenAccessStart(stop_callback, source_callback,
access_app_name);
}
}
void SystemTrayNotifier::NotifyScreenCaptureStop() {
for (auto& observer : screen_capture_observers_)
observer.OnScreenCaptureStop();
void SystemTrayNotifier::NotifyScreenAccessStop() {
for (auto& observer : screen_security_observers_) {
observer.OnScreenAccessStop();
}
}
void SystemTrayNotifier::AddScreenShareObserver(ScreenShareObserver* observer) {
screen_share_observers_.AddObserver(observer);
void SystemTrayNotifier::NotifyRemotingScreenShareStart(
base::RepeatingClosure stop_callback) {
for (auto& observer : screen_security_observers_) {
observer.OnRemotingScreenShareStart(stop_callback);
}
}
void SystemTrayNotifier::RemoveScreenShareObserver(
ScreenShareObserver* observer) {
screen_share_observers_.RemoveObserver(observer);
}
void SystemTrayNotifier::NotifyScreenShareStart(
base::RepeatingClosure stop_callback,
const std::u16string& helper_name) {
for (auto& observer : screen_share_observers_)
observer.OnScreenShareStart(stop_callback, helper_name);
}
void SystemTrayNotifier::NotifyScreenShareStop() {
for (auto& observer : screen_share_observers_)
observer.OnScreenShareStop();
void SystemTrayNotifier::NotifyRemotingScreenShareStop() {
for (auto& observer : screen_security_observers_) {
observer.OnRemotingScreenShareStop();
}
}
void SystemTrayNotifier::AddSystemTrayObserver(SystemTrayObserver* observer) {

@ -15,8 +15,7 @@ namespace ash {
class IMEObserver;
class NetworkObserver;
class ScreenCaptureObserver;
class ScreenShareObserver;
class ScreenSecurityObserver;
class SystemTrayObserver;
class VirtualKeyboardObserver;
@ -45,20 +44,15 @@ class ASH_EXPORT SystemTrayNotifier {
void RemoveNetworkObserver(NetworkObserver* observer);
void NotifyRequestToggleWifi();
// Screen capture.
void AddScreenCaptureObserver(ScreenCaptureObserver* observer);
void RemoveScreenCaptureObserver(ScreenCaptureObserver* observer);
void NotifyScreenCaptureStart(base::RepeatingClosure stop_callback,
base::RepeatingClosure source_callback,
const std::u16string& sharing_app_name);
void NotifyScreenCaptureStop();
// Screen share.
void AddScreenShareObserver(ScreenShareObserver* observer);
void RemoveScreenShareObserver(ScreenShareObserver* observer);
void NotifyScreenShareStart(base::RepeatingClosure stop_callback,
const std::u16string& helper_name);
void NotifyScreenShareStop();
// Screen security.
void AddScreenSecurityObserver(ScreenSecurityObserver* observer);
void RemoveScreenSecurityObserver(ScreenSecurityObserver* observer);
void NotifyScreenAccessStart(base::RepeatingClosure stop_callback,
base::RepeatingClosure source_callback,
const std::u16string& access_app_name);
void NotifyScreenAccessStop();
void NotifyRemotingScreenShareStart(base::RepeatingClosure stop_callback);
void NotifyRemotingScreenShareStop();
// System tray focus.
void AddSystemTrayObserver(SystemTrayObserver* observer);
@ -74,9 +68,8 @@ class ASH_EXPORT SystemTrayNotifier {
private:
base::ObserverList<IMEObserver>::Unchecked ime_observers_;
base::ObserverList<NetworkObserver>::Unchecked network_observers_;
base::ObserverList<ScreenCaptureObserver>::Unchecked
screen_capture_observers_;
base::ObserverList<ScreenShareObserver>::Unchecked screen_share_observers_;
base::ObserverList<ScreenSecurityObserver>::Unchecked
screen_security_observers_;
base::ObserverList<SystemTrayObserver>::Unchecked system_tray_observers_;
base::ObserverList<VirtualKeyboardObserver>::Unchecked
virtual_keyboard_observers_;

@ -19,7 +19,7 @@ ScreenProjectionChangeMonitor::ScreenProjectionChangeMonitor(
// Shell::Get() and CastConfigController::Get() might be null in tests.
if (Shell::HasInstance()) {
Shell::Get()->display_manager()->AddObserver(this);
Shell::Get()->system_tray_notifier()->AddScreenCaptureObserver(this);
Shell::Get()->system_tray_notifier()->AddScreenSecurityObserver(this);
}
if (CastConfigController::Get()) {
@ -33,7 +33,7 @@ ScreenProjectionChangeMonitor::~ScreenProjectionChangeMonitor() {
}
if (Shell::HasInstance()) {
Shell::Get()->system_tray_notifier()->RemoveScreenCaptureObserver(this);
Shell::Get()->system_tray_notifier()->RemoveScreenSecurityObserver(this);
Shell::Get()->display_manager()->RemoveObserver(this);
}
}
@ -63,14 +63,14 @@ void ScreenProjectionChangeMonitor::OnDevicesUpdated(
UpdateCastingAndMirroringState(casting_desktop, is_mirroring_);
}
void ScreenProjectionChangeMonitor::OnScreenCaptureStart(
void ScreenProjectionChangeMonitor::OnScreenAccessStart(
base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& screen_capture_status) {
const std::u16string& access_app_name) {
UpdateCastingAndMirroringState(true, is_mirroring_);
}
void ScreenProjectionChangeMonitor::OnScreenCaptureStop() {
void ScreenProjectionChangeMonitor::OnScreenAccessStop() {
UpdateCastingAndMirroringState(false, is_mirroring_);
}

@ -7,7 +7,7 @@
#include "ash/ash_export.h"
#include "ash/public/cpp/cast_config_controller.h"
#include "ash/system/privacy/screen_capture_observer.h"
#include "ash/system/privacy/screen_security_observer.h"
#include "ui/display/display_observer.h"
namespace ash::input_method {
@ -17,7 +17,7 @@ namespace ash::input_method {
class ASH_EXPORT ScreenProjectionChangeMonitor
: public display::DisplayObserver,
public CastConfigController::Observer,
public ScreenCaptureObserver {
public ScreenSecurityObserver {
public:
using OnScreenProjectionChangedCallback =
base::RepeatingCallback<void(bool is_projected)>;
@ -36,12 +36,11 @@ class ASH_EXPORT ScreenProjectionChangeMonitor
// CastConfigController::Observer:
void OnDevicesUpdated(const std::vector<SinkAndRoute>& devices) override;
// ScreenCaptureObserver:
void OnScreenCaptureStart(
base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& screen_capture_status) override;
void OnScreenCaptureStop() override;
// ScreenSecurityObserver:
void OnScreenAccessStart(base::OnceClosure stop_callback,
const base::RepeatingClosure& source_callback,
const std::u16string& access_app_name) override;
void OnScreenAccessStop() override;
bool IsProjecting() const;

@ -40,9 +40,9 @@ TEST_F(ScreenProjectionChangeMonitorTest, ScreenSharingChangeTriggersCallback) {
RepeatingTestFuture<bool> monitor_future;
ScreenProjectionChangeMonitor monitor(monitor_future.GetCallback());
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStart(
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStart(
base::DoNothing(), base::DoNothing(), u"");
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStop();
EXPECT_TRUE(monitor_future.Take());
EXPECT_FALSE(monitor_future.Take());
@ -59,7 +59,7 @@ TEST_F(ScreenProjectionChangeMonitorTest, NoChangeDoesNotTriggerCallback) {
display_manager->UpdateDisplays();
// Turning on screen capture will not change the screen projection state
// because we are already mirroring.
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStart(
Shell::Get()->system_tray_notifier()->NotifyScreenAccessStart(
base::DoNothing(), base::DoNothing(), u"");
EXPECT_TRUE(monitor_future.Take());

@ -19,7 +19,7 @@ ScreenCaptureNotificationUIAsh::~ScreenCaptureNotificationUIAsh() {
// MediaStreamCaptureIndicator will delete ScreenCaptureNotificationUI object
// after it stops screen capture.
stop_callback_.Reset();
ash::Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
ash::Shell::Get()->system_tray_notifier()->NotifyScreenAccessStop();
}
gfx::NativeViewId ScreenCaptureNotificationUIAsh::OnStarted(
@ -27,7 +27,7 @@ gfx::NativeViewId ScreenCaptureNotificationUIAsh::OnStarted(
content::MediaStreamUI::SourceCallback source_callback,
const std::vector<content::DesktopMediaID>& media_ids) {
stop_callback_ = std::move(stop_callback);
ash::Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStart(
ash::Shell::Get()->system_tray_notifier()->NotifyScreenAccessStart(
base::BindRepeating(
&ScreenCaptureNotificationUIAsh::ProcessStopRequestFromUI,
base::Unretained(this)),

@ -32,18 +32,14 @@ class DisconnectWindowAura : public HostWindow {
DisconnectWindowAura::DisconnectWindowAura() = default;
DisconnectWindowAura::~DisconnectWindowAura() {
ash::Shell::Get()->system_tray_notifier()->NotifyScreenShareStop();
ash::Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStop();
}
void DisconnectWindowAura::Start(
const base::WeakPtr<ClientSessionControl>& client_session_control) {
// TODO(kelvinp): Clean up the NotifyScreenShareStart interface when we
// completely retire Hangout Remote Desktop v1.
std::u16string helper_name;
ash::Shell::Get()->system_tray_notifier()->NotifyScreenShareStart(
ash::Shell::Get()->system_tray_notifier()->NotifyRemotingScreenShareStart(
base::BindRepeating(&ClientSessionControl::DisconnectSession,
client_session_control, protocol::OK),
helper_name);
client_session_control, protocol::OK));
}
} // namespace