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 
17 package android.support.test.aupt;
18 
19 import android.app.Instrumentation;
20 import android.util.Log;
21 
22 import java.io.File;
23 import java.io.IOException;
24 
25 enum LogGenerator {
26     BUGREPORT(new BugreportGenerator()),
27     BUGREPORTZ(new BugreportzGenerator()),
28     GRAPHICS_STATS(new GraphicsGenerator()),
29     MEM_INFO(new CompactMemInfoGenerator()),
30     CPU_INFO(new CpuInfoGenerator()),
31     FRAGMENTATION(new FragmentationGenerator()),
32     ION_HEAP(new IonHeapGenerator()),
33     PAGETYPE_INFO(new PageTypeInfoGenerator()),
34     TRACE(new TraceGenerator());
35 
36     private static final String TAG = "AuptDataCollector";
37 
38     /** Save the output of a process to a log file with the given name template. */
saveLog( Instrumentation instr, String command, String template)39     private static void saveLog(
40             Instrumentation instr,
41             String command,
42             String template) throws IOException {
43         FilesystemUtil.saveProcessOutput(
44             instr,
45             command,
46             new File(FilesystemUtil.templateToFilename(template)));
47     }
48 
49     /* Generator Types */
50 
51     protected interface Generator {
save(Instrumentation instr, String logDir)52         void save(Instrumentation instr, String logDir)
53                 throws IOException, InterruptedException;
54     }
55 
56     private static class CompactMemInfoGenerator implements Generator {
57         @Override
save(Instrumentation instr, String logDir)58         public void save(Instrumentation instr, String logDir)
59                 throws IOException, InterruptedException {
60             try {
61                 saveLog(instr, "dumpsys meminfo -c -S", logDir + "/compact-meminfo-%s.txt");
62             } catch (IOException ioe) {
63                 Log.w(TAG, "Error while saving dumpsys meminfo -c: " + ioe.getMessage());
64             }
65         }
66     }
67 
68     private static class CpuInfoGenerator implements Generator {
69         @Override
save(Instrumentation instr, String logDir)70         public void save(Instrumentation instr, String logDir)
71                 throws IOException, InterruptedException {
72             try {
73                 saveLog(instr, "dumpsys cpuinfo", logDir + "/cpuinfo-%s.txt");
74             } catch (IOException ioe) {
75                 Log.w(TAG, "Error while saving dumpsys cpuinfo : " + ioe.getMessage());
76             }
77         }
78     }
79 
80     private static class BugreportGenerator implements Generator {
81         @Override
save(Instrumentation instr, String logDir)82         public void save(Instrumentation instr, String logDir)
83                 throws IOException, InterruptedException {
84             try {
85                 FilesystemUtil.saveBugreport(instr, logDir + "/bugreport-%s.txt");
86             } catch (IOException e) {
87                 Log.w(TAG, String.format("Failed to take bugreport: %s", e.getMessage()));
88             }
89         }
90     }
91 
92     private static class BugreportzGenerator implements Generator {
93         @Override
save(Instrumentation instr, String logDir)94         public void save(Instrumentation instr, String logDir)
95                 throws IOException, InterruptedException {
96             try {
97                 FilesystemUtil.saveBugreportz(instr);
98             } catch (IOException e) {
99                 Log.w(TAG, String.format("Failed to take bugreport: %s", e.getMessage()));
100             }
101         }
102     }
103 
104     private static class FragmentationGenerator implements Generator {
105         @Override
save(Instrumentation instr, String logDir)106         public void save(Instrumentation instr, String logDir)
107                 throws IOException, InterruptedException {
108             try {
109                 saveLog(instr, "cat /d/extfrag/unusable_index", logDir + "/unusable-index-%s.txt");
110             } catch (IOException e) {
111                 Log.w(TAG, String.format("Failed to save frangmentation: %s", e.getMessage()));
112             }
113         }
114     }
115 
116     private static class GraphicsGenerator implements Generator {
117         @Override
save(Instrumentation instr, String logDir)118         public void save(Instrumentation instr, String logDir)
119                 throws IOException, InterruptedException {
120             try {
121                 saveLog(instr, "dumpsys graphicsstats", logDir + "/graphics-%s.txt");
122             } catch (IOException e) {
123                 Log.w(TAG, String.format("Failed to save graphicsstats: %s", e.getMessage()));
124             }
125         }
126     }
127 
128     private static class IonHeapGenerator implements Generator {
129         @Override
save(Instrumentation instr, String logDir)130         public void save(Instrumentation instr, String logDir)
131                 throws IOException, InterruptedException {
132             try {
133                 saveLog(instr, "cat /d/ion/heaps/audio", logDir + "/ion-audio-%s.txt");
134                 saveLog(instr, "cat /d/ion/heaps/system", logDir + "/ion-system-%s.txt");
135             } catch (IOException e) {
136                 Log.w(TAG, String.format("Failed to save ION heap: %s", e.getMessage()));
137             }
138         }
139     }
140 
141     private static class PageTypeInfoGenerator implements Generator {
142         @Override
save(Instrumentation instr, String logDir)143         public void save(Instrumentation instr, String logDir)
144                 throws IOException, InterruptedException {
145             try {
146                 saveLog(instr, "cat /proc/pagetypeinfo", logDir + "/pagetypeinfo-%s.txt");
147             } catch (IOException e) {
148                 Log.w(TAG, String.format("Failed to save pagetypeinfo: %s", e.getMessage()));
149             }
150         }
151     }
152 
153     private static class TraceGenerator implements Generator {
154         @Override
save(Instrumentation instr, String logDir)155         public void save(Instrumentation instr, String logDir)
156                 throws IOException, InterruptedException {
157             try {
158                 saveLog(instr, "cat /sys/kernel/debug/tracing/trace", logDir + "/trace-%s.txt");
159             } catch (IOException e) {
160                 Log.w(TAG, String.format("Failed to save trace: %s", e.getMessage()));
161             }
162         }
163     }
164 
165     // Individual LogGenerator instance methods
166     private final Generator mGenerator;
167 
LogGenerator(Generator generator)168     LogGenerator (Generator generator) {
169         mGenerator = generator;
170     }
171 
save(Instrumentation instr, String logDir)172     public void save(Instrumentation instr, String logDir)
173             throws IOException, InterruptedException {
174         mGenerator.save(instr, logDir);
175     }
176 }
177