1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.tradefed.invoker;
17 
18 import com.android.tradefed.device.DeviceNotAvailableException;
19 import com.android.tradefed.device.DeviceUnresponsiveException;
20 import com.android.tradefed.device.ITestDevice;
21 import com.android.tradefed.device.StubDevice;
22 import com.android.tradefed.result.FailureDescription;
23 import com.android.tradefed.result.ITestInvocationListener;
24 import com.android.tradefed.result.TestDescription;
25 import com.android.tradefed.result.error.DeviceErrorIdentifier;
26 import com.android.tradefed.result.proto.TestRecordProto.FailureStatus;
27 
28 /** This listener attempts to capture a test case level DNAE only. */
29 public final class DeviceUnavailableMonitor implements ITestInvocationListener {
30 
31     private boolean mInvocationFailed = false;
32     private DeviceNotAvailableException mUnavailableException = null;
33     private String mSerial = null;
34 
35     @Override
invocationStarted(IInvocationContext context)36     public void invocationStarted(IInvocationContext context) {
37         for (ITestDevice device : context.getDevices()) {
38             if (!(device.getIDevice() instanceof StubDevice)) {
39                 mSerial = device.getSerialNumber();
40             }
41         }
42     }
43 
44     @Override
testRunFailed(FailureDescription failure)45     public void testRunFailed(FailureDescription failure) {
46         if (mUnavailableException != null || mInvocationFailed) {
47             return;
48         }
49         mUnavailableException = analyzeFailure(failure);
50     }
51 
52     @Override
testFailed(TestDescription test, FailureDescription failure)53     public void testFailed(TestDescription test, FailureDescription failure) {
54         if (mUnavailableException != null || mInvocationFailed) {
55             return;
56         }
57         mUnavailableException = analyzeFailure(failure);
58     }
59 
60     @Override
invocationFailed(FailureDescription failure)61     public void invocationFailed(FailureDescription failure) {
62         mInvocationFailed = true;
63         if (mUnavailableException != null) {
64           return;
65         }
66         mUnavailableException = analyzeFailure(failure);
67     }
68 
69     @Override
invocationFailed(Throwable cause)70     public void invocationFailed(Throwable cause) {
71         mInvocationFailed = true;
72     }
73 
74     /** Returns the exception if any was captured. */
getUnavailableException()75     public DeviceNotAvailableException getUnavailableException() {
76         return mUnavailableException;
77     }
78 
analyzeFailure(FailureDescription failure)79     private DeviceNotAvailableException analyzeFailure(FailureDescription failure) {
80         if (failure.getCause() != null
81                 && failure.getCause() instanceof DeviceNotAvailableException) {
82             return (DeviceNotAvailableException) failure.getCause();
83         } else if (failure.getFailureStatus() != null
84                 && FailureStatus.LOST_SYSTEM_UNDER_TEST.equals(failure.getFailureStatus())) {
85             return new DeviceNotAvailableException(failure.getErrorMessage(), mSerial);
86         } else if (failure.getErrorIdentifier() != null) {
87             if (DeviceErrorIdentifier.DEVICE_UNAVAILABLE.equals(failure.getErrorIdentifier())) {
88                 return new DeviceNotAvailableException(failure.getErrorMessage(), mSerial);
89             } else if (DeviceErrorIdentifier.DEVICE_UNRESPONSIVE.equals(
90                     failure.getErrorIdentifier())) {
91                 return new DeviceUnresponsiveException(failure.getErrorMessage(), mSerial);
92             }
93         }
94         return null;
95     }
96 }
97