1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch# Copyright 2013 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch# Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch# found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch""" A simple device interface for build steps. 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch""" 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochimport logging 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochimport os 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochimport re 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochimport sys 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)from util import build_utils 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochBUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..', '..') 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochsys.path.append(BUILD_ANDROID_DIR) 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochfrom pylib import android_commands 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)from pylib.device import device_errors 21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochfrom pylib.device import device_utils 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)GetAttachedDevices = android_commands.GetAttachedDevices 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass BuildDevice(object): 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch def __init__(self, configuration): 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch self.id = configuration['id'] 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch self.description = configuration['description'] 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch self.install_metadata = configuration['install_metadata'] 31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self.device = device_utils.DeviceUtils(self.id) 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch def RunShellCommand(self, *args, **kwargs): 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return self.device.RunShellCommand(*args, **kwargs) 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def PushChangedFiles(self, *args, **kwargs): 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return self.device.PushChangedFiles(*args, **kwargs) 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch def GetSerialNumber(self): 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return self.id 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch def Install(self, *args, **kwargs): 43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return self.device.old_interface.Install(*args, **kwargs) 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch def GetInstallMetadata(self, apk_package): 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch """Gets the metadata on the device for the apk_package apk.""" 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch # Matches lines like: 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch # -rw-r--r-- system system 7376582 2013-04-19 16:34 \ 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # org.chromium.chrome.shell.apk 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch # -rw-r--r-- system system 7376582 2013-04-19 16:34 \ 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # org.chromium.chrome.shell-1.apk 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch apk_matcher = lambda s: re.match('.*%s(-[0-9]*)?.apk$' % apk_package, s) 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch matches = filter(apk_matcher, self.install_metadata) 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return matches[0] if matches else None 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)def GetConfigurationForDevice(device_id): 58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch device = device_utils.DeviceUtils(device_id) 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch configuration = None 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch has_root = False 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_online = device.IsOnline() 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if is_online: 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cmd = 'ls -l /data/app; getprop ro.build.description' 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) cmd_output = device.RunShellCommand(cmd) 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch has_root = not 'Permission denied' in cmd_output[0] 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if not has_root: 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # Disable warning log messages from EnableRoot() 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch logging.getLogger().disabled = True 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) try: 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) device.EnableRoot() 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) has_root = True 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) except device_errors.CommandFailedError: 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) has_root = False 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) finally: 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) logging.getLogger().disabled = False 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) cmd_output = device.RunShellCommand(cmd) 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch configuration = { 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 'id': device_id, 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 'description': cmd_output[-1], 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 'install_metadata': cmd_output[:-1], 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return configuration, is_online, has_root 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochdef WriteConfigurations(configurations, path): 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch # Currently we only support installing to the first device. 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch build_utils.WriteJson(configurations[:1], path, only_if_changed=True) 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochdef ReadConfigurations(path): 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return build_utils.ReadJson(path) 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochdef GetBuildDevice(configurations): 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch assert len(configurations) == 1 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return BuildDevice(configurations[0]) 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochdef GetBuildDeviceFromPath(path): 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch configurations = ReadConfigurations(path) 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if len(configurations) > 0: 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return GetBuildDevice(ReadConfigurations(path)) 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return None 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 106