1 /*
2  * Copyright (C) 2018 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 
17 package com.android.tradefed.device.metric;
18 
19 import android.os.IncidentProto;
20 
21 import com.android.tradefed.config.OptionClass;
22 import com.android.tradefed.result.ByteArrayInputStreamSource;
23 import com.android.tradefed.result.LogDataType;
24 import com.google.protobuf.InvalidProtocolBufferException;
25 
26 import java.io.File;
27 import java.io.IOException;
28 import java.nio.file.Files;
29 
30 /**
31  * Pulls and processes incident reports that are reported device-side.
32  *
33  * <p>TODO(b/119418529): Collect an incident report host-side on failure.
34  */
35 @OptionClass(alias = "incident-collector")
36 public class IncidentReportCollector extends FilePullerLogCollector {
37     // Prefix of the keys for all incident files passed from the device.
38     private static final String INCIDENT_KEY_MATCHER = "incident-report";
39     // Suffix for all of the logs that are processed incident reports.
40     private static final String PROCESSED_KEY_SUFFIX = "-processed";
41 
IncidentReportCollector()42     public IncidentReportCollector() {
43         addKeys(INCIDENT_KEY_MATCHER);
44     }
45 
46     @Override
postProcessMetricFile(String key, File metricFile, DeviceMetricData runData)47     protected void postProcessMetricFile(String key, File metricFile, DeviceMetricData runData) {
48         // Read and interpret the incident report's bytes.
49         IncidentProto processedReport;
50         try {
51             byte[] output = Files.readAllBytes(metricFile.toPath());
52             processedReport = IncidentProto.parser().parseFrom(output);
53         } catch (InvalidProtocolBufferException e) {
54             throw new RuntimeException(
55                     String.format("Failed to parse protobuf: %s", metricFile.toPath().toString()),
56                     e);
57         } catch (IOException e) {
58             throw new RuntimeException(
59                     String.format(
60                             "Failed to read incident file: %s", metricFile.toPath().toString()),
61                     e);
62         }
63         // Report the newly processed incident report.
64         testLog(
65                 metricFile.getName().concat(PROCESSED_KEY_SUFFIX),
66                 LogDataType.PB,
67                 new ByteArrayInputStreamSource(processedReport.toString().getBytes()));
68     }
69 }
70