146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)# Copyright 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from telemetry import decorators 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import browser_credentials 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)from telemetry.core import exceptions 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import extension_dict 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from telemetry.core import local_server 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from telemetry.core import memory_cache_http_server 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import tab_list 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import wpr_modes 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import wpr_server 16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)from telemetry.core.backends import browser_backend 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Browser(object): 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """A running browser instance that can be controlled in a limited way. 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) To create a browser instance, use browser_finder.FindBrowser. 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Be sure to clean up after yourself by calling Close() when you are done with 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) the browser. Or better yet: 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_to_create = FindBrowser(options) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) with browser_to_create.Create() as browser: 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ... do all your operations on browser here 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci def __init__(self, backend, platform_backend, archive_path, 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci append_to_existing_wpr, make_javascript_deterministic, 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci credentials_path): 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assert platform_backend.platform != None 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._browser_backend = backend 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._platform_backend = platform_backend 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._wpr_server = None 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._local_server_controller = local_server.LocalServerController(backend) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._tabs = tab_list.TabList(backend.tab_list_backend) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.credentials = browser_credentials.BrowserCredentials() 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.credentials.credentials_path = credentials_path 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._platform_backend.DidCreateBrowser(self, self._browser_backend) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.SetReplayArchivePath(archive_path, 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci append_to_existing_wpr, 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci make_javascript_deterministic) 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_options = self._browser_backend.browser_options 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.platform.FlushDnsCache() 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if browser_options.clear_sytem_cache_for_browser_and_profile_on_start: 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if self.platform.CanFlushIndividualFilesFromSystemCache(): 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.platform.FlushSystemCacheForDirectory( 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self._browser_backend.profile_directory) 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.platform.FlushSystemCacheForDirectory( 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self._browser_backend.browser_directory) 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else: 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.platform.FlushEntireSystemCache() 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self._browser_backend.SetBrowser(self) 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self._browser_backend.Start() 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self._platform_backend.DidStartBrowser(self, self._browser_backend) 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __enter__(self): 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __exit__(self, *args): 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.Close() 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def platform(self): 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self._platform_backend.platform 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def browser_type(self): 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._browser_backend.browser_type 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def supports_extensions(self): 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._browser_backend.supports_extensions 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def supports_tab_control(self): 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._browser_backend.supports_tab_control 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def synthetic_gesture_source_type(self): 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self._browser_backend.browser_options.synthetic_gesture_source_type 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) @property 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def tabs(self): 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._tabs 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def foreground_tab(self): 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for i in xrange(len(self._tabs)): 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # The foreground tab is the first (only) one that isn't hidden. 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # This only works through luck on Android, due to crbug.com/322544 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # which means that tabs that have never been in the foreground return 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # document.hidden as false; however in current code the Android foreground 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # tab is always tab 0, which will be the first one that isn't hidden 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._tabs[i].EvaluateJavaScript('!document.hidden'): 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self._tabs[i] 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise Exception("No foreground tab found") 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) @property 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @decorators.Cache 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def extensions(self): 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not self.supports_extensions: 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise browser_backend.ExtensionsNotSupportedException( 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'Extensions not supported') 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return extension_dict.ExtensionDict(self._browser_backend.extension_backend) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 113a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def _GetStatsCommon(self, pid_stats_function): 114a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) browser_pid = self._browser_backend.pid 115a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) result = { 116a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 'Browser': dict(pid_stats_function(browser_pid), **{'ProcessCount': 1}), 117a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 'Renderer': {'ProcessCount': 0}, 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'Gpu': {'ProcessCount': 0}, 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'Other': {'ProcessCount': 0} 120a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) process_count = 1 122a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) for child_pid in self._platform_backend.GetChildPids(browser_pid): 123a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) try: 124a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) child_cmd_line = self._platform_backend.GetCommandLine(child_pid) 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) child_stats = pid_stats_function(child_pid) 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) except exceptions.ProcessGoneException: 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # It is perfectly fine for a process to have gone away between calling 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # GetChildPids() and then further examining it. 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) child_process_name = self._browser_backend.GetProcessName(child_cmd_line) 131a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) process_name_type_key_map = {'gpu-process': 'Gpu', 'renderer': 'Renderer'} 132a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if child_process_name in process_name_type_key_map: 133a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) child_process_type_key = process_name_type_key_map[child_process_name] 134a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) else: 135a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) # TODO: identify other process types (zygote, plugin, etc), instead of 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # lumping them in a single category. 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) child_process_type_key = 'Other' 138a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) result[child_process_type_key]['ProcessCount'] += 1 139a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) for k, v in child_stats.iteritems(): 140a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if k in result[child_process_type_key]: 141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) result[child_process_type_key][k] += v 142a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) else: 143a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) result[child_process_type_key][k] = v 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) process_count += 1 145a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) for v in result.itervalues(): 146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if v['ProcessCount'] > 1: 147a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) for k in v.keys(): 148a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if k.endswith('Peak'): 149a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) del v[k] 150a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) del v['ProcessCount'] 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) result['ProcessCount'] = process_count 152a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return result 153a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def memory_stats(self): 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Returns a dict of memory statistics for the browser: 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 'Browser': { 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'VM': R, 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'VMPeak': S, 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'WorkingSetSize': T, 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'WorkingSetSizePeak': U, 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'ProportionalSetSize': V, 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'PrivateDirty': W 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 165a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 'Gpu': { 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'VM': R, 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'VMPeak': S, 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'WorkingSetSize': T, 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'WorkingSetSizePeak': U, 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'ProportionalSetSize': V, 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'PrivateDirty': W 172a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) }, 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'Renderer': { 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'VM': R, 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'VMPeak': S, 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'WorkingSetSize': T, 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'WorkingSetSizePeak': U, 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'ProportionalSetSize': V, 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'PrivateDirty': W 180a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) }, 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'SystemCommitCharge': X, 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'SystemTotalPhysicalMemory': Y, 183a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 'ProcessCount': Z, 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Any of the above keys may be missing on a per-platform basis. 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._platform_backend.PurgeUnpinnedMemory() 188a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) result = self._GetStatsCommon(self._platform_backend.GetMemoryStats) 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) commit_charge = self._platform_backend.GetSystemCommitCharge() 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if commit_charge: 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result['SystemCommitCharge'] = commit_charge 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) total = self._platform_backend.GetSystemTotalPhysicalMemory() 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if total: 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result['SystemTotalPhysicalMemory'] = total 195a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return result 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def cpu_stats(self): 19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) """Returns a dict of cpu statistics for the system. 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { 'Browser': { 20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'CpuProcessTime': S, 20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'TotalTime': T 20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }, 20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'Gpu': { 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'CpuProcessTime': S, 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'TotalTime': T 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }, 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'Renderer': { 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'CpuProcessTime': S, 21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'TotalTime': T 21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Any of the above keys may be missing on a per-platform basis. 21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) """ 21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) result = self._GetStatsCommon(self._platform_backend.GetCpuStats) 21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) del result['ProcessCount'] 21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) # We want a single time value, not the sum for all processes. 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cpu_timestamp = self._platform_backend.GetCpuTimestamp() 22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for process_type in result: 22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) # Skip any process_types that are empty 22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if not len(result[process_type]): 22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) continue 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) result[process_type].update(cpu_timestamp) 22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return result 22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) @property 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def io_stats(self): 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Returns a dict of IO statistics for the browser: 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 'Browser': { 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'ReadOperationCount': W, 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'WriteOperationCount': X, 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'ReadTransferCount': Y, 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'WriteTransferCount': Z 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 'Gpu': { 237a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 'ReadOperationCount': W, 238a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 'WriteOperationCount': X, 239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 'ReadTransferCount': Y, 240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 'WriteTransferCount': Z 241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) }, 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'Renderer': { 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'ReadOperationCount': W, 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'WriteOperationCount': X, 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'ReadTransferCount': Y, 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'WriteTransferCount': Z 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 250a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) result = self._GetStatsCommon(self._platform_backend.GetIOStats) 251a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) del result['ProcessCount'] 252a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return result 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def Close(self): 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Closes this browser.""" 2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self._browser_backend.IsBrowserRunning(): 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._platform_backend.WillCloseBrowser(self, self._browser_backend) 2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._wpr_server: 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._wpr_server.Close() 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._wpr_server = None 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._local_server_controller.Close() 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._browser_backend.Close() 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.credentials = None 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def http_server(self): 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self._local_server_controller.GetRunningServer( 2706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) memory_cache_http_server.MemoryCacheHTTPServer, None) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def SetHTTPServerDirectories(self, paths): 2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) """Returns True if the HTTP server was started, False otherwise.""" 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if isinstance(paths, basestring): 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) paths = set([paths]) 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) paths = set(os.path.realpath(p) for p in paths) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) # If any path is in a subdirectory of another, remove the subdirectory. 2798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) duplicates = set() 2808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for parent_path in paths: 2818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for sub_path in paths: 2828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if parent_path == sub_path: 2838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) continue 2848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if os.path.commonprefix((parent_path, sub_path)) == parent_path: 2858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) duplicates.add(sub_path) 2868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) paths -= duplicates 2878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.http_server: 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if paths and self.http_server.paths == paths: 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return False 2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.http_server.Close() 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not paths: 2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return False 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) server = memory_cache_http_server.MemoryCacheHTTPServer(paths) 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.StartLocalServer(server) 2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return True 3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def StartLocalServer(self, server): 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Starts a LocalServer and associates it with this browser. 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) It will be closed when the browser closes. 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._local_server_controller.StartServer(server) 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) @property 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def local_servers(self): 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Returns the currently running local servers.""" 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self._local_server_controller.local_servers 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def SetReplayArchivePath(self, archive_path, append_to_existing_wpr=False, 3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch make_javascript_deterministic=True): 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._wpr_server: 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._wpr_server.Close() 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._wpr_server = None 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not archive_path: 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return None 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._browser_backend.wpr_mode == wpr_modes.WPR_OFF: 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) use_record_mode = self._browser_backend.wpr_mode == wpr_modes.WPR_RECORD 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not use_record_mode: 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert os.path.isfile(archive_path) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._wpr_server = wpr_server.ReplayServer( 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._browser_backend, 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) archive_path, 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) use_record_mode, 3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) append_to_existing_wpr, 33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) make_javascript_deterministic) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def GetStandardOutput(self): 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._browser_backend.GetStandardOutput() 3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def GetStackTrace(self): 3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return self._browser_backend.GetStackTrace() 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @property 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def supports_system_info(self): 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return self._browser_backend.supports_system_info 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def GetSystemInfo(self): 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) """Returns low-level information about the system, if available. 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) See the documentation of the SystemInfo class for more details.""" 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return self._browser_backend.GetSystemInfo() 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # TODO: Remove after call to Start() has been removed from 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # related authotest files. 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci def Start(self): 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pass 356