Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / backends / chrome / ios_browser_finder.py
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
7 import contextlib
8 import json
9 import logging
10 import re
11 import subprocess
12 import urllib2
13
14 from telemetry.core import platform
15 from telemetry.core import possible_browser
16 from telemetry.core import util
17 from telemetry.core.backends.chrome import inspector_backend
18
19
20 class PossibleIOSBrowser(possible_browser.PossibleBrowser):
21
22   """A running iOS browser instance."""
23   def __init__(self, browser_type, finder_options):
24     super(PossibleIOSBrowser, self).__init__(browser_type, 'ios',
25         finder_options, True)
26
27   # TODO(baxley): Implement the following methods for iOS.
28   def Create(self):
29     raise NotImplementedError()
30
31   def SupportOptions(self, finder_options):
32     raise NotImplementedError()
33
34 # Key matches output from ios-webkit-debug-proxy and the value is a readable
35 # description of the browser.
36 IOS_BROWSERS = {'CriOS': 'ios-chrome', 'Version': 'ios-safari'}
37
38 DEVICE_LIST_URL = 'http://127.0.0.1:9221/json'
39
40 IOS_WEBKIT_DEBUG_PROXY = 'ios_webkit_debug_proxy'
41
42
43 def SelectDefaultBrowser(_):
44   return None  # TODO(baxley): Implement me.
45
46
47 def CanFindAvailableBrowsers():
48   return False  # TODO(baxley): Implement me.
49
50
51 def FindAllBrowserTypes():
52   return IOS_BROWSERS.values()
53
54
55 def FindAllAvailableBrowsers(finder_options):
56   """Find all running iOS browsers on connected devices."""
57   ios_device_attached = False
58   host = platform.GetHostPlatform()
59   if host.GetOSName() == 'mac':
60     devices = subprocess.check_output(
61         'system_profiler SPUSBDataType', shell=True)
62     ios_devices = 'iPod|iPhone|iPad'
63     for line in devices.split('\n'):
64       if line:
65         m = re.match('\s*(%s):' % ios_devices, line)
66         if m:
67           ios_device_attached = True
68           break
69   else:
70     # TODO(baxley): Add support for all platforms possible. Probably Linux,
71     # probably not Windows.
72     return []
73
74   if ios_device_attached:
75     # TODO(baxley) Use idevice to wake up device or log debug statement.
76     if not host.IsApplicationRunning(IOS_WEBKIT_DEBUG_PROXY):
77       host.LaunchApplication(IOS_WEBKIT_DEBUG_PROXY)
78       if not host.IsApplicationRunning(IOS_WEBKIT_DEBUG_PROXY):
79         return []
80   else:
81     return []
82
83   try:
84     # TODO(baxley): Refactor this into a backend file.
85     with contextlib.closing(
86         urllib2.urlopen(DEVICE_LIST_URL), timeout=10) as device_list:
87       json_urls = device_list.read()
88     device_urls = json.loads(json_urls)
89     if not device_urls:
90       logging.debug('No iOS devices found. Will not try searching for iOS '
91                     'browsers.')
92       return []
93   except urllib2.URLError as e:
94     logging.error('Error communicating with devices over %s.'
95                   % IOS_WEBKIT_DEBUG_PROXY)
96     logging.error(str(e))
97     return []
98
99   # TODO(baxley): Move to ios-webkit-debug-proxy command class, similar
100   # to GetAttachedDevices() in adb_commands.
101   data = []
102   # Loop through all devices.
103   for d in device_urls:
104     # Retry a few times since it can take a few seconds for this API to be
105     # ready, if ios_webkit_debug_proxy is just launched.
106     def GetData():
107       try:
108         with contextlib.closing(
109             urllib2.urlopen('http://%s/json' % d['url']), timeout=10) as f:
110           json_result = f.read()
111         data = json.loads(json_result)
112         return data
113       except urllib2.URLError as e:
114         logging.error('Error communicating with device over %s.'
115                       % IOS_WEBKIT_DEBUG_PROXY)
116         logging.error(str(e))
117         return False
118     try:
119       data = util.WaitFor(GetData, 5)
120     except util.TimeoutException as e:
121       return []
122
123   # Find all running UIWebViews.
124   debug_urls = []
125   for j in data:
126     debug_urls.append(j['webSocketDebuggerUrl'])
127
128   # Get the userAgent for each UIWebView to find the browsers.
129   browser_pattern = ('\)\s(%s)\/(\d+[\.\d]*)\sMobile'
130                      % '|'.join(IOS_BROWSERS.keys()))
131   browsers = []
132   for url in debug_urls:
133     context = {'webSocketDebuggerUrl':url , 'id':1}
134     # TODO(baxley): Replace None with ios_browser_backend, once implemented.
135     inspector_alt = inspector_backend.InspectorBackend(None, context)
136     res = inspector_alt.EvaluateJavaScript("navigator.userAgent")
137     match_browsers = re.search(browser_pattern, res)
138     if match_browsers:
139       browsers.append(PossibleIOSBrowser(IOS_BROWSERS[match_browsers.group(1)],
140                                          finder_options))
141
142   return browsers