1# Copyright 2014 The Chromium 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"""Finds iOS browsers that can be controlled by telemetry.""" 6 7import logging 8import re 9 10from telemetry.core import platform 11from telemetry.internal.backends.chrome import ios_browser_backend 12from telemetry.internal.backends.chrome_inspector import inspector_backend 13from telemetry.internal.browser import browser 14from telemetry.internal.browser import possible_browser 15from telemetry.internal.platform import ios_device 16from telemetry.internal.platform import ios_platform_backend 17 18 19# Key matches output from ios-webkit-debug-proxy and the value is a readable 20# description of the browser. 21IOS_BROWSERS = {'CriOS': 'ios-chrome', 'Version': 'ios-safari'} 22DEVICE_LIST_URL = 'http://127.0.0.1:9221/json' 23IOS_WEBKIT_DEBUG_PROXY = 'ios_webkit_debug_proxy' 24 25 26class PossibleIOSBrowser(possible_browser.PossibleBrowser): 27 28 """A running iOS browser instance.""" 29 def __init__(self, browser_type, _): 30 super(PossibleIOSBrowser, self).__init__(browser_type, 'ios', True) 31 32 # TODO(baxley): Implement the following methods for iOS. 33 def Create(self, finder_options): 34 browser_backend = ios_browser_backend.IosBrowserBackend( 35 self._platform_backend, finder_options.browser_options) 36 return browser.Browser( 37 browser_backend, self._platform_backend, self._credentials_path) 38 39 def SupportsOptions(self, finder_options): 40 #TODO(baxley): Implement me. 41 return True 42 43 def UpdateExecutableIfNeeded(self): 44 #TODO(baxley): Implement me. 45 pass 46 47 def _InitPlatformIfNeeded(self): 48 if self._platform: 49 return 50 51 self._platform_backend = ios_platform_backend.IosPlatformBackend() 52 self._platform = platform.Platform(self._platform_backend) 53 54def SelectDefaultBrowser(_): 55 return None # TODO(baxley): Implement me. 56 57 58def CanFindAvailableBrowsers(): 59 # TODO(baxley): Add support for all platforms possible. Probably Linux, 60 # probably not Windows. 61 return platform.GetHostPlatform().GetOSName() == 'mac' 62 63 64def FindAllBrowserTypes(_): 65 return IOS_BROWSERS.values() 66 67 68def FindAllAvailableBrowsers(finder_options, device): 69 """Find all running iOS browsers on connected devices.""" 70 if not isinstance(device, ios_device.IOSDevice): 71 return [] 72 73 if not CanFindAvailableBrowsers(): 74 return [] 75 76 options = finder_options.browser_options 77 78 options.browser_type = 'ios-chrome' 79 host = platform.GetHostPlatform() 80 backend = ios_browser_backend.IosBrowserBackend(host, options) 81 # TODO(baxley): Use idevice to wake up device or log debug statement. 82 if not host.IsApplicationRunning(IOS_WEBKIT_DEBUG_PROXY): 83 host.LaunchApplication(IOS_WEBKIT_DEBUG_PROXY) 84 if not host.IsApplicationRunning(IOS_WEBKIT_DEBUG_PROXY): 85 return [] 86 87 device_urls = backend.GetDeviceUrls() 88 if not device_urls: 89 logging.debug('Could not find any devices over %s.' 90 % IOS_WEBKIT_DEBUG_PROXY) 91 return [] 92 93 debug_urls = backend.GetWebSocketDebuggerUrls(device_urls) 94 95 # Get the userAgent for each UIWebView to find the browsers. 96 browser_pattern = (r'\)\s(%s)\/(\d+[\.\d]*)\sMobile' 97 % '|'.join(IOS_BROWSERS.keys())) 98 browser_types = set() 99 for url in debug_urls: 100 context = {'webSocketDebuggerUrl': url, 'id': 1} 101 try: 102 inspector = inspector_backend.InspectorBackend( 103 backend.app, backend.devtools_client, context) 104 res = inspector.EvaluateJavaScript("navigator.userAgent") 105 finally: 106 inspector.Disconnect() 107 match_browsers = re.search(browser_pattern, res) 108 if match_browsers: 109 browser_types.add(match_browsers.group(1)) 110 111 browsers = [] 112 for browser_type in browser_types: 113 browsers.append(PossibleIOSBrowser(IOS_BROWSERS[browser_type], 114 finder_options)) 115 return list(browsers) 116