1*c2e18aaaSAndroid Build Coastguard Worker# Copyright 2023, The Android Open Source Project 2*c2e18aaaSAndroid Build Coastguard Worker# 3*c2e18aaaSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*c2e18aaaSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*c2e18aaaSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*c2e18aaaSAndroid Build Coastguard Worker# 7*c2e18aaaSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*c2e18aaaSAndroid Build Coastguard Worker# 9*c2e18aaaSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*c2e18aaaSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*c2e18aaaSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*c2e18aaaSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*c2e18aaaSAndroid Build Coastguard Worker# limitations under the License. 14*c2e18aaaSAndroid Build Coastguard Worker 15*c2e18aaaSAndroid Build Coastguard Worker"""Device update methods used to prepare the device under test.""" 16*c2e18aaaSAndroid Build Coastguard Worker 17*c2e18aaaSAndroid Build Coastguard Workerfrom abc import ABC, abstractmethod 18*c2e18aaaSAndroid Build Coastguard Workerfrom pathlib import Path 19*c2e18aaaSAndroid Build Coastguard Workerimport subprocess 20*c2e18aaaSAndroid Build Coastguard Workerfrom subprocess import CalledProcessError 21*c2e18aaaSAndroid Build Coastguard Workerimport time 22*c2e18aaaSAndroid Build Coastguard Workerfrom typing import List, Set 23*c2e18aaaSAndroid Build Coastguard Worker 24*c2e18aaaSAndroid Build Coastguard Workerfrom atest import atest_utils 25*c2e18aaaSAndroid Build Coastguard Workerfrom atest import constants 26*c2e18aaaSAndroid Build Coastguard Worker 27*c2e18aaaSAndroid Build Coastguard Worker 28*c2e18aaaSAndroid Build Coastguard Workerclass DeviceUpdateMethod(ABC): 29*c2e18aaaSAndroid Build Coastguard Worker """A device update method used to update device.""" 30*c2e18aaaSAndroid Build Coastguard Worker 31*c2e18aaaSAndroid Build Coastguard Worker @abstractmethod 32*c2e18aaaSAndroid Build Coastguard Worker def update(self, serials: List[str] = None): 33*c2e18aaaSAndroid Build Coastguard Worker """Updates the device. 34*c2e18aaaSAndroid Build Coastguard Worker 35*c2e18aaaSAndroid Build Coastguard Worker Args: 36*c2e18aaaSAndroid Build Coastguard Worker serials: A list of serial numbers. 37*c2e18aaaSAndroid Build Coastguard Worker 38*c2e18aaaSAndroid Build Coastguard Worker Raises: 39*c2e18aaaSAndroid Build Coastguard Worker Error: If the device update fails. 40*c2e18aaaSAndroid Build Coastguard Worker """ 41*c2e18aaaSAndroid Build Coastguard Worker 42*c2e18aaaSAndroid Build Coastguard Worker @abstractmethod 43*c2e18aaaSAndroid Build Coastguard Worker def dependencies(self) -> Set[str]: 44*c2e18aaaSAndroid Build Coastguard Worker """Returns the dependencies required by this device update method.""" 45*c2e18aaaSAndroid Build Coastguard Worker 46*c2e18aaaSAndroid Build Coastguard Worker 47*c2e18aaaSAndroid Build Coastguard Workerclass NoopUpdateMethod(DeviceUpdateMethod): 48*c2e18aaaSAndroid Build Coastguard Worker 49*c2e18aaaSAndroid Build Coastguard Worker def update(self, serials: List[str] = None) -> None: 50*c2e18aaaSAndroid Build Coastguard Worker pass 51*c2e18aaaSAndroid Build Coastguard Worker 52*c2e18aaaSAndroid Build Coastguard Worker def dependencies(self) -> Set[str]: 53*c2e18aaaSAndroid Build Coastguard Worker return set() 54*c2e18aaaSAndroid Build Coastguard Worker 55*c2e18aaaSAndroid Build Coastguard Worker 56*c2e18aaaSAndroid Build Coastguard Workerclass AdeviceUpdateMethod(DeviceUpdateMethod): 57*c2e18aaaSAndroid Build Coastguard Worker _TOOL = 'adevice' 58*c2e18aaaSAndroid Build Coastguard Worker 59*c2e18aaaSAndroid Build Coastguard Worker def __init__(self, adevice_path: Path=_TOOL, targets: Set[str]=None): 60*c2e18aaaSAndroid Build Coastguard Worker self._adevice_path = adevice_path 61*c2e18aaaSAndroid Build Coastguard Worker self._targets = targets or set(['sync']) 62*c2e18aaaSAndroid Build Coastguard Worker 63*c2e18aaaSAndroid Build Coastguard Worker def update(self, serials: List[str] = None) -> None: 64*c2e18aaaSAndroid Build Coastguard Worker try: 65*c2e18aaaSAndroid Build Coastguard Worker print(atest_utils.mark_cyan('\nUpdating device...')) 66*c2e18aaaSAndroid Build Coastguard Worker update_start = time.time() 67*c2e18aaaSAndroid Build Coastguard Worker 68*c2e18aaaSAndroid Build Coastguard Worker update_cmd = [self._adevice_path, 'update'] 69*c2e18aaaSAndroid Build Coastguard Worker if serials: 70*c2e18aaaSAndroid Build Coastguard Worker if len(serials) > 1: 71*c2e18aaaSAndroid Build Coastguard Worker atest_utils.colorful_print( 72*c2e18aaaSAndroid Build Coastguard Worker 'Warning: Device update feature can only update one ' 73*c2e18aaaSAndroid Build Coastguard Worker 'device for now, but this invocation specifies more ' 74*c2e18aaaSAndroid Build Coastguard Worker 'than one device. Atest will update the first device ' 75*c2e18aaaSAndroid Build Coastguard Worker 'by default.', 76*c2e18aaaSAndroid Build Coastguard Worker constants.YELLOW, 77*c2e18aaaSAndroid Build Coastguard Worker ) 78*c2e18aaaSAndroid Build Coastguard Worker 79*c2e18aaaSAndroid Build Coastguard Worker update_cmd.extend(['--serial', serials[0]]) 80*c2e18aaaSAndroid Build Coastguard Worker 81*c2e18aaaSAndroid Build Coastguard Worker subprocess.check_call(update_cmd) 82*c2e18aaaSAndroid Build Coastguard Worker 83*c2e18aaaSAndroid Build Coastguard Worker print( 84*c2e18aaaSAndroid Build Coastguard Worker atest_utils.mark_cyan( 85*c2e18aaaSAndroid Build Coastguard Worker '\nDevice update finished in ' 86*c2e18aaaSAndroid Build Coastguard Worker f'{str(round(time.time() - update_start, 2))}s.' 87*c2e18aaaSAndroid Build Coastguard Worker ) 88*c2e18aaaSAndroid Build Coastguard Worker ) 89*c2e18aaaSAndroid Build Coastguard Worker 90*c2e18aaaSAndroid Build Coastguard Worker except CalledProcessError as e: 91*c2e18aaaSAndroid Build Coastguard Worker raise Error('Failed to update the device with adevice') from e 92*c2e18aaaSAndroid Build Coastguard Worker 93*c2e18aaaSAndroid Build Coastguard Worker def dependencies(self) -> Set[str]: 94*c2e18aaaSAndroid Build Coastguard Worker return self._targets.union({self._TOOL}) 95*c2e18aaaSAndroid Build Coastguard Worker 96*c2e18aaaSAndroid Build Coastguard Worker 97*c2e18aaaSAndroid Build Coastguard Workerclass Error(Exception): 98*c2e18aaaSAndroid Build Coastguard Worker pass 99