| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/capture_mode/capture_mode_test_util.h" |
| #include "ash/capture_mode/capture_mode_types.h" |
| #include "ash/constants/ash_features.h" |
| #include "ash/public/cpp/capture_mode/capture_mode_test_api.h" |
| #include "ash/public/cpp/projector/projector_client.h" |
| #include "ash/public/cpp/projector/projector_controller.h" |
| #include "ash/public/cpp/projector/projector_session.h" |
| #include "ash/public/cpp/shell_window_ids.h" |
| #include "ash/public/cpp/test/shell_test_api.h" |
| #include "ash/session/session_controller_impl.h" |
| #include "ash/shell.h" |
| #include "ash/system/status_area_widget_test_helper.h" |
| #include "ash/system/video_conference/video_conference_common.h" |
| #include "ash/system/video_conference/video_conference_tray.h" |
| #include "base/files/file_util.h" |
| #include "base/files/safe_base_name.h" |
| #include "base/functional/callback_forward.h" |
| #include "base/run_loop.h" |
| #include "base/scoped_observation.h" |
| #include "base/task/sequenced_task_runner.h" |
| #include "base/test/bind.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "base/test/test_future.h" |
| #include "chrome/browser/ash/file_manager/file_manager_test_util.h" |
| #include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" |
| #include "chrome/browser/ash/video_conference/video_conference_manager_ash.h" |
| #include "chrome/browser/chromeos/policy/dlp/dlp_content_observer.h" |
| #include "chrome/browser/chromeos/policy/dlp/dlp_content_restriction_set.h" |
| #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h" |
| #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h" |
| #include "chrome/browser/chromeos/policy/dlp/test/dlp_content_manager_test_helper.h" |
| #include "chrome/browser/chromeos/policy/dlp/test/mock_dlp_rules_manager.h" |
| #include "chrome/browser/download/download_prefs.h" |
| #include "chrome/browser/enterprise/data_controls/dlp_reporting_manager.h" |
| #include "chrome/browser/enterprise/data_controls/dlp_reporting_manager_test_helper.h" |
| #include "chrome/browser/extensions/extension_browsertest.h" |
| #include "chrome/browser/policy/policy_test_utils.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/common/chrome_features.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/enterprise/common/proto/synced/dlp_policy_event.pb.h" |
| #include "components/policy/policy_constants.h" |
| #include "components/prefs/pref_service.h" |
| #include "content/public/test/browser_test.h" |
| #include "media/base/media_switches.h" |
| #include "media/base/video_frame.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/aura/window_observer.h" |
| #include "ui/events/event_constants.h" |
| #include "ui/events/keycodes/keyboard_codes_posix.h" |
| #include "ui/events/test/event_generator.h" |
| #include "ui/wm/core/window_util.h" |
| |
| namespace { |
| |
| // Defines a report-level restriction type for screen captures. |
| const policy::DlpContentRestrictionSet kScreenCaptureReported{ |
| policy::DlpContentRestriction::kScreenshot, |
| policy::DlpRulesManager::Level::kReport}; |
| // Defines a warning-level restriction type for screen captures. |
| const policy::DlpContentRestrictionSet kScreenCaptureWarned{ |
| policy::DlpContentRestriction::kScreenshot, |
| policy::DlpRulesManager::Level::kWarn}; |
| |
| constexpr char kSrcPattern[] = "example.com"; |
| constexpr char kRuleName[] = "rule #1"; |
| constexpr char kRuleId[] = "testid1"; |
| const policy::DlpRulesManager::RuleMetadata kRuleMetadata(kRuleName, kRuleId); |
| |
| // Returns the native window of the given `browser`. |
| aura::Window* GetBrowserWindow(Browser* browser) { |
| return browser->window()->GetNativeWindow(); |
| } |
| |
| void SetupLoopToWaitForCaptureFileToBeSaved(base::RunLoop* loop) { |
| ash::CaptureModeTestApi().SetOnCaptureFileSavedCallback( |
| base::BindLambdaForTesting([loop](const base::FilePath& path) { |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| EXPECT_TRUE(base::PathExists(path)); |
| loop->Quit(); |
| })); |
| } |
| |
| // Defines a waiter that waits for the DLP warning dialog to be added as a child |
| // of the system modal container window under the given `root`. |
| // A single instance of `DlpWarningDialogWaiter` can be used only once for |
| // waiting. |
| class DlpWarningDialogWaiter : public aura::WindowObserver { |
| public: |
| explicit DlpWarningDialogWaiter(aura::Window* root) { |
| observation_.Observe( |
| root->GetChildById(ash::kShellWindowId_SystemModalContainer)); |
| on_window_added_callback_ = loop_.QuitClosure(); |
| } |
| DlpWarningDialogWaiter(const DlpWarningDialogWaiter&) = delete; |
| DlpWarningDialogWaiter& operator=(const DlpWarningDialogWaiter&) = delete; |
| ~DlpWarningDialogWaiter() override = default; |
| |
| void Wait() { loop_.Run(); } |
| |
| // aura::WindowObserver: |
| void OnWindowAdded(aura::Window* new_window) override { |
| if (on_window_added_callback_) { |
| std::move(on_window_added_callback_).Run(); |
| } |
| } |
| |
| private: |
| base::ScopedObservation<aura::Window, aura::WindowObserver> observation_{ |
| this}; |
| base::RunLoop loop_; |
| base::OnceClosure on_window_added_callback_; |
| }; |
| |
| // Starts a fullscreen video recording. |
| void StartVideoRecording() { |
| ash::CaptureModeTestApi test_api; |
| test_api.StartForFullscreen(/*for_video=*/true); |
| ASSERT_TRUE(test_api.IsSessionActive()); |
| test_api.PerformCapture(); |
| test_api.FlushRecordingServiceForTesting(); |
| EXPECT_TRUE(test_api.IsVideoRecordingInProgress()); |
| } |
| |
| // Marks the active web contents of the given `browser` as DLP restricted with a |
| // warning level. |
| void MarkActiveTabAsDlpWarnedForScreenCapture(Browser* browser) { |
| auto* dlp_content_observer = policy::DlpContentObserver::Get(); |
| ASSERT_TRUE(dlp_content_observer); |
| |
| content::WebContents* web_contents = |
| browser->tab_strip_model()->GetActiveWebContents(); |
| ASSERT_TRUE(web_contents); |
| dlp_content_observer->OnConfidentialityChanged(web_contents, |
| kScreenCaptureWarned); |
| } |
| |
| // Waits for video record countdown to be finished. |
| void WaitForCountDownToFinish() { |
| base::RunLoop run_loop; |
| ash::CaptureModeTestApi().SetOnVideoRecordCountdownFinishedCallback( |
| run_loop.QuitClosure()); |
| run_loop.Run(); |
| } |
| |
| // Stops the video recording and waits for the DLP warning dialog to be added. |
| void StopRecordingAndWaitForDlpWarningDialog(Browser* browser) { |
| auto* root = GetBrowserWindow(browser)->GetRootWindow(); |
| ASSERT_TRUE(root); |
| DlpWarningDialogWaiter waiter{root}; |
| ash::CaptureModeTestApi test_api; |
| test_api.StopVideoRecording(); |
| waiter.Wait(); |
| EXPECT_FALSE(test_api.IsVideoRecordingInProgress()); |
| } |
| |
| void SendKeyEvent(Browser* browser, |
| ui::KeyboardCode key_code, |
| int flags = ui::EF_NONE) { |
| auto* browser_window = GetBrowserWindow(browser); |
| ui::test::EventGenerator event_generator{browser_window->GetRootWindow(), |
| browser_window}; |
| event_generator.PressAndReleaseKeyAndModifierKeys(key_code, flags); |
| } |
| |
| std::unique_ptr<KeyedService> SetDlpRulesManager( |
| content::BrowserContext* context) { |
| auto dlp_rules_manager = |
| std::make_unique<testing::NiceMock<policy::MockDlpRulesManager>>( |
| Profile::FromBrowserContext(context)); |
| ON_CALL(*dlp_rules_manager, GetSourceUrlPattern) |
| .WillByDefault(testing::DoAll(testing::SetArgPointee<3>(kRuleMetadata), |
| testing::Return(kSrcPattern))); |
| return dlp_rules_manager; |
| } |
| |
| } // namespace |
| |
| class CaptureModeBrowserTest : public InProcessBrowserTest {}; |
| |
| IN_PROC_BROWSER_TEST_F(CaptureModeBrowserTest, ContextMenuStaysOpen) { |
| // Right click the desktop to open a context menu. |
| aura::Window* browser_window = browser()->window()->GetNativeWindow(); |
| const gfx::Point point_on_desktop(1, 1); |
| ASSERT_FALSE(browser_window->bounds().Contains(point_on_desktop)); |
| |
| ui::test::EventGenerator event_generator(browser_window->GetRootWindow(), |
| point_on_desktop); |
| event_generator.ClickRightButton(); |
| |
| ash::ShellTestApi shell_test_api; |
| ASSERT_TRUE(shell_test_api.IsContextMenuShown()); |
| |
| ash::CaptureModeTestApi().StartForWindow(/*for_video=*/false); |
| EXPECT_TRUE(shell_test_api.IsContextMenuShown()); |
| } |
| |
| // A regression test for https://crbug.com/1350711 in which a session is started |
| // quickly after clicking the sign out button. |
| IN_PROC_BROWSER_TEST_F(CaptureModeBrowserTest, |
| SimulateStartingSessionAfterSignOut) { |
| ash::Shell::Get()->session_controller()->RequestSignOut(); |
| ash::CaptureModeTestApi().StartForFullscreen(false); |
| } |
| |
| // Testing class to test CrOS capture mode, which is a feature to take |
| // screenshots and record video. |
| class CaptureModeDlpBrowserTest : public CaptureModeBrowserTest { |
| public: |
| CaptureModeDlpBrowserTest() = default; |
| ~CaptureModeDlpBrowserTest() override = default; |
| |
| void SetUpOnMainThread() override { |
| // Instantiate |DlpContentManagerTestHelper| after main thread has been |
| // set up because |DlpReportingManager| needs a sequenced task runner handle |
| // to set up the report queue. |
| helper_ = std::make_unique<policy::DlpContentManagerTestHelper>(); |
| |
| // TODO(https://crbug.com/1283065): Remove this. |
| // Currently, setting the notifier explicitly is needed since otherwise, due |
| // to a wrongly initialized notifier, calling the virtual |
| // ShowDlpWarningDialog() method causes a crash. |
| helper_->ResetWarnNotifierForTesting(); |
| |
| SetupDlpReporting(); |
| } |
| |
| void TearDownOnMainThread() override { helper_.reset(); } |
| |
| void SetupDlpReporting() { |
| SetupDlpRulesManager(); |
| // Set up mock report queue. |
| SetReportQueueForReportingManager( |
| helper_->GetReportingManager(), events_, |
| base::SequencedTaskRunner::GetCurrentDefault()); |
| } |
| |
| const GURL GetActiveWebContentsUrl() { |
| return browser() |
| ->tab_strip_model() |
| ->GetActiveWebContents() |
| ->GetLastCommittedURL(); |
| } |
| |
| protected: |
| // Sets up mock rules manager. |
| void SetupDlpRulesManager() { |
| policy::DlpRulesManagerFactory::GetInstance()->SetTestingFactory( |
| browser()->profile(), base::BindRepeating(&SetDlpRulesManager)); |
| ASSERT_TRUE(policy::DlpRulesManagerFactory::GetForPrimaryProfile()); |
| } |
| |
| std::unique_ptr<policy::DlpContentManagerTestHelper> helper_; |
| std::vector<DlpPolicyEvent> events_; |
| }; |
| |
| // Checks that video capture emits exactly one DLP reporting event. |
| IN_PROC_BROWSER_TEST_F(CaptureModeDlpBrowserTest, DlpReportingVideoCapture) { |
| // Set DLP restriction. |
| auto* dlp_content_observer = policy::DlpContentObserver::Get(); |
| ASSERT_TRUE(dlp_content_observer); |
| content::WebContents* web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| ASSERT_TRUE(web_contents); |
| dlp_content_observer->OnConfidentialityChanged(web_contents, |
| kScreenCaptureReported); |
| |
| ash::CaptureModeTestApi test_api; |
| |
| // Should emit the first reporting event. |
| StartVideoRecording(); |
| ASSERT_TRUE(test_api.IsVideoRecordingInProgress()); |
| // Set up a waiter to wait for the file to be saved. |
| { |
| base::RunLoop loop; |
| SetupLoopToWaitForCaptureFileToBeSaved(&loop); |
| test_api.StopVideoRecording(); |
| loop.Run(); |
| } |
| ASSERT_FALSE(test_api.IsVideoRecordingInProgress()); |
| |
| ASSERT_EQ(events_.size(), 1u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kReport))); |
| |
| // Repeat, should emit the second reporting event. |
| StartVideoRecording(); |
| ASSERT_TRUE(test_api.IsVideoRecordingInProgress()); |
| { |
| base::RunLoop loop; |
| SetupLoopToWaitForCaptureFileToBeSaved(&loop); |
| test_api.StopVideoRecording(); |
| loop.Run(); |
| } |
| ASSERT_FALSE(test_api.IsVideoRecordingInProgress()); |
| |
| ASSERT_EQ(events_.size(), 2u); |
| EXPECT_THAT( |
| events_[1], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kReport))); |
| } |
| |
| // Tests DLP reporting without opening the capture bar. |
| IN_PROC_BROWSER_TEST_F(CaptureModeDlpBrowserTest, |
| DlpReportingDialogOnFullscreenScreenCaptureShortcut) { |
| ASSERT_TRUE(browser()); |
| // Set DLP restriction. |
| auto* dlp_content_observer = policy::DlpContentObserver::Get(); |
| ASSERT_TRUE(dlp_content_observer); |
| content::WebContents* web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| ASSERT_TRUE(web_contents); |
| dlp_content_observer->OnConfidentialityChanged(web_contents, |
| kScreenCaptureReported); |
| |
| // Set up a waiter to wait for the file to be saved. |
| base::RunLoop loop; |
| SetupLoopToWaitForCaptureFileToBeSaved(&loop); |
| |
| SendKeyEvent(browser(), ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN); |
| |
| // Wait for the file to be saved. |
| loop.Run(); |
| |
| ASSERT_EQ(events_.size(), 1u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kReport))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CaptureModeDlpBrowserTest, |
| DlpWarningDialogOnVideoEndDismissed) { |
| ASSERT_TRUE(browser()); |
| StartVideoRecording(); |
| |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| ash::CaptureModeTestApi test_api; |
| // Video recording should not end as a result of adding a restriction of a |
| // warning level type. |
| EXPECT_TRUE(test_api.IsVideoRecordingInProgress()); |
| |
| // Set up a waiter to wait for the file to be deleted. |
| base::RunLoop loop; |
| test_api.SetOnCaptureFileDeletedCallback(base::BindLambdaForTesting( |
| [&loop](const base::FilePath& path, bool delete_successful) { |
| EXPECT_TRUE(delete_successful); |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| EXPECT_FALSE(base::PathExists(path)); |
| loop.Quit(); |
| })); |
| StopRecordingAndWaitForDlpWarningDialog(browser()); |
| |
| // Dismiss the dialog by hitting the ESCAPE key and wait for the file to be |
| // deleted. |
| SendKeyEvent(browser(), ui::VKEY_ESCAPE); |
| loop.Run(); |
| |
| ASSERT_EQ(events_.size(), 1u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| GetActiveWebContentsUrl().spec(), |
| policy::DlpRulesManager::Restriction::kScreenshot, kRuleName, kRuleId, |
| policy::DlpRulesManager::Level::kWarn))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CaptureModeDlpBrowserTest, |
| DlpWarningDialogOnVideoEndAccepted) { |
| ASSERT_TRUE(browser()); |
| StartVideoRecording(); |
| |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| ash::CaptureModeTestApi test_api; |
| // Video recording should not end as a result of adding a restriction of a |
| // warning level type. |
| EXPECT_TRUE(test_api.IsVideoRecordingInProgress()); |
| |
| // Set up a waiter to wait for the file to be saved. |
| base::RunLoop loop; |
| SetupLoopToWaitForCaptureFileToBeSaved(&loop); |
| StopRecordingAndWaitForDlpWarningDialog(browser()); |
| |
| // Accept the dialog by hitting the ENTER key and wait for the file to be |
| // saved. |
| SendKeyEvent(browser(), ui::VKEY_RETURN); |
| loop.Run(); |
| |
| ASSERT_EQ(events_.size(), 2u); |
| const auto src_url = GetActiveWebContentsUrl().spec(); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| src_url, policy::DlpRulesManager::Restriction::kScreenshot, kRuleName, |
| kRuleId, policy::DlpRulesManager::Level::kWarn))); |
| EXPECT_THAT( |
| events_[1], |
| data_controls::IsDlpPolicyEvent( |
| data_controls::CreateDlpPolicyWarningProceededEvent( |
| src_url, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId))); |
| } |
| |
| // Parametrize capture mode browser tests to check both making screenshots and |
| // video capture. This is particularly important for DLP which handles reporting |
| // of user activity differently for screenshots and video capture. |
| class CaptureModeParamDlpBrowserTest |
| : public CaptureModeDlpBrowserTest, |
| public ::testing::WithParamInterface<bool> { |
| public: |
| CaptureModeParamDlpBrowserTest() : for_video_(GetParam()) {} |
| ~CaptureModeParamDlpBrowserTest() override = default; |
| |
| protected: |
| const bool for_video_; |
| }; |
| |
| INSTANTIATE_TEST_SUITE_P(CaptureModeParamDlpBrowserTest, |
| CaptureModeParamDlpBrowserTest, |
| ::testing::Bool()); |
| |
| IN_PROC_BROWSER_TEST_P(CaptureModeParamDlpBrowserTest, |
| DlpWarningDialogOnSessionInitDismissed) { |
| ASSERT_TRUE(browser()); |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| ash::CaptureModeTestApi test_api; |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| test_api.StartForFullscreen(for_video_); |
| // A capture mode session doesn't start immediately. The controller should be |
| // in a pending state waiting for a reply from the DLP manager. |
| EXPECT_FALSE(test_api.IsSessionActive()); |
| EXPECT_TRUE(test_api.IsPendingDlpCheck()); |
| |
| // Dismiss the dialog by hitting the ESCAPE key. The session should be aborted |
| // and the pending state should end. |
| SendKeyEvent(browser(), ui::VKEY_ESCAPE); |
| EXPECT_FALSE(test_api.IsSessionActive()); |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| ASSERT_EQ(events_.size(), 1u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kWarn))); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(CaptureModeParamDlpBrowserTest, |
| DlpWarningDialogOnSessionInitAccepted) { |
| ASSERT_TRUE(browser()); |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| ash::CaptureModeTestApi test_api; |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| test_api.StartForFullscreen(for_video_); |
| // A capture mode session doesn't start immediately. The controller should be |
| // in a pending state waiting for a reply from the DLP manager. |
| EXPECT_FALSE(test_api.IsSessionActive()); |
| EXPECT_TRUE(test_api.IsPendingDlpCheck()); |
| |
| // Accept the dialog by hitting the ENTER key. The session should start and |
| // the pending state should end. |
| SendKeyEvent(browser(), ui::VKEY_RETURN); |
| EXPECT_TRUE(test_api.IsSessionActive()); |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| // Don't send warning proceeded event as the video capture didn't start. |
| |
| ASSERT_EQ(events_.size(), 1u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kWarn))); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(CaptureModeParamDlpBrowserTest, |
| DlpWarningDialogOnPerformingCaptureDismissed) { |
| ASSERT_TRUE(browser()); |
| // Start the session before a window becomes restricted. |
| ash::CaptureModeTestApi test_api; |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| test_api.StartForFullscreen(for_video_); |
| ASSERT_TRUE(test_api.IsSessionActive()); |
| |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| |
| // Attempt performing the capture now, it won't be performed immediately, |
| // rather the dialog will show instead. |
| test_api.PerformCapture(); |
| |
| // The session should remain active but in a pending state. |
| EXPECT_TRUE(test_api.IsSessionActive()); |
| EXPECT_TRUE(test_api.IsPendingDlpCheck()); |
| EXPECT_TRUE(test_api.IsSessionWaitingForDlpConfirmation()); |
| |
| // Dismiss the dialog by hitting the ESCAPE key. The session should be aborted |
| // and the pending state should end. |
| SendKeyEvent(browser(), ui::VKEY_ESCAPE); |
| EXPECT_FALSE(test_api.IsSessionActive()); |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| ASSERT_EQ(events_.size(), 1u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kWarn))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CaptureModeDlpBrowserTest, |
| DlpWarningDialogOnPerformingScreenCaptureAccepted) { |
| ASSERT_TRUE(browser()); |
| // Start the session before a window becomes restricted. |
| ash::CaptureModeTestApi test_api; |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| test_api.StartForFullscreen(/*for_video=*/false); |
| ASSERT_TRUE(test_api.IsSessionActive()); |
| |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| |
| // Attempt performing the capture now, it won't be performed immediately, |
| // rather the dialog will show instead. |
| test_api.PerformCapture(); |
| |
| // The session should remain active but in a pending state. |
| EXPECT_TRUE(test_api.IsSessionActive()); |
| EXPECT_TRUE(test_api.IsPendingDlpCheck()); |
| EXPECT_TRUE(test_api.IsSessionWaitingForDlpConfirmation()); |
| |
| // Accept the dialog by hitting the ENTER key. The session should end, and the |
| // screenshot should be taken. |
| base::RunLoop loop; |
| SetupLoopToWaitForCaptureFileToBeSaved(&loop); |
| SendKeyEvent(browser(), ui::VKEY_RETURN); |
| EXPECT_FALSE(test_api.IsSessionActive()); |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| loop.Run(); |
| |
| EXPECT_EQ(events_.size(), 2u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kWarn))); |
| EXPECT_THAT( |
| events_[1], |
| data_controls::IsDlpPolicyEvent( |
| data_controls::CreateDlpPolicyWarningProceededEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CaptureModeDlpBrowserTest, |
| DlpWarningDialogOnPerformingVideoCaptureAccepted) { |
| ASSERT_TRUE(browser()); |
| SetupDlpReporting(); |
| |
| ash::CaptureModeTestApi test_api; |
| test_api.StartForFullscreen(/*for_video=*/true); |
| ASSERT_TRUE(test_api.IsSessionActive()); |
| |
| auto* root = GetBrowserWindow(browser())->GetRootWindow(); |
| ASSERT_TRUE(root); |
| DlpWarningDialogWaiter waiter{root}; |
| |
| // Mark the window as restricted and perform video capture. |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| test_api.PerformCapture(/*skip_count_down=*/false); |
| EXPECT_FALSE(test_api.IsInCountDownAnimation()); |
| EXPECT_FALSE(test_api.IsVideoRecordingInProgress()); |
| EXPECT_TRUE(test_api.IsSessionActive()); |
| EXPECT_TRUE(test_api.IsPendingDlpCheck()); |
| EXPECT_TRUE(test_api.IsSessionWaitingForDlpConfirmation()); |
| |
| // Wait for the dialog to show before the countdown starts. |
| waiter.Wait(); |
| EXPECT_FALSE(test_api.IsInCountDownAnimation()); |
| EXPECT_FALSE(test_api.IsVideoRecordingInProgress()); |
| EXPECT_TRUE(test_api.IsSessionActive()); |
| EXPECT_TRUE(test_api.IsPendingDlpCheck()); |
| EXPECT_TRUE(test_api.IsSessionWaitingForDlpConfirmation()); |
| |
| // Accept the dialog by hitting the ENTER key, and expect countdown to start. |
| SendKeyEvent(browser(), ui::VKEY_RETURN); |
| EXPECT_TRUE(test_api.IsInCountDownAnimation()); |
| EXPECT_FALSE(test_api.IsVideoRecordingInProgress()); |
| EXPECT_TRUE(test_api.IsSessionActive()); |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| EXPECT_FALSE(test_api.IsSessionWaitingForDlpConfirmation()); |
| |
| // Start the video recording. |
| WaitForCountDownToFinish(); |
| test_api.FlushRecordingServiceForTesting(); |
| EXPECT_FALSE(test_api.IsInCountDownAnimation()); |
| EXPECT_TRUE(test_api.IsVideoRecordingInProgress()); |
| EXPECT_FALSE(test_api.IsSessionActive()); |
| |
| // Stop recording and wait for file to be saved successfully. |
| base::RunLoop loop; |
| SetupLoopToWaitForCaptureFileToBeSaved(&loop); |
| test_api.StopVideoRecording(); |
| loop.Run(); |
| |
| ASSERT_EQ(events_.size(), 2u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kWarn))); |
| EXPECT_THAT( |
| events_[1], |
| data_controls::IsDlpPolicyEvent( |
| data_controls::CreateDlpPolicyWarningProceededEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CaptureModeDlpBrowserTest, |
| DlpWarningDialogOnCountdownEndDismissed) { |
| ASSERT_TRUE(browser()); |
| ash::CaptureModeTestApi test_api; |
| test_api.StartForFullscreen(/*for_video=*/true); |
| ASSERT_TRUE(test_api.IsSessionActive()); |
| test_api.PerformCapture(/*skip_count_down=*/false); |
| EXPECT_TRUE(test_api.IsInCountDownAnimation()); |
| |
| // While countdown is in progress, mark the window as restricted, and wait for |
| // the dialog to show when the countdown ends. |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| auto* root = GetBrowserWindow(browser())->GetRootWindow(); |
| DlpWarningDialogWaiter(root).Wait(); |
| EXPECT_FALSE(test_api.IsInCountDownAnimation()); |
| EXPECT_FALSE(test_api.IsVideoRecordingInProgress()); |
| EXPECT_TRUE(test_api.IsSessionActive()); |
| EXPECT_TRUE(test_api.IsPendingDlpCheck()); |
| EXPECT_TRUE(test_api.IsSessionWaitingForDlpConfirmation()); |
| |
| // Dismiss the dialog by hitting the ESCAPE key and expect that recording |
| // doesn't start. |
| SendKeyEvent(browser(), ui::VKEY_ESCAPE); |
| EXPECT_FALSE(test_api.IsInCountDownAnimation()); |
| EXPECT_FALSE(test_api.IsVideoRecordingInProgress()); |
| EXPECT_FALSE(test_api.IsSessionActive()); |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| ASSERT_EQ(events_.size(), 1u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kWarn))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CaptureModeDlpBrowserTest, |
| DlpWarningDialogOnCountdownEndAccepted) { |
| ASSERT_TRUE(browser()); |
| ash::CaptureModeTestApi test_api; |
| test_api.StartForFullscreen(/*for_video=*/true); |
| ASSERT_TRUE(test_api.IsSessionActive()); |
| test_api.PerformCapture(/*skip_count_down=*/false); |
| EXPECT_TRUE(test_api.IsInCountDownAnimation()); |
| |
| // While countdown is in progress, mark the window as restricted, and wait for |
| // the dialog to show when the countdown ends. |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| auto* root = GetBrowserWindow(browser())->GetRootWindow(); |
| DlpWarningDialogWaiter(root).Wait(); |
| EXPECT_FALSE(test_api.IsInCountDownAnimation()); |
| EXPECT_FALSE(test_api.IsVideoRecordingInProgress()); |
| EXPECT_TRUE(test_api.IsSessionActive()); |
| EXPECT_TRUE(test_api.IsPendingDlpCheck()); |
| EXPECT_TRUE(test_api.IsSessionWaitingForDlpConfirmation()); |
| |
| // Accept the dialog by hitting the ENTER key, and expect recording to start. |
| SendKeyEvent(browser(), ui::VKEY_RETURN); |
| test_api.FlushRecordingServiceForTesting(); |
| EXPECT_FALSE(test_api.IsInCountDownAnimation()); |
| EXPECT_TRUE(test_api.IsVideoRecordingInProgress()); |
| EXPECT_FALSE(test_api.IsSessionActive()); |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| // Stop recording and wait for file to be saved successfully. |
| base::RunLoop loop; |
| SetupLoopToWaitForCaptureFileToBeSaved(&loop); |
| test_api.StopVideoRecording(); |
| loop.Run(); |
| |
| ASSERT_EQ(events_.size(), 2u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kWarn))); |
| EXPECT_THAT( |
| events_[1], |
| data_controls::IsDlpPolicyEvent( |
| data_controls::CreateDlpPolicyWarningProceededEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| CaptureModeDlpBrowserTest, |
| DlpWarningDialogOnCaptureScreenshotsOfAllDisplaysDismissed) { |
| ASSERT_TRUE(browser()); |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| ash::CaptureModeTestApi test_api; |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| // The screenshots should not be taken immediately through the keyboard |
| // shortcut. The controller should be in a pending state waiting for a reply |
| // from the DLP manager. |
| SendKeyEvent(browser(), ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN); |
| EXPECT_TRUE(test_api.IsPendingDlpCheck()); |
| |
| // Dismiss the dialog by hitting the ESCAPE key. The screenshot should be |
| // aborted and the pending state should end. |
| SendKeyEvent(browser(), ui::VKEY_ESCAPE); |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| ASSERT_EQ(events_.size(), 1u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kWarn))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| CaptureModeDlpBrowserTest, |
| DlpWarningDialogOnFullscreenScreenCaptureShortcutAccepted) { |
| ASSERT_TRUE(browser()); |
| MarkActiveTabAsDlpWarnedForScreenCapture(browser()); |
| ash::CaptureModeTestApi test_api; |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| // The screenshots should not be taken immediately through the keyboard |
| // shortcut. The controller should be in a pending state waiting for a reply |
| // from the DLP manager. |
| SendKeyEvent(browser(), ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN); |
| EXPECT_TRUE(test_api.IsPendingDlpCheck()); |
| |
| // Set up a waiter to wait for the file to be saved. |
| base::RunLoop loop; |
| test_api.SetOnCaptureFileSavedCallback( |
| base::BindLambdaForTesting([&loop](const base::FilePath& path) { |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| EXPECT_TRUE(base::PathExists(path)); |
| loop.Quit(); |
| })); |
| |
| // Accept the dialog by hitting the ENTER key. The screenshot should be taken |
| // and the pending state should end. |
| SendKeyEvent(browser(), ui::VKEY_RETURN); |
| EXPECT_FALSE(test_api.IsPendingDlpCheck()); |
| |
| // Wait for the file to be saved. |
| loop.Run(); |
| |
| ASSERT_EQ(events_.size(), 2u); |
| EXPECT_THAT( |
| events_[0], |
| data_controls::IsDlpPolicyEvent(data_controls::CreateDlpPolicyEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId, policy::DlpRulesManager::Level::kWarn))); |
| EXPECT_THAT( |
| events_[1], |
| data_controls::IsDlpPolicyEvent( |
| data_controls::CreateDlpPolicyWarningProceededEvent( |
| kSrcPattern, policy::DlpRulesManager::Restriction::kScreenshot, |
| kRuleName, kRuleId))); |
| } |
| |
| class CaptureModeSettingsBrowserTest : public extensions::ExtensionBrowserTest { |
| public: |
| CaptureModeSettingsBrowserTest() = default; |
| ~CaptureModeSettingsBrowserTest() override = default; |
| |
| // extensions::ExtensionBrowserTest: |
| void SetUpOnMainThread() override { |
| extensions::ExtensionBrowserTest::SetUpOnMainThread(); |
| CHECK(profile()); |
| file_manager::test::AddDefaultComponentExtensionsOnMainThread(profile()); |
| } |
| }; |
| |
| // Tests that the capture mode folder selection dialog window gets parented |
| // correctly when a browser window is available. |
| IN_PROC_BROWSER_TEST_F(CaptureModeSettingsBrowserTest, |
| FolderSelectionDialogParentedCorrectly) { |
| ASSERT_TRUE(browser()); |
| ash::CaptureModeTestApi test_api; |
| test_api.StartForFullscreen(/*for_video=*/false); |
| test_api.SimulateOpeningFolderSelectionDialog(); |
| auto* dialog_window = test_api.GetFolderSelectionDialogWindow(); |
| ASSERT_TRUE(dialog_window); |
| auto* transient_root = wm::GetTransientRoot(dialog_window); |
| ASSERT_TRUE(transient_root); |
| EXPECT_EQ(transient_root->GetId(), |
| ash::kShellWindowId_CaptureModeFolderSelectionDialogOwner); |
| EXPECT_NE(transient_root, browser()->window()->GetNativeWindow()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CaptureModeSettingsBrowserTest, |
| AudioCaptureDisabledByPolicy) { |
| ash::CaptureModeTestApi test_api; |
| test_api.SetAudioRecordingMode(ash::AudioRecordingMode::kMicrophone); |
| EXPECT_EQ(ash::AudioRecordingMode::kMicrophone, |
| test_api.GetEffectiveAudioRecordingMode()); |
| |
| auto* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs(); |
| prefs->SetBoolean(prefs::kAudioCaptureAllowed, false); |
| EXPECT_EQ(ash::AudioRecordingMode::kOff, |
| test_api.GetEffectiveAudioRecordingMode()); |
| prefs->SetBoolean(prefs::kAudioCaptureAllowed, true); |
| EXPECT_EQ(ash::AudioRecordingMode::kMicrophone, |
| test_api.GetEffectiveAudioRecordingMode()); |
| } |
| |
| // This test fixture tests the chromeos-linux path of camera video frames coming |
| // from the actual video_capture service using a fake camera device. It can only |
| // test the `kSharedMemory` buffer type. The `kGpuMemoryBuffer` type path cannot |
| // be tested here, as the `GpuMemoryBufferTracker` instance on chromeos attempts |
| // creating a `GpuMemoryBuffer` with the usage |
| // `VEA_READ_CAMERA_AND_CPU_READ_WRITE` which is not supported in a |
| // chromeos-linux environment. This path however is tested in ash_unittests. |
| class CaptureModeCameraBrowserTests : public InProcessBrowserTest { |
| public: |
| CaptureModeCameraBrowserTests() = default; |
| ~CaptureModeCameraBrowserTests() override = default; |
| |
| // InProcessBrowserTest: |
| void SetUpCommandLine(base::CommandLine* command_line) override { |
| // This command-line switch adds a single fake camera. |
| command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream); |
| } |
| |
| void SetUpOnMainThread() override { |
| ASSERT_EQ(1u, ash::WaitForCameraAvailabilityWithTimeout(base::Seconds(5))); |
| ash::CaptureModeTestApi test_api; |
| test_api.SelectCameraAtIndex(0); |
| } |
| |
| void WaitForAndVerifyRenderedVideoFrame() { |
| constexpr int kFramesToRender = 15; |
| for (int i = 0; i < kFramesToRender; ++i) { |
| base::RunLoop loop; |
| ash::CaptureModeTestApi().SetOnCameraVideoFrameRendered( |
| base::BindLambdaForTesting( |
| [&loop](scoped_refptr<media::VideoFrame> frame) { |
| ASSERT_TRUE(frame); |
| loop.Quit(); |
| })); |
| loop.Run(); |
| } |
| } |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(CaptureModeCameraBrowserTests, VerifyFrames) { |
| ash::CaptureModeTestApi().StartForFullscreen(/*for_video=*/true); |
| WaitForAndVerifyRenderedVideoFrame(); |
| } |
| |
| class CaptureModeProjectorBrowserTests : public CaptureModeCameraBrowserTests { |
| public: |
| CaptureModeProjectorBrowserTests() = default; |
| |
| ~CaptureModeProjectorBrowserTests() override = default; |
| |
| // InProcessBrowserTest: |
| void SetUpOnMainThread() override { |
| CaptureModeCameraBrowserTests::SetUpOnMainThread(); |
| auto* profile = browser()->profile(); |
| ash::SystemWebAppManager::GetForTest(profile) |
| ->InstallSystemAppsForTesting(); |
| |
| ui_test_utils::BrowserCreatedObserver browser_created_observer; |
| ash::ProjectorClient::Get()->OpenProjectorApp(); |
| browser_created_observer.Wait(); |
| |
| Browser* app_browser = |
| FindSystemWebAppBrowser(profile, ash::SystemWebAppType::PROJECTOR); |
| ASSERT_TRUE(app_browser); |
| } |
| |
| void SetUpCommandLine(base::CommandLine* command_line) override { |
| CaptureModeCameraBrowserTests::SetUpCommandLine(command_line); |
| command_line->AppendSwitch("--projector-extended-features-disabled"); |
| } |
| |
| void StartProjectorModeSession() { |
| auto* projector_session = ash::ProjectorSession::Get(); |
| EXPECT_FALSE(projector_session->is_active()); |
| ash::ProjectorController::Get()->StartProjectorSession( |
| base::SafeBaseName::Create("projector_data").value()); |
| EXPECT_TRUE(projector_session->is_active()); |
| EXPECT_TRUE(ash::CaptureModeTestApi().IsSessionActive()); |
| } |
| }; |
| |
| // Tests that the crash reported in https://crbug.com/1368903 is not happening. |
| IN_PROC_BROWSER_TEST_F(CaptureModeProjectorBrowserTests, |
| NoCrashWhenExitingSessionInWindowRecording) { |
| StartProjectorModeSession(); |
| ash::CaptureModeTestApi test_api; |
| ASSERT_TRUE(test_api.GetCameraPreviewWidget()); |
| test_api.SetCaptureModeSource(ash::CaptureModeSource::kWindow); |
| SendKeyEvent(browser(), ui::VKEY_ESCAPE); |
| EXPECT_FALSE(test_api.IsSessionActive()); |
| } |
| |
| class CaptureModeVideoConferenceBrowserTests |
| : public testing::WithParamInterface<bool>, |
| public CaptureModeCameraBrowserTests { |
| public: |
| CaptureModeVideoConferenceBrowserTests() |
| : is_share_screen_icon_enabled_(GetParam()) { |
| if (is_share_screen_icon_enabled_) { |
| scoped_feature_list_.InitWithFeatures( |
| /*enabled_features=*/{ash::features::kVcStopAllScreenShare, |
| ash::features:: |
| kFeatureManagementVideoConference}, |
| /*disabled_features=*/{}); |
| } else { |
| scoped_feature_list_.InitWithFeatures( |
| /*enabled_features=*/{ash::features:: |
| kFeatureManagementVideoConference}, |
| /*disabled_features=*/{}); |
| } |
| } |
| CaptureModeVideoConferenceBrowserTests( |
| const CaptureModeVideoConferenceBrowserTests&) = delete; |
| CaptureModeVideoConferenceBrowserTests& operator=( |
| const CaptureModeVideoConferenceBrowserTests&) = delete; |
| ~CaptureModeVideoConferenceBrowserTests() override = default; |
| |
| ash::VideoConferenceTray* video_conference_tray() { |
| return ash::StatusAreaWidgetTestHelper::GetStatusAreaWidget() |
| ->video_conference_tray(); |
| } |
| |
| ash::VideoConferenceTrayButton* vc_tray_camera_icon() { |
| return video_conference_tray()->camera_icon(); |
| } |
| |
| ash::VideoConferenceTrayButton* vc_tray_audio_icon() { |
| return video_conference_tray()->audio_icon(); |
| } |
| |
| ash::VideoConferenceTrayButton* vc_tray_screen_share_icon() { |
| return video_conference_tray()->screen_share_icon(); |
| } |
| |
| ash::VideoConferenceMediaState GetMediaStateInVideoConferenceManager() { |
| return ash::VideoConferenceManagerAsh::Get()->GetAggregatedState(); |
| } |
| |
| protected: |
| const bool is_share_screen_icon_enabled_; |
| |
| private: |
| base::test::ScopedFeatureList scoped_feature_list_; |
| }; |
| |
| INSTANTIATE_TEST_SUITE_P(, // Empty to simplify gtest output |
| CaptureModeVideoConferenceBrowserTests, |
| testing::Bool()); |
| |
| IN_PROC_BROWSER_TEST_P(CaptureModeVideoConferenceBrowserTests, |
| ManagerGetsUpdated) { |
| // Test the initial state. |
| ash::VideoConferenceMediaState state = |
| GetMediaStateInVideoConferenceManager(); |
| EXPECT_FALSE(state.has_media_app); |
| EXPECT_FALSE(state.has_camera_permission); |
| EXPECT_FALSE(state.has_microphone_permission); |
| EXPECT_FALSE(state.is_capturing_camera); |
| EXPECT_FALSE(state.is_capturing_microphone); |
| EXPECT_FALSE(state.is_capturing_screen); |
| |
| // Start recording with microphone and camera turned on. |
| ash::CaptureModeTestApi test_api; |
| test_api.SetAudioRecordingMode(ash::AudioRecordingMode::kMicrophone); |
| test_api.StartForFullscreen(/*for_video=*/true); |
| test_api.PerformCapture(); |
| EXPECT_TRUE(test_api.IsVideoRecordingInProgress()); |
| EXPECT_TRUE(test_api.GetCameraPreviewWidget()); |
| |
| state = GetMediaStateInVideoConferenceManager(); |
| EXPECT_TRUE(state.has_media_app); |
| EXPECT_TRUE(state.has_camera_permission); |
| EXPECT_TRUE(state.has_microphone_permission); |
| EXPECT_TRUE(state.is_capturing_camera); |
| EXPECT_TRUE(state.is_capturing_microphone); |
| EXPECT_FALSE(state.is_capturing_screen); |
| |
| EXPECT_TRUE(video_conference_tray()->GetVisible()); |
| EXPECT_TRUE(vc_tray_audio_icon()->GetVisible()); |
| EXPECT_TRUE(vc_tray_camera_icon()->GetVisible()); |
| EXPECT_TRUE(!is_share_screen_icon_enabled_ || |
| !vc_tray_screen_share_icon()->GetVisible()); |
| |
| // Stop recording and expect the state to return back to the initial state, |
| // and the VC tray buttons should be hidden. |
| base::RunLoop loop; |
| SetupLoopToWaitForCaptureFileToBeSaved(&loop); |
| test_api.StopVideoRecording(); |
| loop.Run(); |
| |
| state = GetMediaStateInVideoConferenceManager(); |
| EXPECT_FALSE(state.has_media_app); |
| EXPECT_FALSE(state.has_camera_permission); |
| EXPECT_FALSE(state.has_microphone_permission); |
| EXPECT_FALSE(state.is_capturing_camera); |
| EXPECT_FALSE(state.is_capturing_microphone); |
| EXPECT_FALSE(state.is_capturing_screen); |
| |
| EXPECT_FALSE(video_conference_tray()->GetVisible()); |
| EXPECT_FALSE(vc_tray_audio_icon()->GetVisible()); |
| EXPECT_FALSE(vc_tray_camera_icon()->GetVisible()); |
| EXPECT_TRUE(!is_share_screen_icon_enabled_ || |
| !vc_tray_screen_share_icon()->GetVisible()); |
| } |
| |
| // Tests that the capture is saved to policy defined location if feature is |
| // enabled. Received a param on whether to test video or image capture and |
| // another param on whether the feature is enabled or not. |
| class CaptureModePolicyBrowserTest |
| : public testing::WithParamInterface<std::pair<bool, bool>>, |
| public policy::PolicyTest { |
| public: |
| CaptureModePolicyBrowserTest() |
| : for_video_(GetParam().first), skyvault_enabled_(GetParam().second) { |
| if (skyvault_enabled_) { |
| scoped_feature_list_.InitAndEnableFeature(features::kSkyVault); |
| } else { |
| scoped_feature_list_.InitAndDisableFeature(features::kSkyVault); |
| } |
| } |
| |
| protected: |
| bool for_video_, skyvault_enabled_; |
| |
| private: |
| base::test::ScopedFeatureList scoped_feature_list_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_P(CaptureModePolicyBrowserTest, |
| ScreenCaptureLocationPolicy) { |
| ASSERT_TRUE(browser()); |
| // Start the session before a window becomes restricted. |
| ash::CaptureModeTestApi test_api; |
| |
| test_api.StartForFullscreen(for_video_); |
| ASSERT_TRUE(test_api.IsSessionActive()); |
| { |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| base::ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| policy::PolicyMap policies; |
| SetPolicy(&policies, policy::key::kScreenCaptureLocation, |
| base::Value(temp_dir.GetPath().value())); |
| UpdateProviderPolicy(policies); |
| |
| // Set up a waiter to wait for the file to be saved. |
| base::test::TestFuture<const base::FilePath&> path_future; |
| test_api.SetOnCaptureFileSavedCallback(path_future.GetCallback()); |
| |
| test_api.PerformCapture(); |
| |
| if (for_video_) { |
| // Explicitly waiting for video capture to start as it might |
| // asynchronously check custom destination folder. |
| if (!test_api.IsVideoRecordingInProgress()) { |
| base::RunLoop run_loop; |
| test_api.SetOnVideoRecordingStartedCallback(run_loop.QuitClosure()); |
| run_loop.Run(); |
| } |
| // Wait while the file location is checked. |
| test_api.FlushRecordingServiceForTesting(); |
| test_api.StopVideoRecording(); |
| } |
| |
| // If SkyVault enabled - the file is saved |
| // to the policy dir, otherwise to the default downloads folder. |
| const base::FilePath expected_location = |
| skyvault_enabled_ |
| ? temp_dir.GetPath() |
| : DownloadPrefs::FromBrowserContext(browser()->profile()) |
| ->GetDefaultDownloadDirectoryForProfile(); |
| // Wait for the file to be saved. |
| EXPECT_TRUE(expected_location.IsParent(path_future.Get())); |
| } |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(, // Empty to simplify gtest output |
| CaptureModePolicyBrowserTest, |
| testing::ValuesIn({ |
| std::make_pair(true, true), |
| std::make_pair(true, false), |
| std::make_pair(false, true), |
| std::make_pair(false, false), |
| })); |