blob: 3189d57ea86558750a9959c4b112b18c9f3fd563 [file] [log] [blame] [edit]
# Copyright 2023, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Device update methods used to prepare the device under test."""
from abc import ABC, abstractmethod
from pathlib import Path
import subprocess
from subprocess import CalledProcessError
import time
from typing import List, Set
from atest import atest_utils
from atest import constants
class DeviceUpdateMethod(ABC):
"""A device update method used to update device."""
@abstractmethod
def update(self, serials: List[str] = None):
"""Updates the device.
Args:
serials: A list of serial numbers.
Raises:
Error: If the device update fails.
"""
@abstractmethod
def dependencies(self) -> Set[str]:
"""Returns the dependencies required by this device update method."""
class NoopUpdateMethod(DeviceUpdateMethod):
def update(self, serials: List[str] = None) -> None:
pass
def dependencies(self) -> Set[str]:
return set()
class AdeviceUpdateMethod(DeviceUpdateMethod):
_TOOL = 'adevice'
def __init__(self, adevice_path: Path=_TOOL, targets: Set[str]=None):
self._adevice_path = adevice_path
self._targets = targets or set(['sync'])
def update(self, serials: List[str] = None) -> None:
try:
print(atest_utils.mark_cyan('\nUpdating device...'))
update_start = time.time()
update_cmd = [self._adevice_path, 'update']
if serials:
if len(serials) > 1:
atest_utils.colorful_print(
'Warning: Device update feature can only update one '
'device for now, but this invocation specifies more '
'than one device. Atest will update the first device '
'by default.',
constants.YELLOW,
)
update_cmd.extend(['--serial', serials[0]])
subprocess.check_call(update_cmd)
print(
atest_utils.mark_cyan(
'\nDevice update finished in '
f'{str(round(time.time() - update_start, 2))}s.'
)
)
except CalledProcessError as e:
raise Error('Failed to update the device with adevice') from e
def dependencies(self) -> Set[str]:
return self._targets.union({self._TOOL})
class Error(Exception):
pass