1# Copyright 2015 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""A module providing common resources for different facades.""" 6 7import exceptions 8 9from autotest_lib.client.common_lib.cros import chrome 10from autotest_lib.client.common_lib.cros import retry 11from autotest_lib.client.cros import constants 12 13_FLAKY_CALL_RETRY_TIMEOUT_SEC = 60 14_FLAKY_CHROME_CALL_RETRY_DELAY_SEC = 1 15 16retry_chrome_call = retry.retry( 17 (chrome.Error, exceptions.IndexError, exceptions.Exception), 18 timeout_min=_FLAKY_CALL_RETRY_TIMEOUT_SEC / 60.0, 19 delay_sec=_FLAKY_CHROME_CALL_RETRY_DELAY_SEC) 20 21class FacadeResource(object): 22 """This class provides access to telemetry chrome wrapper.""" 23 24 EXTRA_BROWSER_ARGS = ['--enable-gpu-benchmarking'] 25 26 def __init__(self, chrome_object=None, restart=False): 27 """Initializes a FacadeResource. 28 29 @param chrome_object: A chrome.Chrome object or None. 30 @param restart: Preserve the previous browser state. 31 32 """ 33 if chrome_object: 34 self._chrome = chrome_object 35 else: 36 self._chrome = chrome.Chrome( 37 extension_paths=[constants.MULTIMEDIA_TEST_EXTENSION], 38 extra_browser_args=self.EXTRA_BROWSER_ARGS, 39 clear_enterprise_policy=not restart, 40 autotest_ext=True) 41 self._browser = self._chrome.browser 42 # The opened tabs are stored by tab descriptors. 43 # Key is the tab descriptor string. 44 # We use string as the key because of RPC Call. Client can use the 45 # string to locate the tab object. 46 # Value is the tab object. 47 self._tabs = dict() 48 49 50 def close(self): 51 """Closes Chrome.""" 52 self._chrome.close() 53 54 55 def __enter__(self): 56 return self 57 58 59 def __exit__(self, *args): 60 self.close() 61 62 63 @retry_chrome_call 64 def get_extension(self, extension_path=None): 65 """Gets the extension from the indicated path. 66 67 @param extension_path: the path of the target extension. 68 Set to None to get autotest extension. 69 Defaults to None. 70 @return an extension object. 71 72 @raise RuntimeError if the extension is not found. 73 @raise chrome.Error if the found extension has not yet been 74 retrieved succesfully. 75 76 """ 77 try: 78 if extension_path is None: 79 extension = self._chrome.autotest_ext 80 else: 81 extension = self._chrome.get_extension(extension_path) 82 except KeyError, errmsg: 83 # Trigger retry_chrome_call to retry to retrieve the 84 # found extension. 85 raise chrome.Error(errmsg) 86 if not extension: 87 if extension_path is None: 88 raise RuntimeError('Autotest extension not found') 89 else: 90 raise RuntimeError('Extension not found in %r' 91 % extension_path) 92 return extension 93 94 95 @retry_chrome_call 96 def load_url(self, url): 97 """Loads the given url in a new tab. The new tab will be active. 98 99 @param url: The url to load as a string. 100 @return a str, the tab descriptor of the opened tab. 101 102 """ 103 tab = self._browser.tabs.New() 104 tab.Navigate(url) 105 tab.Activate() 106 tab_descriptor = hex(id(tab)) 107 self._tabs[tab_descriptor] = tab 108 return tab_descriptor 109 110 111 def get_tabs(self): 112 """Gets the tabs opened by browser. 113 114 @returns: The tabs attribute in telemetry browser object. 115 116 """ 117 return self._browser.tabs 118 119 120 def get_tab_by_descriptor(self, tab_descriptor): 121 """Gets the tab by the tab descriptor. 122 123 @returns: The tab object indicated by the tab descriptor. 124 125 """ 126 return self._tabs[tab_descriptor] 127 128 129 @retry_chrome_call 130 def close_tab(self, tab_descriptor): 131 """Closes the tab. 132 133 @param tab_descriptor: Indicate which tab to be closed. 134 135 """ 136 if tab_descriptor not in self._tabs: 137 raise RuntimeError('There is no tab for %s' % tab_descriptor) 138 tab = self._tabs[tab_descriptor] 139 del self._tabs[tab_descriptor] 140 tab.Close() 141