blob: e4135b5584e46779c74008c27a64d8117bec0011 [file] [log] [blame]
Mat Bevilacqua81601212020-07-30 17:26:45 -07001/*
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
17package com.android.server.powerstats;
18
19import java.io.FileInputStream;
20import java.io.IOException;
21
22/**
23 * This class implements a utility to parse ODPM data out
24 * of incident reports contained in bugreports. The data
25 * is output to STDOUT in csv format.
26 */
27public class PowerStatsServiceProtoParser {
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070028 private static void printEnergyMeterInfo(PowerStatsServiceMeterProto proto) {
Mat Bevilacqua81601212020-07-30 17:26:45 -070029 String csvHeader = new String();
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080030 for (int i = 0; i < proto.getChannelCount(); i++) {
31 ChannelProto energyMeterInfo = proto.getChannel(i);
32 csvHeader += "Index,Timestamp,Duration," + energyMeterInfo.getId()
33 + "/" + energyMeterInfo.getName() + ",";
Mat Bevilacqua81601212020-07-30 17:26:45 -070034 }
35 System.out.println(csvHeader);
36 }
37
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070038 private static void printEnergyMeasurements(PowerStatsServiceMeterProto proto) {
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080039 int energyMeterInfoCount = proto.getChannelCount();
Mat Bevilacqua81601212020-07-30 17:26:45 -070040
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070041 if (energyMeterInfoCount > 0) {
42 int energyMeasurementCount = proto.getEnergyMeasurementCount();
43 int energyMeasurementSetCount = energyMeasurementCount / energyMeterInfoCount;
Mat Bevilacqua81601212020-07-30 17:26:45 -070044
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070045 for (int i = 0; i < energyMeasurementSetCount; i++) {
Mat Bevilacqua81601212020-07-30 17:26:45 -070046 String csvRow = new String();
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070047 for (int j = 0; j < energyMeterInfoCount; j++) {
48 EnergyMeasurementProto energyMeasurement =
49 proto.getEnergyMeasurement(i * energyMeterInfoCount + j);
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080050 csvRow += energyMeasurement.getId() + ","
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070051 + energyMeasurement.getTimestampMs() + ","
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080052 + energyMeasurement.getDurationMs() + ","
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070053 + energyMeasurement.getEnergyUws() + ",";
Mat Bevilacqua81601212020-07-30 17:26:45 -070054 }
55 System.out.println(csvRow);
56 }
57 } else {
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070058 System.out.println("Error: energyMeterInfoCount is zero");
59 }
60 }
61
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080062 private static void printEnergyConsumer(PowerStatsServiceModelProto proto) {
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070063 String csvHeader = new String();
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080064 for (int i = 0; i < proto.getEnergyConsumerCount(); i++) {
65 EnergyConsumerProto energyConsumer = proto.getEnergyConsumer(i);
66 csvHeader += "Index,Timestamp," + energyConsumer.getId() + "/"
67 + energyConsumer.getOrdinal() + "/"
68 + energyConsumer.getType() + "/"
69 + energyConsumer.getName() + ",";
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070070 }
71 System.out.println(csvHeader);
72 }
73
74 private static void printEnergyConsumerResults(PowerStatsServiceModelProto proto) {
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080075 int energyConsumerCount = proto.getEnergyConsumerCount();
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070076
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080077 if (energyConsumerCount > 0) {
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070078 int energyConsumerResultCount = proto.getEnergyConsumerResultCount();
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080079 int energyConsumerResultSetCount = energyConsumerResultCount / energyConsumerCount;
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070080
81 for (int i = 0; i < energyConsumerResultSetCount; i++) {
82 String csvRow = new String();
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080083 for (int j = 0; j < energyConsumerCount; j++) {
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070084 EnergyConsumerResultProto energyConsumerResult =
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080085 proto.getEnergyConsumerResult(i * energyConsumerCount + j);
86 csvRow += energyConsumerResult.getId() + ","
Mat Bevilacquaa375ea02020-09-21 18:59:06 -070087 + energyConsumerResult.getTimestampMs() + ","
88 + energyConsumerResult.getEnergyUws() + ",";
89 }
90 System.out.println(csvRow);
91 }
92 } else {
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080093 System.out.println("Error: energyConsumerCount is zero");
Mat Bevilacqua81601212020-07-30 17:26:45 -070094 }
95 }
96
Mat Bevilacqua723784a2020-12-22 09:57:01 -080097 private static void printPowerEntityInfo(PowerStatsServiceResidencyProto proto) {
98 String csvHeader = new String();
Mat Bevilacqua6058dc22021-01-20 17:45:20 -080099 for (int i = 0; i < proto.getPowerEntityCount(); i++) {
100 PowerEntityProto powerEntity = proto.getPowerEntity(i);
101 csvHeader += powerEntity.getId() + "," + powerEntity.getName() + ",";
102 for (int j = 0; j < powerEntity.getStatesCount(); j++) {
103 StateProto state = powerEntity.getStates(j);
104 csvHeader += state.getId() + "," + state.getName() + ",";
Mat Bevilacqua723784a2020-12-22 09:57:01 -0800105 }
106 }
107 System.out.println(csvHeader);
108 }
109
110 private static void printStateResidencyResult(PowerStatsServiceResidencyProto proto) {
111 for (int i = 0; i < proto.getStateResidencyResultCount(); i++) {
112 String csvRow = new String();
113
114 StateResidencyResultProto stateResidencyResult = proto.getStateResidencyResult(i);
Mat Bevilacqua6058dc22021-01-20 17:45:20 -0800115 csvRow += stateResidencyResult.getId() + ",";
Mat Bevilacqua723784a2020-12-22 09:57:01 -0800116
117 for (int j = 0; j < stateResidencyResult.getStateResidencyDataCount(); j++) {
118 StateResidencyProto stateResidency = stateResidencyResult.getStateResidencyData(j);
Mat Bevilacqua6058dc22021-01-20 17:45:20 -0800119 csvRow += stateResidency.getId() + ","
Mat Bevilacqua723784a2020-12-22 09:57:01 -0800120 + stateResidency.getTotalTimeInStateMs() + ","
121 + stateResidency.getTotalStateEntryCount() + ","
122 + stateResidency.getLastEntryTimestampMs() + ",";
123 }
124 System.out.println(csvRow);
125 }
126 }
127
Mat Bevilacqua81601212020-07-30 17:26:45 -0700128 private static void generateCsvFile(String pathToIncidentReport) {
129 try {
Mat Bevilacquaa375ea02020-09-21 18:59:06 -0700130 // Print power meter data.
131 IncidentReportMeterProto irMeterProto =
132 IncidentReportMeterProto.parseFrom(new FileInputStream(pathToIncidentReport));
Mat Bevilacqua81601212020-07-30 17:26:45 -0700133
Mat Bevilacquaa375ea02020-09-21 18:59:06 -0700134 if (irMeterProto.hasIncidentReport()) {
135 PowerStatsServiceMeterProto pssMeterProto = irMeterProto.getIncidentReport();
136 printEnergyMeterInfo(pssMeterProto);
137 printEnergyMeasurements(pssMeterProto);
Mat Bevilacqua81601212020-07-30 17:26:45 -0700138 } else {
Mat Bevilacquaa375ea02020-09-21 18:59:06 -0700139 System.out.println("Meter incident report not found. Exiting.");
140 }
141
142 // Print power model data.
143 IncidentReportModelProto irModelProto =
144 IncidentReportModelProto.parseFrom(new FileInputStream(pathToIncidentReport));
145
146 if (irModelProto.hasIncidentReport()) {
147 PowerStatsServiceModelProto pssModelProto = irModelProto.getIncidentReport();
Mat Bevilacqua6058dc22021-01-20 17:45:20 -0800148 printEnergyConsumer(pssModelProto);
Mat Bevilacquaa375ea02020-09-21 18:59:06 -0700149 printEnergyConsumerResults(pssModelProto);
150 } else {
151 System.out.println("Model incident report not found. Exiting.");
Mat Bevilacqua81601212020-07-30 17:26:45 -0700152 }
Mat Bevilacqua723784a2020-12-22 09:57:01 -0800153
154 // Print state residency data.
155 IncidentReportResidencyProto irResidencyProto =
156 IncidentReportResidencyProto.parseFrom(
157 new FileInputStream(pathToIncidentReport));
158
159 if (irResidencyProto.hasIncidentReport()) {
160 PowerStatsServiceResidencyProto pssResidencyProto =
161 irResidencyProto.getIncidentReport();
162 printPowerEntityInfo(pssResidencyProto);
163 printStateResidencyResult(pssResidencyProto);
164 } else {
165 System.out.println("Residency incident report not found. Exiting.");
166 }
167
Mat Bevilacqua81601212020-07-30 17:26:45 -0700168 } catch (IOException e) {
169 System.out.println("Unable to open incident report file: " + pathToIncidentReport);
170 System.out.println(e);
171 }
172 }
173
174 /**
175 * This is the entry point to parse the ODPM data out of incident reports.
176 * It requires one argument which is the path to the incident_report.proto
177 * file captured in a bugreport.
178 *
179 * @param args Path to incident_report.proto passed in from command line.
180 */
181 public static void main(String[] args) {
182 if (args.length > 0) {
183 generateCsvFile(args[0]);
184 } else {
185 System.err.println("Usage: PowerStatsServiceProtoParser <incident_report.proto>");
186 System.err.println("Missing path to incident_report.proto. Exiting.");
187 System.exit(1);
188 }
189 }
190}