FastbootDeviceFlasher

public class FastbootDeviceFlasher
extends Object implements IDeviceFlasher

java.lang.Object
   ↳ com.android.tradefed.targetprep.FastbootDeviceFlasher


這個類別仰賴 Fastboot 在實體 Android 硬體上刷新映像檔。

摘要

欄位

public static final String BASEBAND_IMAGE_NAME

公用建構函式

FastbootDeviceFlasher()

公用方法

static String fetchImageVersion(IRunUtil runUtil, ITestDevice device, String imageName)

取得裝置目前映像檔版本的輔助方法。

void flash(ITestDevice device, IDeviceBuildInfo deviceBuild)

閃爍的版本。

CommandStatus getSystemFlashingStatus()

擷取刷新主要系統分區的指令執行狀態。

IDeviceFlasher.UserDataFlashOption getUserDataFlashOption()

取得是否應刷新、抹除或保留使用者資料映像檔

void overrideDeviceOptions(ITestDevice device)

覆寫裝置的選項。

void preFlashOperations(ITestDevice device, IDeviceBuildInfo deviceBuild)

所有設定作業與檢查在實際刷新重要部分前執行。

void setDataWipeSkipList( dataWipeSkipList)

設定 /data 下的路徑清單,以免在使用 ITestsZipInstaller 時清除

請注意,略過清單的精細程度是 /data 的直接子項。

void setFlashOptions( flashOptions)

設定一系列要透過 flash/update 指令傳送的選項。

void setFlashingResourcesRetriever(IFlashingResourcesRetriever retriever)

設定 Flasher 可擷取資源檔案進行刷新的機制。

void setForceSystemFlash(boolean forceSystemFlash)

設定是否應一律刷新系統 (即使在執行目前的版本時)

void setIncrementalFlashing(IncrementalImageUtil incrementalUtil)
void setRamdiskPartition(String ramdiskPartition)

設定 ramdisk 分區

void setShouldFlashRamdisk(boolean shouldFlashRamdisk)

設定透過映像檔 ZIP 更新裝置後,是否要為其他 ramdisk 刷新

void setUserDataFlashOption(IDeviceFlasher.UserDataFlashOption flashOption)

切換是否要刷新、抹除或保留使用者資料圖片

void setWipeTimeout(long timeout)

設定清除資料的逾時時間。

boolean shouldFlashRamdisk()

透過映像檔 ZIP 檔案更新裝置後,檢查 Flasher 是否設為需使用額外的 ramdisk

保護方法

void checkAndFlashBaseband(ITestDevice device, IDeviceBuildInfo deviceBuild)

如有需要,請將裝置上的基頻映像檔刷新。

boolean checkAndFlashBootloader(ITestDevice device, IDeviceBuildInfo deviceBuild)

如有需要,請刷新裝置上的系統啟動載入程式映像檔。

boolean checkAndFlashSystem(ITestDevice device, String systemBuildId, String systemBuildFlavor, IDeviceBuildInfo deviceBuild)

如有需要,請在裝置上刷新系統映像檔。

boolean checkShouldFlashBaseband(ITestDevice device, IDeviceBuildInfo deviceBuild)

檢查所提供裝置上的基頻是否需要刷新。

IFlashingResourcesParser createFlashingResourcesParser(IDeviceBuildInfo localBuild, DeviceDescriptor descriptor)

建立 IFlashingResourcesParser 的工廠方法。

void downloadExtraImageFiles(IFlashingResourcesParser resourceParser, IFlashingResourcesRetriever retriever, IDeviceBuildInfo localBuild)

讓子類別視需要下載額外的自訂圖片檔。

void downloadFlashingResources(ITestDevice device, IDeviceBuildInfo localBuild)

下載所需的額外刷新圖片檔

String executeFastbootCmd(ITestDevice device, String... cmdArgs)

執行 Fastboot 指令的輔助方法。

String executeLongFastbootCmd(ITestDevice device, String... cmdArgs)

用於執行長時間執行的 Fastboot 指令的輔助方法。

String executeLongFastbootCmd(ITestDevice device, envVarMap, String... cmdArgs)

透過環境變數執行長時間執行的 Fastboot 指令的輔助方法。

void flashBaseband(ITestDevice device, File basebandImageFile)

刷新指定基頻映像檔,並重新啟動系統啟動載入程式

void flashBootloader(ITestDevice device, File bootloaderImageFile)

刷新指定的系統啟動載入程式映像檔,並重新啟動系統啟動載入程式

void flashExtraImages(ITestDevice device, IDeviceBuildInfo deviceBuild)

刷新系統並重新啟動前,刷新裝置專用分區。

void flashPartition(ITestDevice device, File imgFile, String partition)

刷新裝置個別分區

void flashRamdiskIfNeeded(ITestDevice device, IDeviceBuildInfo deviceBuild)
void flashSystem(ITestDevice device, IDeviceBuildInfo deviceBuild)

刷新裝置中的系統映像檔。

void flashUserData(ITestDevice device, IDeviceBuildInfo deviceBuild)

裝置上的 Flash 使用者資料分區。

void flashUserDataFromDeviceImageFile(ITestDevice device, IDeviceBuildInfo deviceBuild)

從裝置映像檔擷取 userdata.img 並刷新到裝置上

String getBootPartitionName()

取得此裝置 Flasher 的啟動分區名稱。

String getBootloaderFilePrefix(ITestDevice device)

取得系統啟動載入程式檔案的前置字串。

String getCurrentSlot(ITestDevice device)

擷取目前版位的輔助方法 (適用於支援 A/B 的裝置)。

IFlashingResourcesRetriever getFlashingResourcesRetriever()
FuseUtil getFuseUtil()
String getImageVersion(ITestDevice device, String imageName)
IRunUtil getRunUtil()

公開測試。

void handleUserDataFlashing(ITestDevice device, IDeviceBuildInfo deviceBuild)

處理使用者資料/快取分區的刷新作業

boolean hasPartition(ITestDevice device, String partition)

檢查系統啟動載入程式是否存在指定的分區

void preFlashSetup(ITestDevice device, IDeviceBuildInfo deviceBuild)

執行任何其他必要的預先刷新設定。

void setSystemBuildInfo(String systemBuildId, String systemBuildFlavor)
void verifyRequiredBoards(ITestDevice device, IFlashingResourcesParser resourceParser, String deviceProductType)

確認裝置的產品類型支援要刷新的版本。

void wipeCache(ITestDevice device)

清除裝置上的快取分區。

void wipePartition(ITestDevice device, String partition)

使用「Fastbootwipe <name>」抹除指定分區

欄位

BASEBAND_IMAGE_NAME

public static final String BASEBAND_IMAGE_NAME

公用建構函式

FastbootDeviceFlasher

public FastbootDeviceFlasher ()

公用方法

擷取圖片版本

public static String fetchImageVersion (IRunUtil runUtil, 
                ITestDevice device, 
                String imageName)

取得裝置上目前映像檔版本的輔助方法。

參數
runUtil IRunUtil

device ITestDevice:要用於執行指令的 ITestDevice

imageName String:要取得的映像檔名稱。

傳回
String 指令中的 stdout 輸出內容字串

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果 Quickboot 指令失敗或無法判斷版本

閃光燈

public void flash (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

刷新會在裝置上。

刷新完成後立即傳回。呼叫端應等待裝置連上網路且可供使用後,才能繼續進行測試。

參數
device ITestDevice:要刷新的 ITestDevice

deviceBuild IDeviceBuildInfo:要刷新的 IDeviceBuildInfo

擲回
DeviceNotAvailableException
TargetSetupError

getSystemFlashingStatus

public CommandStatus getSystemFlashingStatus ()

擷取刷新主要系統分區的指令執行狀態。

請注意,如果系統分區未刷新 (系統已有要刷新的版本),指令狀態可能會是 null

傳回
CommandStatus

getUserDataFlashOption

public IDeviceFlasher.UserDataFlashOption getUserDataFlashOption ()

取得是否應刷新、清除或保留使用者資料圖片

傳回
IDeviceFlasher.UserDataFlashOption 是否應刷新、清除或保留使用者資料圖片

覆寫裝置選項

public void overrideDeviceOptions (ITestDevice device)

覆寫裝置的選項。如果特定裝置不支援預設值,可以使用這項屬性覆寫預設的選項值。

preFlashOperations

public void preFlashOperations (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

所有設定作業與檢查在實際刷新重要部分前執行。這些作業均不會納入受並行控制的重要部分。

參數
device ITestDevice:要刷新的 ITestDevice

deviceBuild IDeviceBuildInfo:要刷新的 IDeviceBuildInfo

擲回
DeviceNotAvailableException
TargetSetupError

setDataWipeSkipList

public void setDataWipeSkipList ( dataWipeSkipList)

設定 /data 下的路徑清單,以免在使用 ITestsZipInstaller 時清除

請注意,略過清單的精細程度是 /data 的直接子項。

參數
dataWipeSkipList

setFlashOptions

public void setFlashOptions ( flashOptions)

設定一系列選項,以透過 Flash/update 指令傳送。

setFlashingResourcesRetriever

public void setFlashingResourcesRetriever (IFlashingResourcesRetriever retriever)

設定 Flasher 可擷取資源檔案進行刷新的機制。

參數
retriever IFlashingResourcesRetriever:要使用的 IFlashingResourcesRetriever

setForceSystemFlash

public void setForceSystemFlash (boolean forceSystemFlash)

設定是否應一律刷新系統 (即使在執行目前版本時)

setIncrementalFlash

public void setIncrementalFlashing (IncrementalImageUtil incrementalUtil)

參數
incrementalUtil IncrementalImageUtil

setRamdiskPartition

public void setRamdiskPartition (String ramdiskPartition)

設定 ramdisk 分區

setSetFlashRamdisk

public void setShouldFlashRamdisk (boolean shouldFlashRamdisk)

設定是否在透過映像檔 ZIP 更新裝置後,應刷新其他 ramdisk

setUserDataFlashOption

public void setUserDataFlashOption (IDeviceFlasher.UserDataFlashOption flashOption)

切換是否要刷新、抹除或保留使用者資料圖片

設定抹除逾時

public void setWipeTimeout (long timeout)

設定清除資料的逾時時間。

參數
timeout long

應該使用 FlashRamdisk

public boolean shouldFlashRamdisk ()

透過映像檔 ZIP 檔案更新裝置後,檢查 Flasher 是否應設為使用額外的 ramdisk

傳回
boolean

保護方法

檢查 AndFlashBaseband

protected void checkAndFlashBaseband (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

如有需要,請將裝置上的基頻映像檔刷新。只有在裝置目前的版本 != 必要版本時,才會刷新基頻

參數
device ITestDevice:要刷新的 ITestDevice

deviceBuild IDeviceBuildInfo:包含要刷新的基頻映像檔的 IDeviceBuildInfo

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果無法刷新基頻

checkAndFlashBootloader

protected boolean checkAndFlashBootloader (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

如有需要,請刷新裝置上的系統啟動載入程式映像檔。

只有在裝置的目前版本 != 必要版本時,才會刷新系統啟動載入程式。

參數
device ITestDevice:要刷新的 ITestDevice

deviceBuild IDeviceBuildInfo:包含要刷新的系統啟動載入程式映像檔的 IDeviceBuildInfo

傳回
boolean 如果系統啟動載入程式已刷新,則為 true;如果略過,則為 false

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 表示無法刷新系統啟動載入程式。

檢查 AndFlashSystem

protected boolean checkAndFlashSystem (ITestDevice device, 
                String systemBuildId, 
                String systemBuildFlavor, 
                IDeviceBuildInfo deviceBuild)

如有需要,請在裝置上刷新系統映像檔。

請參考 ERROR(/#shouldFlashSystem(String,String,com.android.tradefed.build.IDeviceBuildInfo))

無論選擇哪種路徑,在方法執行裝置之後應啟動進入使用者空間。

參數
device ITestDevice:要刷新的 ITestDevice

systemBuildId String:裝置上執行目前版本的建構 ID

systemBuildFlavor String:在裝置上執行目前的建構變種版本

deviceBuild IDeviceBuildInfo:包含要刷新的系統映像檔的 IDeviceBuildInfo

傳回
boolean 如果系統經過刷新,請true;如果略過,則設為 false

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 表示無法刷新系統啟動載入程式。

check shouldFlashBaseband

protected boolean checkShouldFlashBaseband (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

檢查隨附裝置上的基頻是否需要刷新。

參數
device ITestDevice:要檢查的 ITestDevice

deviceBuild IDeviceBuildInfo:包含要檢查的基頻映像檔的 IDeviceBuildInfo

傳回
boolean

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果無法刷新基頻

createFlashingResourcesParser

protected IFlashingResourcesParser createFlashingResourcesParser (IDeviceBuildInfo localBuild, 
                DeviceDescriptor descriptor)

建立 IFlashingResourcesParser 的工廠方法。

可供單元測試使用。

參數
localBuild IDeviceBuildInfo:要剖析的 IDeviceBuildInfo

descriptor DeviceDescriptor:要刷新的裝置描述元。

傳回
IFlashingResourcesParser 工廠方法建立的 IFlashingResourcesParser

擲回
com.android.tradefed.targetprep.TargetSetupError
TargetSetupError

downloadExtraImageFiles

protected void downloadExtraImageFiles (IFlashingResourcesParser resourceParser, 
                IFlashingResourcesRetriever retriever, 
                IDeviceBuildInfo localBuild)

掛鉤,讓子類別視需要下載額外的自訂圖片檔。

參數
resourceParser IFlashingResourcesParserIFlashingResourcesParser

retriever IFlashingResourcesRetrieverIFlashingResourcesRetriever

localBuild IDeviceBuildInfoIDeviceBuildInfo

擲回
com.android.tradefed.targetprep.TargetSetupError
TargetSetupError

downloadFlashing 資源

protected void downloadFlashingResources (ITestDevice device, 
                IDeviceBuildInfo localBuild)

下載額外 Flash 圖片檔

參數
device ITestDevice:要下載資源的 ITestDevice

localBuild IDeviceBuildInfo:要填入的 IDeviceBuildInfo。假設裝置映像檔已設定完畢

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果無法擷取資源時傳回

執行 FastbootCmd

protected String executeFastbootCmd (ITestDevice device, 
                String... cmdArgs)

執行 Quickboot 指令的輔助方法。

參數
device ITestDevice:要用於執行指令的 ITestDevice

cmdArgs String:提供給 Fastboot 的引數

傳回
String 如果並非空白,則從指令輸出 stderr 輸出內容的字串。否則會傳回 stdout。某些 Fastboot 命令在成功的情況下會將輸出內容轉儲到 stderr 中,這是奇怪的

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果 Fastboot 指令失敗

執行 LongFastbootCmd

protected String executeLongFastbootCmd (ITestDevice device, 
                String... cmdArgs)

用於執行長時間執行的 Fastboot 指令的輔助方法。

注意:大部分 Fastboot 指令通常在 INativeDevice.executeFastbootCommand(String) 允許的逾時時間內執行。不過,當多部裝置同時刷新裝置時,Fastboot 指令可能會比一般更長的時間更長。

參數
device ITestDevice:要用於執行指令的 ITestDevice

cmdArgs String:提供給 Fastboot 的引數

傳回
String 如果並非空白,則從指令輸出 stderr 輸出內容的字串。否則會傳回 stdout。某些 Fastboot 命令在成功的情況下會將輸出內容轉儲到 stderr 中,這是奇怪的

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果 Fastboot 指令失敗

執行 LongFastbootCmd

protected String executeLongFastbootCmd (ITestDevice device, 
                 envVarMap, 
                String... cmdArgs)

透過環境變數執行長時間執行的 Fastboot 指令的輔助方法。

注意:大部分 Fastboot 指令通常在 INativeDevice.executeFastbootCommand(String) 允許的逾時時間內執行。不過,當多部裝置同時刷新裝置時,Fastboot 指令可能會比一般更長的時間更長。

參數
device ITestDevice:要用於執行指令的 ITestDevice

envVarMap :此地圖含有執行 Fastboot 指令前必須設定的環境變數

cmdArgs String:提供給 Fastboot 的引數

傳回
String 如果並非空白,則從指令輸出 stderr 輸出內容的字串。否則會傳回 stdout。某些 Fastboot 命令在成功的情況下會將輸出內容轉儲到 stderr 中,這是奇怪的

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果 Fastboot 指令失敗

flashBaseband

protected void flashBaseband (ITestDevice device, 
                File basebandImageFile)

刷新指定基頻映像檔,並重新啟動以系統啟動載入程式

參數
device ITestDevice:要刷新的 ITestDevice

basebandImageFile File:基頻映像檔 ERROR(/File)

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果無法刷新基頻

flashBootloader

protected void flashBootloader (ITestDevice device, 
                File bootloaderImageFile)

刷新指定的系統啟動載入程式映像檔,並重新啟動系統啟動載入程式

參數
device ITestDevice:要刷新的 ITestDevice

bootloaderImageFile File:系統啟動載入程式映像檔 ERROR(/File)

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果無法刷新的

FlashExtraImage

protected void flashExtraImages (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

刷新系統並重新啟動前,刷新裝置專用分割區。除非遭到覆寫,否則免人工管理。

參數
device ITestDevice:要刷新的 ITestDevice

deviceBuild IDeviceBuildInfo:包含建構檔案的 IDeviceBuildInfo

擲回
com.android.tradefed.device.DeviceNotAvailableException
com.android.tradefed.targetprep.TargetSetupError
DeviceNotAvailableException
TargetSetupError

flashPartition

protected void flashPartition (ITestDevice device, 
                File imgFile, 
                String partition)

刷新裝置個別分區

參數
device ITestDevice:要刷新的 ITestDevice

imgFile File:指向要刷新的映像檔的 ERROR(/File)

partition String:要刷新的分區名稱

擲回
DeviceNotAvailableException
TargetSetupError

flashRamdiskIf 需要 ed

protected void flashRamdiskIfNeeded (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

參數
device ITestDevice

deviceBuild IDeviceBuildInfo

擲回
DeviceNotAvailableException
TargetSetupError

閃光系統

protected void flashSystem (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

更新裝置上的系統映像檔。

參數
device ITestDevice:要刷新的 ITestDevice

deviceBuild IDeviceBuildInfo:要刷新的 IDeviceBuildInfo

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果 Fastboot 指令失敗

flashUserData

protected void flashUserData (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

裝置上的 Flash 使用者資料分區。

參數
device ITestDevice:要刷新的 ITestDevice

deviceBuild IDeviceBuildInfo:這個 IDeviceBuildInfo 包含要刷新的檔案

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError (如果無法刷新使用者資料)

從裝置映像檔載入 flashUserDataFromDeviceImageFile

protected void flashUserDataFromDeviceImageFile (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

從裝置映像檔擷取 userdata.img 並刷新到裝置上

參數
device ITestDevice:要刷新的 ITestDevice

deviceBuild IDeviceBuildInfo:這個 IDeviceBuildInfo 包含要刷新的檔案

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果無法擷取或刷新使用者資料

getBootPartitionName

protected String getBootPartitionName ()

取得此裝置 Flasher 的啟動分區名稱。

預設為「系統啟動載入程式」。如有需要,子類別應覆寫。

傳回
String

getBootloaderFilePrefix

protected String getBootloaderFilePrefix (ITestDevice device)

取得系統啟動載入程式檔案前置字串。

預設為 getBootPartitionName()。如有需要,子類別應覆寫。

參數
device ITestDevice:要刷新的 ITestDevice

傳回
String

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 無法取得前置碼

getCurrentSlot

protected String getCurrentSlot (ITestDevice device)

擷取目前插槽 (適用於支援 A/B 功能的裝置) 的輔助方法。

參數
device ITestDevice:要用於執行指令的 ITestDevice

傳回
String 「a」、「b」或空值 (如果裝置不支援 A/B 功能)

擲回
com.android.tradefed.device.DeviceNotAvailableException
com.android.tradefed.targetprep.TargetSetupError
DeviceNotAvailableException
TargetSetupError

getFlashingResourcesRetriever

protected IFlashingResourcesRetriever getFlashingResourcesRetriever ()

傳回
IFlashingResourcesRetriever

getFuseUtil

protected FuseUtil getFuseUtil ()

傳回
FuseUtil

getImageVersion

protected String getImageVersion (ITestDevice device, 
                String imageName)

參數
device ITestDevice

imageName String

傳回
String

擲回
DeviceNotAvailableException
TargetSetupError

getRunUtil

protected IRunUtil getRunUtil ()

公開測試。

傳回
IRunUtil

handleUserDataFlashing

protected void handleUserDataFlashing (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

處理使用者資料/快取分區的刷新作業

參數
device ITestDevice:要刷新的 ITestDevice

deviceBuild IDeviceBuildInfo:這個 IDeviceBuildInfo 包含要刷新的檔案

擲回
com.android.tradefed.device.DeviceNotAvailableException
com.android.tradefed.targetprep.TargetSetupError
DeviceNotAvailableException
TargetSetupError

hasPartition

protected boolean hasPartition (ITestDevice device, 
                String partition)

檢查系統啟動載入程式是否存在指定的分區

參數
device ITestDevice:要在其中操作的 ITestDevice

partition String:要檢查的分區名稱

傳回
boolean

擲回
DeviceNotAvailableException

舊版 Flash 設定

protected void preFlashSetup (ITestDevice device, 
                IDeviceBuildInfo deviceBuild)

執行任何額外的預先刷新設定。除非遭到覆寫,否則免人工管理。

參數
device ITestDevice:要準備的 ITestDevice

deviceBuild IDeviceBuildInfo:包含建構檔案的 IDeviceBuildInfo

擲回
com.android.tradefed.device.DeviceNotAvailableException
com.android.tradefed.targetprep.TargetSetupError
DeviceNotAvailableException
TargetSetupError

setSystemBuildInfo

protected void setSystemBuildInfo (String systemBuildId, 
                String systemBuildFlavor)

參數
systemBuildId String

systemBuildFlavor String

驗證必要板

protected void verifyRequiredBoards (ITestDevice device, 
                IFlashingResourcesParser resourceParser, 
                String deviceProductType)

確認裝置的產品類型支援要刷新的版本。

基本實作會驗證 deviceProductType 已包含在 IFlashingResourcesParser.getRequiredBoards() 集合中。子類別可視需要覆寫。

參數
device ITestDevice:要刷新的 ITestDevice

resourceParser IFlashingResourcesParserIFlashingResourcesParser

deviceProductType Stringdevice的產品類型

擲回
TargetSetupError 如果版本所需的主機資訊與裝置不符

抹除快取

protected void wipeCache (ITestDevice device)

清除裝置上的快取分區。

參數
device ITestDevice:要刷新的 ITestDevice

擲回
DeviceNotAvailableException 如果沒有裝置
TargetSetupError 如果無法刷新快取

劃接

protected void wipePartition (ITestDevice device, 
                String partition)

使用「Fastbootwipe <name>」清除指定分區

參數
device ITestDevice:要在其中操作的 ITestDevice

partition String:要清除的分區名稱

擲回
DeviceNotAvailableException
TargetSetupError