| #!/usr/bin/env python3 |
| # Copyright 2014 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Embeds standalone JavaScript snippets in C++ code. |
| |
| The script requires the Source/devtools/front_end/emulated_devices/module.json |
| file from Blink that lists the known mobile devices to be passed in as the only |
| argument. The list of known devices will be written to a C-style string to be |
| parsed with JSONReader. |
| """ |
| |
| import ast |
| import json |
| import optparse |
| import os |
| import sys |
| |
| import chrome_paths |
| import cpp_source |
| |
| _EMULATED_DEVICES_BEGIN = '// DEVICE-LIST-BEGIN' |
| _EMULATED_DEVICES_END = '// DEVICE-LIST-END' |
| _EMULATED_DEVICES_IF = '/* DEVICE-LIST-IF-JS */' |
| _EMULATED_DEVICES_ELSE = '/* DEVICE-LIST-ELSE' |
| _EMULATED_DEVICES_ENDIF = 'DEVICE-LIST-END-IF */' |
| |
| def main(): |
| parser = optparse.OptionParser() |
| parser.add_option( |
| '', '--version-file', type='string', |
| default=os.path.join(chrome_paths.GetSrc(), 'chrome', 'VERSION'), |
| help='Path to Chrome version file') |
| parser.add_option( |
| '', '--directory', type='string', default='.', |
| help='Path to directory where the cc/h files should be created') |
| options, args = parser.parse_args() |
| |
| # The device userAgent string may contain '%s', which should be replaced with |
| # current Chrome version. First we read the version file. |
| version_parts = ['MAJOR', 'MINOR', 'BUILD', 'PATCH'] |
| version = [] |
| version_file = open(options.version_file, 'r', encoding='utf-8') |
| for part in version_parts: |
| # The version file should have 4 lines, with format like MAJOR=63 |
| components = version_file.readline().split('=') |
| if len(components) != 2 or components[0].strip() != part: |
| print('Bad version file') |
| return 1 |
| version.append(components[1].strip()) |
| # Join parts of version together using '.' as separator |
| version = '.'.join(version) |
| |
| devices = {} |
| file_name = args[0] |
| with open(file_name, 'r', encoding='utf-8') as f: |
| data = f.read() |
| |
| # Extract the list from the source file. |
| begin_position = data.find(_EMULATED_DEVICES_BEGIN) |
| end_position = data.find(_EMULATED_DEVICES_END) |
| if begin_position == -1 or end_position == -1: |
| print('Could not find list of emulatedDevices in %s' % file_name) |
| return 1 |
| begin_position += len(_EMULATED_DEVICES_BEGIN) |
| list_string = '[' + data[begin_position:end_position] + ']' |
| |
| # Only used the non-localized strings in the list. |
| if_position = list_string.find(_EMULATED_DEVICES_IF) |
| while if_position != -1: |
| else_position = list_string.find(_EMULATED_DEVICES_ELSE) |
| if else_position == -1: |
| print('Could not find list of emulatedDevices in %s' % file_name) |
| return 1 |
| else_position += len(_EMULATED_DEVICES_ELSE) |
| list_string = list_string[0:if_position] + list_string[else_position::] |
| |
| endif_position = list_string.find(_EMULATED_DEVICES_ENDIF) |
| if endif_position == -1: |
| print('Could not find list of emulatedDevices in %s' % file_name) |
| return 1 |
| list_string = list_string[0:endif_position] + \ |
| list_string[endif_position + len(_EMULATED_DEVICES_ENDIF)::] |
| |
| if_position = list_string.find(_EMULATED_DEVICES_IF) |
| |
| # Do a bunch of substitutions to get something parseable by Python. |
| list_string = list_string.replace('true', 'True') |
| list_string = list_string.replace('false', 'False') |
| emulated_devices = ast.literal_eval(list_string) |
| for device in emulated_devices: |
| title = device['title'] |
| titles = [title] |
| # For 'iPhone 6/7/8', also add ['iPhone 6', 'iPhone 7', 'iPhone 8'] for |
| # backward compatibility. |
| if '/' in title: |
| words = title.split() |
| for i in range(len(words)): |
| if '/' in words[i]: |
| # Only support one word containing '/' |
| break |
| tokens = words[i].split('/') |
| for token in tokens: |
| words[i] = token |
| titles.append(' '.join(words)) |
| for title in titles: |
| mobile_emulation = { |
| 'userAgent': device['user-agent'], |
| 'deviceMetrics': { |
| 'width': device['screen']['vertical']['width'], |
| 'height': device['screen']['vertical']['height'], |
| 'deviceScaleFactor': device['screen']['device-pixel-ratio'], |
| 'touch': 'touch' in device['capabilities'], |
| 'mobile': 'mobile' in device['capabilities'], |
| }, |
| 'type': device['type'] |
| } |
| if 'user-agent-metadata' in device: |
| client_hints = device['user-agent-metadata'] |
| mobile_emulation['clientHints'] = { |
| 'architecture': client_hints['architecture'], |
| 'bitness': '', |
| 'platform': client_hints['platform'], |
| 'platformVersion': client_hints['platformVersion'], |
| 'model': client_hints['model'], |
| 'mobile': client_hints['mobile'], |
| 'wow64': False, |
| } |
| devices[title] = mobile_emulation |
| |
| output_dir = 'chrome/test/chromedriver/chrome' |
| cpp_source.WriteSource('mobile_device_list', |
| output_dir, |
| options.directory, |
| {'kMobileDevices': json.dumps(devices)}) |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |