blob: 6fd09063bcac7c7546b954e5990d49a4c636fa2d [file] [log] [blame]
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import glob
import logging
import os
import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.cros.enterprise import enterprise_policy_base
from autotest_lib.client.cros.input_playback import input_playback
POLL_TIMEOUT = 5
POLL_FREQUENCY = 0.5
class policy_DisableScreenshots(
enterprise_policy_base.EnterprisePolicyTest):
version = 1
def initialize(self, **kwargs):
"""Emulate a keyboard in order to play back the screenshot shortcut."""
self._initialize_test_constants()
super(policy_DisableScreenshots, self).initialize(**kwargs)
self.player = input_playback.InputPlayback()
self.player.emulate(input_type='keyboard')
self.player.find_connected_inputs()
def _initialize_test_constants(self):
"""Initialize test-specific constants, some from class constants."""
self.POLICY_NAME = 'DisableScreenshots'
self._DOWNLOADS = '/home/chronos/user/Downloads/'
self._SCREENSHOT_PATTERN = 'Screenshot*'
self._SCREENSHOT_FILENAME = self._DOWNLOADS + self._SCREENSHOT_PATTERN
self.TEST_CASES = {
'DisableScreenshot_Block': True,
'False_Allow': False,
'NotSet_Allow': None
}
# Possible API methods to capture the screen
self.CAPTURE_CMDS = [
'captureVisibleTab',
# TODO(timkovich): https://crbug.com/839630
# 'tabCapture',
# TODO(timkovich): https://crbug.com/817497
# 'desktopCapture'
]
def _screenshot_file_exists(self):
"""
Checks if screenshot file was created by keyboard shortcut.
@returns boolean indicating if screenshot file was saved or not.
"""
try:
utils.poll_for_condition(
lambda: len(glob.glob(self._SCREENSHOT_FILENAME)) > 0,
timeout=POLL_TIMEOUT,
sleep_interval=POLL_FREQUENCY)
except utils.TimeoutError:
logging.info('Screenshot file not found.')
return False
logging.info('Screenshot file found.')
return True
def _delete_screenshot_files(self):
"""Delete existing screenshot files, if any."""
for filename in glob.glob(self._SCREENSHOT_FILENAME):
os.remove(filename)
def cleanup(self):
"""Cleanup files created in this test, if any and close the player."""
self._delete_screenshot_files()
self.player.close()
super(policy_DisableScreenshots, self).cleanup()
def _test_screenshot_shortcut(self, policy_value):
"""
Verify DisableScreenshots is enforced for the screenshot shortcut.
When DisableScreenshots policy value is undefined, screenshots shall
be captured via the keyboard shortcut Ctrl + F5.
When DisableScreenshots policy is set to True screenshots shall not
be captured.
@param policy_value: policy value for this case.
"""
logging.info('Deleting preexisting Screenshot files.')
self._delete_screenshot_files()
# Keyboard shortcut for screenshots
self.player.blocking_playback_of_default_file(
input_type='keyboard', filename='keyboard_ctrl+f5')
screenshot_file_captured = self._screenshot_file_exists()
if policy_value:
if screenshot_file_captured:
raise error.TestFail('Screenshot should not be captured')
elif not screenshot_file_captured:
raise error.TestFail('Screenshot should be captured')
def _test_screenshot_apis(self, policy_value):
"""
Verify DisableScreenshot policy blocks API calls.
Attempts to capture the screen using all of the methods to capture
the screen through the APIs. Captures should not happen when
policy_value is True and should happen in the other cases.
@param policy_value: policy value for this case
@raises error.TestFail: In the case where the capture behavior
does not match the policy value
"""
tab = self.navigate_to_url('https://google.com')
current_dir = os.path.dirname(os.path.realpath(__file__))
for method in self.CAPTURE_CMDS:
# Set the document.title to the test name
tab.ExecuteJavaScript('document.title = "%s"' % method)
# Call the extension's shortcut to trigger the API call
self.player.blocking_playback(
input_type='keyboard',
filepath=os.path.join(current_dir, 'keyboard_ctrl+shift+y'))
# desktopCapture opens a prompt window that needs to be OKed
if method == 'desktopCapture':
self.player.blocking_playback_of_default_file(
input_type='keyboard', filename='keyboard_enter')
# The document.title is used to pass information to and from
# the DOM and the extension. The return value of the screenshot
# API call is set to the document.title.
try:
utils.poll_for_condition(
lambda: tab.EvaluateJavaScript(
'document.title != "%s"' % method
),
timeout=POLL_TIMEOUT)
capture = tab.EvaluateJavaScript('document.title')
except utils.TimeoutError:
capture = None
if capture == 'undefined':
capture = None
if policy_value:
if capture is not None:
raise error.TestFail('Screen should not be captured. '
'method = %s, capture = %s'
% (method, capture))
elif capture is None:
raise error.TestFail('Screen should be captured. '
'method = %s, capture = %s'
% (method, capture))
def run_once(self, case):
"""
Setup and run the test configured for the specified test case.
@param case: Name of the test case to run.
"""
case_value = self.TEST_CASES[case]
self._extension_path = os.path.join(os.path.dirname(__file__),
'Screenshooter')
self.setup_case(user_policies={self.POLICY_NAME: case_value},
extension_paths=[self._extension_path])
self._test_screenshot_shortcut(case_value)
self._test_screenshot_apis(case_value)