Commit fb1bc3c7 authored by Sergey Poromov's avatar Sergey Poromov Committed by Commit Bot

DLP: Show a notification when screen capture is paused/resumed.

When confidential content appears in the capture area, the screen capture is being paused.
User should be notified about this via a notification.
The same should be done when the capture is resumed as the content leaves the capture area.

Bug: 1134566
Change-Id: Ide75999dda0cea04f14b56407513a47897fbc7eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2520834Reviewed-by: default avatarNikita Podguzov <nikitapodguzov@chromium.org>
Commit-Queue: Sergey Poromov <poromov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825373}
parent 969fb156
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_notification_helper.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "content/public/browser/visibility.h" #include "content/public/browser/visibility.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
...@@ -153,6 +154,7 @@ void DlpContentManager::OnScreenCaptureStopped( ...@@ -153,6 +154,7 @@ void DlpContentManager::OnScreenCaptureStopped(
[=](const ScreenCaptureInfo& capture) -> bool { [=](const ScreenCaptureInfo& capture) -> bool {
return capture.label == label && capture.media_id == media_id; return capture.label == label && capture.media_id == media_id;
}); });
MaybeUpdateScreenCaptureNotification();
} }
/* static */ /* static */
...@@ -375,6 +377,39 @@ void DlpContentManager::CheckRunningVideoCapture() { ...@@ -375,6 +377,39 @@ void DlpContentManager::CheckRunningVideoCapture() {
} }
} }
void DlpContentManager::MaybeUpdateScreenCaptureNotification() {
bool is_running = false;
bool is_paused = false;
for (auto& capture : running_screen_captures_) {
is_running |= capture.is_running;
is_paused |= !capture.is_running;
}
// If a capture was paused and a "paused" notification was shown, but the
// capture is resumed/stopped - hide the "paused" notification.
if (showing_paused_notification_ && !is_paused) {
HideDlpScreenCapturePausedNotification();
showing_paused_notification_ = false;
// If a capture was paused and later resumed - show a "resumed" notification
// if not yet shown.
if (!showing_resumed_notification_ && is_running) {
ShowDlpScreenCaptureResumedNotification();
showing_resumed_notification_ = true;
}
}
// If a capture was resumed and "resumed" notification was shown, but the
// capture is not running anymore - hide the "resumed" notification.
if (showing_resumed_notification_ && !is_running) {
HideDlpScreenCaptureResumedNotification();
showing_resumed_notification_ = false;
}
// If a capture was paused, but no notification is yet shown - show "paused"
// notification.
if (!showing_paused_notification_ && is_paused) {
ShowDlpScreenCapturePausedNotification();
showing_paused_notification_ = true;
}
}
void DlpContentManager::CheckRunningScreenCaptures() { void DlpContentManager::CheckRunningScreenCaptures() {
for (auto& capture : running_screen_captures_) { for (auto& capture : running_screen_captures_) {
bool is_allowed = !IsScreenCaptureRestricted(capture.media_id); bool is_allowed = !IsScreenCaptureRestricted(capture.media_id);
...@@ -384,6 +419,7 @@ void DlpContentManager::CheckRunningScreenCaptures() { ...@@ -384,6 +419,7 @@ void DlpContentManager::CheckRunningScreenCaptures() {
? blink::mojom::MediaStreamStateChange::PAUSE ? blink::mojom::MediaStreamStateChange::PAUSE
: blink::mojom::MediaStreamStateChange::PLAY); : blink::mojom::MediaStreamStateChange::PLAY);
capture.is_running = is_allowed; capture.is_running = is_allowed;
MaybeUpdateScreenCaptureNotification();
} }
} }
} }
......
...@@ -110,6 +110,8 @@ class DlpContentManager : public DlpWindowObserver::Delegate { ...@@ -110,6 +110,8 @@ class DlpContentManager : public DlpWindowObserver::Delegate {
VideoCaptureNotStoppedWhenConfidentialWindowHidden); VideoCaptureNotStoppedWhenConfidentialWindowHidden);
FRIEND_TEST_ALL_PREFIXES(DlpContentManagerPolicyBrowserTest, FRIEND_TEST_ALL_PREFIXES(DlpContentManagerPolicyBrowserTest,
GetRestrictionSetForURL); GetRestrictionSetForURL);
FRIEND_TEST_ALL_PREFIXES(DlpContentManagerBrowserTest,
ScreenCaptureNotification);
FRIEND_TEST_ALL_PREFIXES(::WebRtcGetDisplayMediaBrowserTestWithPicker, FRIEND_TEST_ALL_PREFIXES(::WebRtcGetDisplayMediaBrowserTestWithPicker,
GetDisplayMediaVideoWithDlp); GetDisplayMediaVideoWithDlp);
friend class DlpContentManagerTest; friend class DlpContentManagerTest;
...@@ -179,6 +181,10 @@ class DlpContentManager : public DlpWindowObserver::Delegate { ...@@ -179,6 +181,10 @@ class DlpContentManager : public DlpWindowObserver::Delegate {
// in the corresponding areas. // in the corresponding areas.
void CheckRunningVideoCapture(); void CheckRunningVideoCapture();
// Checks whether screen capture paused/resumed notification should be shown
// or hidden.
void MaybeUpdateScreenCaptureNotification();
// Checks and stops the running screen captures if restricted content appeared // Checks and stops the running screen captures if restricted content appeared
// in the corresponding areas. // in the corresponding areas.
void CheckRunningScreenCaptures(); void CheckRunningScreenCaptures();
...@@ -203,6 +209,11 @@ class DlpContentManager : public DlpWindowObserver::Delegate { ...@@ -203,6 +209,11 @@ class DlpContentManager : public DlpWindowObserver::Delegate {
// List of the currently running screen captures. // List of the currently running screen captures.
std::vector<ScreenCaptureInfo> running_screen_captures_; std::vector<ScreenCaptureInfo> running_screen_captures_;
// Indicates whether screen capture paused/resumed notification is currently
// shown.
bool showing_paused_notification_ = false;
bool showing_resumed_notification_ = false;
}; };
} // namespace policy } // namespace policy
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/policy/policy_test_utils.h" #include "chrome/browser/policy/policy_test_utils.h"
#include "chrome/browser/ui/ash/screenshot_area.h" #include "chrome/browser/ui/ash/screenshot_area.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
#include "chrome/test/base/ui_test_utils.h" #include "chrome/test/base/ui_test_utils.h"
#include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h" #include "components/policy/policy_constants.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/test/browser_test.h" #include "content/public/test/browser_test.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
...@@ -26,6 +28,7 @@ ...@@ -26,6 +28,7 @@
namespace policy { namespace policy {
namespace { namespace {
const DlpContentRestrictionSet kEmptyRestrictionSet;
const DlpContentRestrictionSet kScreenshotRestricted( const DlpContentRestrictionSet kScreenshotRestricted(
DlpContentRestriction::kScreenshot); DlpContentRestriction::kScreenshot);
const DlpContentRestrictionSet kPrivacyScreenEnforced( const DlpContentRestrictionSet kPrivacyScreenEnforced(
...@@ -35,6 +38,11 @@ const DlpContentRestrictionSet kVideoCaptureRestricted( ...@@ -35,6 +38,11 @@ const DlpContentRestrictionSet kVideoCaptureRestricted(
DlpContentRestriction::kVideoCapture); DlpContentRestriction::kVideoCapture);
const DlpContentRestrictionSet kScreenShareRestricted( const DlpContentRestrictionSet kScreenShareRestricted(
DlpContentRestriction::kScreenShare); DlpContentRestriction::kScreenShare);
constexpr char kScreenCapturePausedNotificationId[] =
"screen_capture_dlp_paused";
constexpr char kScreenCaptureResumedNotificationId[] =
"screen_capture_dlp_resumed";
} // namespace } // namespace
class DlpContentManagerBrowserTest : public InProcessBrowserTest { class DlpContentManagerBrowserTest : public InProcessBrowserTest {
...@@ -225,6 +233,46 @@ IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest, ...@@ -225,6 +233,46 @@ IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest,
browser2->window()->Close(); browser2->window()->Close();
} }
IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest,
ScreenCaptureNotification) {
NotificationDisplayServiceTester display_service_tester(browser()->profile());
DlpContentManager* manager = DlpContentManager::Get();
ui_test_utils::NavigateToURL(browser(), GURL("https://example.com"));
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
aura::Window* root_window =
browser()->window()->GetNativeWindow()->GetRootWindow();
const auto media_id = content::DesktopMediaID::RegisterNativeWindow(
content::DesktopMediaID::TYPE_SCREEN, root_window);
manager->OnScreenCaptureStarted("label", {media_id}, base::DoNothing());
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCapturePausedNotificationId));
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCaptureResumedNotificationId));
manager->OnConfidentialityChanged(web_contents, kScreenShareRestricted);
EXPECT_TRUE(display_service_tester.GetNotification(
kScreenCapturePausedNotificationId));
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCaptureResumedNotificationId));
manager->OnConfidentialityChanged(web_contents, kEmptyRestrictionSet);
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCapturePausedNotificationId));
EXPECT_TRUE(display_service_tester.GetNotification(
kScreenCaptureResumedNotificationId));
manager->OnScreenCaptureStopped("label", media_id);
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCapturePausedNotificationId));
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCaptureResumedNotificationId));
}
class DlpContentManagerPolicyBrowserTest : public PolicyTest { class DlpContentManagerPolicyBrowserTest : public PolicyTest {
public: public:
DlpContentManagerPolicyBrowserTest() { DlpContentManagerPolicyBrowserTest() {
......
...@@ -21,16 +21,18 @@ namespace policy { ...@@ -21,16 +21,18 @@ namespace policy {
namespace { namespace {
constexpr char kPrintBlockedNotificationId[] = "print_dlp_blocked"; constexpr char kPrintBlockedNotificationId[] = "print_dlp_blocked";
constexpr char kScreenCapturePausedNotificationId[] =
"screen_capture_dlp_paused";
constexpr char kScreenCaptureResumedNotificationId[] =
"screen_capture_dlp_resumed";
constexpr char kDlpPolicyNotifierId[] = "policy.dlp"; constexpr char kDlpPolicyNotifierId[] = "policy.dlp";
} // namespace void ShowDlpNotification(const std::string& id,
const base::string16& title,
void ShowDlpPrintDisabledNotification() { const base::string16& message) {
std::unique_ptr<message_center::Notification> notification = std::unique_ptr<message_center::Notification> notification =
ash::CreateSystemNotification( ash::CreateSystemNotification(
message_center::NOTIFICATION_TYPE_SIMPLE, kPrintBlockedNotificationId, message_center::NOTIFICATION_TYPE_SIMPLE, id, title, message,
l10n_util::GetStringUTF16(IDS_POLICY_DLP_PRINTING_BLOCKED_TITLE),
l10n_util::GetStringUTF16(IDS_POLICY_DLP_PRINTING_BLOCKED_MESSAGE),
/*display_source=*/base::string16(), GURL(), /*display_source=*/base::string16(), GURL(),
message_center::NotifierId( message_center::NotifierId(
message_center::NotifierType::SYSTEM_COMPONENT, message_center::NotifierType::SYSTEM_COMPONENT,
...@@ -40,11 +42,47 @@ void ShowDlpPrintDisabledNotification() { ...@@ -40,11 +42,47 @@ void ShowDlpPrintDisabledNotification() {
vector_icons::kBusinessIcon, vector_icons::kBusinessIcon,
message_center::SystemNotificationWarningLevel::CRITICAL_WARNING); message_center::SystemNotificationWarningLevel::CRITICAL_WARNING);
notification->set_renotify(true); notification->set_renotify(true);
NotificationDisplayService::GetForProfile( NotificationDisplayService::GetForProfile(
ProfileManager::GetActiveUserProfile()) ProfileManager::GetActiveUserProfile())
->Display(NotificationHandler::Type::TRANSIENT, *notification, ->Display(NotificationHandler::Type::TRANSIENT, *notification,
/*metadata=*/nullptr); /*metadata=*/nullptr);
} }
} // namespace
void ShowDlpPrintDisabledNotification() {
ShowDlpNotification(
kPrintBlockedNotificationId,
l10n_util::GetStringUTF16(IDS_POLICY_DLP_PRINTING_BLOCKED_TITLE),
l10n_util::GetStringUTF16(IDS_POLICY_DLP_PRINTING_BLOCKED_MESSAGE));
}
void HideDlpScreenCapturePausedNotification() {
NotificationDisplayService::GetForProfile(
ProfileManager::GetActiveUserProfile())
->Close(NotificationHandler::Type::TRANSIENT,
kScreenCapturePausedNotificationId);
}
void ShowDlpScreenCapturePausedNotification() {
ShowDlpNotification(
kScreenCapturePausedNotificationId,
l10n_util::GetStringUTF16(IDS_POLICY_DLP_SCREEN_CAPTURE_PAUSED_TITLE),
l10n_util::GetStringUTF16(IDS_POLICY_DLP_SCREEN_CAPTURE_PAUSED_MESSAGE));
}
void HideDlpScreenCaptureResumedNotification() {
NotificationDisplayService::GetForProfile(
ProfileManager::GetActiveUserProfile())
->Close(NotificationHandler::Type::TRANSIENT,
kScreenCaptureResumedNotificationId);
}
void ShowDlpScreenCaptureResumedNotification() {
ShowDlpNotification(
kScreenCaptureResumedNotificationId,
l10n_util::GetStringUTF16(IDS_POLICY_DLP_SCREEN_CAPTURE_RESUMED_TITLE),
l10n_util::GetStringUTF16(IDS_POLICY_DLP_SCREEN_CAPTURE_RESUMED_MESSAGE));
}
} // namespace policy } // namespace policy
...@@ -10,6 +10,14 @@ namespace policy { ...@@ -10,6 +10,14 @@ namespace policy {
// Shows a notification that printing is not allowed due to DLP rules. // Shows a notification that printing is not allowed due to DLP rules.
void ShowDlpPrintDisabledNotification(); void ShowDlpPrintDisabledNotification();
// Shows/hides a notification that screen capture was paused because
// confidential content appeared in the captured area, or resumed when it left
// the captured area.
void HideDlpScreenCapturePausedNotification();
void ShowDlpScreenCapturePausedNotification();
void HideDlpScreenCaptureResumedNotification();
void ShowDlpScreenCaptureResumedNotification();
} // namespace policy } // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_NOTIFICATION_HELPER_H_ #endif // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_NOTIFICATION_HELPER_H_
...@@ -591,5 +591,17 @@ Additional details: ...@@ -591,5 +591,17 @@ Additional details:
<message name="IDS_POLICY_DLP_PRINTING_BLOCKED_MESSAGE" desc="The message for notification informing the user that printing is blocked."> <message name="IDS_POLICY_DLP_PRINTING_BLOCKED_MESSAGE" desc="The message for notification informing the user that printing is blocked.">
Printing of this content is blocked by your administrator. Printing of this content is blocked by your administrator.
</message> </message>
<message name="IDS_POLICY_DLP_SCREEN_CAPTURE_PAUSED_TITLE" desc="The title for notification informing the user that screen capture is paused.">
Screen capture paused
</message>
<message name="IDS_POLICY_DLP_SCREEN_CAPTURE_PAUSED_MESSAGE" desc="The message for notification informing the user that screen capture is paused.">
Screen capture has been paused by your administrator due to content on your screen.
</message>
<message name="IDS_POLICY_DLP_SCREEN_CAPTURE_RESUMED_TITLE" desc="The title for notification informing the user that screen capture is resumed.">
Screen capture resumed
</message>
<message name="IDS_POLICY_DLP_SCREEN_CAPTURE_RESUMED_MESSAGE" desc="The message for notification informing the user that screen capture is resumed.">
Screen capture has been resumed.
</message>
</grit-part> </grit-part>
9dc8bc7b71430c645dfa483ea7a0a54df9262c2c
\ No newline at end of file
9dc8bc7b71430c645dfa483ea7a0a54df9262c2c
\ No newline at end of file
0864f0fd6954d3845e100e12e7ba7d59367dc079
\ No newline at end of file
0864f0fd6954d3845e100e12e7ba7d59367dc079
\ No newline at end of file
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