1 /*
2  * Copyright (C) 2016 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.result;
17 
18 import com.android.test.metrics.proto.FileMetadataProto.FileMetadata;
19 import com.android.test.metrics.proto.FileMetadataProto.LogFile;
20 import com.android.test.metrics.proto.FileMetadataProto.LogType;
21 import com.android.tradefed.config.Option;
22 import com.android.tradefed.config.OptionClass;
23 import com.android.tradefed.log.LogUtil.CLog;
24 import com.android.tradefed.util.StreamUtil;
25 
26 import com.google.common.annotations.VisibleForTesting;
27 
28 import java.io.IOException;
29 import java.io.InputStream;
30 
31 /** A listener that collects and uploads metadata about saved log files. */
32 @OptionClass(alias = "metadata")
33 public class FileMetadataCollector implements ILogSaverListener, ITestInvocationListener {
34     @Option(name = "disable", description = "Disable metadata collecting")
35     protected boolean mDisable = false;
36 
37     private ILogSaver mLogSaver = null;
38     private FileMetadata.Builder mMetadataBuilder;
39 
40     /** Create a {@link FileMetadataCollector}. */
FileMetadataCollector()41     public FileMetadataCollector() {
42         super();
43         mMetadataBuilder = FileMetadata.newBuilder();
44     }
45 
46     /**
47      * Query proto contents for testing.
48      * @hide
49      */
50     @VisibleForTesting
getMetadataContents()51     public FileMetadata getMetadataContents() {
52         return mMetadataBuilder.build();
53     }
54 
55     @Override
testLogSaved(String dataName, LogDataType dataType, InputStreamSource source, com.android.tradefed.result.LogFile file)56     public void testLogSaved(String dataName, LogDataType dataType, InputStreamSource source,
57             com.android.tradefed.result.LogFile file) {
58         if (mDisable) {
59             return;
60         }
61 
62         LogFile log =
63                 LogFile.newBuilder().setLogType(getLogType(dataType)).setName(dataName).build();
64         mMetadataBuilder.addLogFiles(log);
65     }
66 
67     @Override
invocationEnded(long elapsedTime)68     public void invocationEnded(long elapsedTime) {
69         if (mDisable) {
70             return;
71         }
72         // Log(save) the file contents to the result directory
73         InputStreamSource source =
74                 new ByteArrayInputStreamSource(getMetadataContents().toByteArray());
75         InputStream stream = null;
76         try {
77             stream = source.createInputStream();
78             mLogSaver.saveLogDataRaw("metadata", LogDataType.TEXTPB, stream);
79         } catch (IOException e) {
80             CLog.e(e);
81             CLog.e("Failed to save metadata.");
82         } finally {
83             StreamUtil.cancel(source);
84             StreamUtil.close(stream);
85         }
86     }
87 
88     @Override
setLogSaver(ILogSaver logSaver)89     public void setLogSaver(ILogSaver logSaver) {
90         mLogSaver = logSaver;
91     }
92 
getLogType(LogDataType type)93     private LogType getLogType(LogDataType type) {
94         switch (type) {
95             case BUGREPORT:
96                 return LogType.BUGREPORT;
97             case BUGREPORTZ:
98                 return LogType.BUGREPORTZ;
99             case LOGCAT:
100                 return LogType.LOGCAT;
101             case KERNEL_LOG:
102                 return LogType.KERNEL;
103             case MEM_INFO:
104                 return LogType.MEMINFO;
105             case TOP:
106                 return LogType.TOP;
107             case DUMPSYS:
108                 return LogType.DUMPSYS;
109             case COMPACT_MEMINFO:
110                 return LogType.COMPACT_MEMINFO;
111             case SERVICES:
112                 return LogType.SERVICES;
113             case MUGSHOT_LOG:
114                 return LogType.MUGSHOT;
115             default: // All others
116                 return LogType.UNKNOWN;
117         }
118     }
119 }
120