xref: /aosp_15_r20/frameworks/base/tools/powerstats/PowerStatsServiceProtoParser.java (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker package com.android.server.powerstats;
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker import java.io.FileInputStream;
20*d57664e9SAndroid Build Coastguard Worker import java.io.IOException;
21*d57664e9SAndroid Build Coastguard Worker 
22*d57664e9SAndroid Build Coastguard Worker /**
23*d57664e9SAndroid Build Coastguard Worker  * This class implements a utility to parse ODPM data out
24*d57664e9SAndroid Build Coastguard Worker  * of incident reports contained in bugreports.  The data
25*d57664e9SAndroid Build Coastguard Worker  * is output to STDOUT in csv format.
26*d57664e9SAndroid Build Coastguard Worker  */
27*d57664e9SAndroid Build Coastguard Worker public class PowerStatsServiceProtoParser {
printEnergyMeterInfo(PowerStatsServiceMeterProto proto)28*d57664e9SAndroid Build Coastguard Worker     private static void printEnergyMeterInfo(PowerStatsServiceMeterProto proto) {
29*d57664e9SAndroid Build Coastguard Worker         String csvHeader = new String();
30*d57664e9SAndroid Build Coastguard Worker         for (int i = 0; i < proto.getChannelCount(); i++) {
31*d57664e9SAndroid Build Coastguard Worker             ChannelProto energyMeterInfo = proto.getChannel(i);
32*d57664e9SAndroid Build Coastguard Worker             csvHeader += "Index,Timestamp,Duration," + energyMeterInfo.getId()
33*d57664e9SAndroid Build Coastguard Worker                 + "/" + energyMeterInfo.getName() + "/" + energyMeterInfo.getSubsystem() + ",";
34*d57664e9SAndroid Build Coastguard Worker         }
35*d57664e9SAndroid Build Coastguard Worker         System.out.println(csvHeader);
36*d57664e9SAndroid Build Coastguard Worker     }
37*d57664e9SAndroid Build Coastguard Worker 
printEnergyMeasurements(PowerStatsServiceMeterProto proto)38*d57664e9SAndroid Build Coastguard Worker     private static void printEnergyMeasurements(PowerStatsServiceMeterProto proto) {
39*d57664e9SAndroid Build Coastguard Worker         int energyMeterInfoCount = proto.getChannelCount();
40*d57664e9SAndroid Build Coastguard Worker 
41*d57664e9SAndroid Build Coastguard Worker         if (energyMeterInfoCount > 0) {
42*d57664e9SAndroid Build Coastguard Worker             int energyMeasurementCount = proto.getEnergyMeasurementCount();
43*d57664e9SAndroid Build Coastguard Worker             int energyMeasurementSetCount = energyMeasurementCount / energyMeterInfoCount;
44*d57664e9SAndroid Build Coastguard Worker 
45*d57664e9SAndroid Build Coastguard Worker             for (int i = 0; i < energyMeasurementSetCount; i++) {
46*d57664e9SAndroid Build Coastguard Worker                 String csvRow = new String();
47*d57664e9SAndroid Build Coastguard Worker                 for (int j = 0; j < energyMeterInfoCount; j++) {
48*d57664e9SAndroid Build Coastguard Worker                     EnergyMeasurementProto energyMeasurement =
49*d57664e9SAndroid Build Coastguard Worker                             proto.getEnergyMeasurement(i * energyMeterInfoCount + j);
50*d57664e9SAndroid Build Coastguard Worker                     csvRow += energyMeasurement.getId() + ","
51*d57664e9SAndroid Build Coastguard Worker                         + energyMeasurement.getTimestampMs() + ","
52*d57664e9SAndroid Build Coastguard Worker                         + energyMeasurement.getDurationMs() + ","
53*d57664e9SAndroid Build Coastguard Worker                         + energyMeasurement.getEnergyUws() + ",";
54*d57664e9SAndroid Build Coastguard Worker                 }
55*d57664e9SAndroid Build Coastguard Worker                 System.out.println(csvRow);
56*d57664e9SAndroid Build Coastguard Worker             }
57*d57664e9SAndroid Build Coastguard Worker         } else {
58*d57664e9SAndroid Build Coastguard Worker             System.out.println("Error:  energyMeterInfoCount is zero");
59*d57664e9SAndroid Build Coastguard Worker         }
60*d57664e9SAndroid Build Coastguard Worker     }
61*d57664e9SAndroid Build Coastguard Worker 
printEnergyConsumer(PowerStatsServiceModelProto proto)62*d57664e9SAndroid Build Coastguard Worker     private static void printEnergyConsumer(PowerStatsServiceModelProto proto) {
63*d57664e9SAndroid Build Coastguard Worker         String csvHeader = new String();
64*d57664e9SAndroid Build Coastguard Worker         for (int i = 0; i < proto.getEnergyConsumerCount(); i++) {
65*d57664e9SAndroid Build Coastguard Worker             EnergyConsumerProto energyConsumer = proto.getEnergyConsumer(i);
66*d57664e9SAndroid Build Coastguard Worker             csvHeader += "Index,Timestamp," + energyConsumer.getId() + "/"
67*d57664e9SAndroid Build Coastguard Worker                 + energyConsumer.getOrdinal() + "/"
68*d57664e9SAndroid Build Coastguard Worker                 + energyConsumer.getType() + "/"
69*d57664e9SAndroid Build Coastguard Worker                 + energyConsumer.getName() + ",";
70*d57664e9SAndroid Build Coastguard Worker         }
71*d57664e9SAndroid Build Coastguard Worker         System.out.println(csvHeader);
72*d57664e9SAndroid Build Coastguard Worker     }
73*d57664e9SAndroid Build Coastguard Worker 
printEnergyConsumerResults(PowerStatsServiceModelProto proto)74*d57664e9SAndroid Build Coastguard Worker     private static void printEnergyConsumerResults(PowerStatsServiceModelProto proto) {
75*d57664e9SAndroid Build Coastguard Worker         int energyConsumerCount = proto.getEnergyConsumerCount();
76*d57664e9SAndroid Build Coastguard Worker 
77*d57664e9SAndroid Build Coastguard Worker         if (energyConsumerCount > 0) {
78*d57664e9SAndroid Build Coastguard Worker             int energyConsumerResultCount = proto.getEnergyConsumerResultCount();
79*d57664e9SAndroid Build Coastguard Worker             int energyConsumerResultSetCount = energyConsumerResultCount / energyConsumerCount;
80*d57664e9SAndroid Build Coastguard Worker 
81*d57664e9SAndroid Build Coastguard Worker             for (int i = 0; i < energyConsumerResultSetCount; i++) {
82*d57664e9SAndroid Build Coastguard Worker                 String csvRow = new String();
83*d57664e9SAndroid Build Coastguard Worker                 for (int j = 0; j < energyConsumerCount; j++) {
84*d57664e9SAndroid Build Coastguard Worker                     EnergyConsumerResultProto energyConsumerResult =
85*d57664e9SAndroid Build Coastguard Worker                             proto.getEnergyConsumerResult(i * energyConsumerCount + j);
86*d57664e9SAndroid Build Coastguard Worker                     csvRow += energyConsumerResult.getId() + ","
87*d57664e9SAndroid Build Coastguard Worker                         + energyConsumerResult.getTimestampMs() + ","
88*d57664e9SAndroid Build Coastguard Worker                         + energyConsumerResult.getEnergyUws() + ",";
89*d57664e9SAndroid Build Coastguard Worker                     for (int k = 0; k < energyConsumerResult.getAttributionCount(); k++) {
90*d57664e9SAndroid Build Coastguard Worker                         final EnergyConsumerAttributionProto energyConsumerAttribution =
91*d57664e9SAndroid Build Coastguard Worker                                 energyConsumerResult.getAttribution(k);
92*d57664e9SAndroid Build Coastguard Worker                         csvRow += energyConsumerAttribution.getUid() + ","
93*d57664e9SAndroid Build Coastguard Worker                             + energyConsumerAttribution.getEnergyUws() + ",";
94*d57664e9SAndroid Build Coastguard Worker                     }
95*d57664e9SAndroid Build Coastguard Worker                 }
96*d57664e9SAndroid Build Coastguard Worker                 System.out.println(csvRow);
97*d57664e9SAndroid Build Coastguard Worker             }
98*d57664e9SAndroid Build Coastguard Worker         } else {
99*d57664e9SAndroid Build Coastguard Worker             System.out.println("Error:  energyConsumerCount is zero");
100*d57664e9SAndroid Build Coastguard Worker         }
101*d57664e9SAndroid Build Coastguard Worker     }
102*d57664e9SAndroid Build Coastguard Worker 
printPowerEntityInfo(PowerStatsServiceResidencyProto proto)103*d57664e9SAndroid Build Coastguard Worker     private static void printPowerEntityInfo(PowerStatsServiceResidencyProto proto) {
104*d57664e9SAndroid Build Coastguard Worker         String csvHeader = new String();
105*d57664e9SAndroid Build Coastguard Worker         for (int i = 0; i < proto.getPowerEntityCount(); i++) {
106*d57664e9SAndroid Build Coastguard Worker             PowerEntityProto powerEntity = proto.getPowerEntity(i);
107*d57664e9SAndroid Build Coastguard Worker             csvHeader += powerEntity.getId() + "," + powerEntity.getName() + ",";
108*d57664e9SAndroid Build Coastguard Worker             for (int j = 0; j < powerEntity.getStatesCount(); j++) {
109*d57664e9SAndroid Build Coastguard Worker                 StateProto state = powerEntity.getStates(j);
110*d57664e9SAndroid Build Coastguard Worker                 csvHeader += state.getId() + "," + state.getName() + ",";
111*d57664e9SAndroid Build Coastguard Worker             }
112*d57664e9SAndroid Build Coastguard Worker         }
113*d57664e9SAndroid Build Coastguard Worker         System.out.println(csvHeader);
114*d57664e9SAndroid Build Coastguard Worker     }
115*d57664e9SAndroid Build Coastguard Worker 
printStateResidencyResult(PowerStatsServiceResidencyProto proto)116*d57664e9SAndroid Build Coastguard Worker     private static void printStateResidencyResult(PowerStatsServiceResidencyProto proto) {
117*d57664e9SAndroid Build Coastguard Worker         for (int i = 0; i < proto.getStateResidencyResultCount(); i++) {
118*d57664e9SAndroid Build Coastguard Worker             String csvRow = new String();
119*d57664e9SAndroid Build Coastguard Worker 
120*d57664e9SAndroid Build Coastguard Worker             StateResidencyResultProto stateResidencyResult = proto.getStateResidencyResult(i);
121*d57664e9SAndroid Build Coastguard Worker             csvRow += stateResidencyResult.getId() + ",";
122*d57664e9SAndroid Build Coastguard Worker 
123*d57664e9SAndroid Build Coastguard Worker             for (int j = 0; j < stateResidencyResult.getStateResidencyDataCount(); j++) {
124*d57664e9SAndroid Build Coastguard Worker                 StateResidencyProto stateResidency = stateResidencyResult.getStateResidencyData(j);
125*d57664e9SAndroid Build Coastguard Worker                 csvRow += stateResidency.getId() + ","
126*d57664e9SAndroid Build Coastguard Worker                     + stateResidency.getTotalTimeInStateMs() + ","
127*d57664e9SAndroid Build Coastguard Worker                     + stateResidency.getTotalStateEntryCount() + ","
128*d57664e9SAndroid Build Coastguard Worker                     + stateResidency.getLastEntryTimestampMs() + ",";
129*d57664e9SAndroid Build Coastguard Worker             }
130*d57664e9SAndroid Build Coastguard Worker             System.out.println(csvRow);
131*d57664e9SAndroid Build Coastguard Worker         }
132*d57664e9SAndroid Build Coastguard Worker     }
133*d57664e9SAndroid Build Coastguard Worker 
generateCsvFile(String pathToIncidentReport)134*d57664e9SAndroid Build Coastguard Worker     private static void generateCsvFile(String pathToIncidentReport) {
135*d57664e9SAndroid Build Coastguard Worker         try {
136*d57664e9SAndroid Build Coastguard Worker             // Print power meter data.
137*d57664e9SAndroid Build Coastguard Worker             IncidentReportMeterProto irMeterProto =
138*d57664e9SAndroid Build Coastguard Worker                     IncidentReportMeterProto.parseFrom(new FileInputStream(pathToIncidentReport));
139*d57664e9SAndroid Build Coastguard Worker 
140*d57664e9SAndroid Build Coastguard Worker             if (irMeterProto.hasIncidentReport()) {
141*d57664e9SAndroid Build Coastguard Worker                 PowerStatsServiceMeterProto pssMeterProto = irMeterProto.getIncidentReport();
142*d57664e9SAndroid Build Coastguard Worker                 printEnergyMeterInfo(pssMeterProto);
143*d57664e9SAndroid Build Coastguard Worker                 printEnergyMeasurements(pssMeterProto);
144*d57664e9SAndroid Build Coastguard Worker             } else {
145*d57664e9SAndroid Build Coastguard Worker                 System.out.println("Meter incident report not found.  Exiting.");
146*d57664e9SAndroid Build Coastguard Worker             }
147*d57664e9SAndroid Build Coastguard Worker 
148*d57664e9SAndroid Build Coastguard Worker             // Print power model data.
149*d57664e9SAndroid Build Coastguard Worker             IncidentReportModelProto irModelProto =
150*d57664e9SAndroid Build Coastguard Worker                     IncidentReportModelProto.parseFrom(new FileInputStream(pathToIncidentReport));
151*d57664e9SAndroid Build Coastguard Worker 
152*d57664e9SAndroid Build Coastguard Worker             if (irModelProto.hasIncidentReport()) {
153*d57664e9SAndroid Build Coastguard Worker                 PowerStatsServiceModelProto pssModelProto = irModelProto.getIncidentReport();
154*d57664e9SAndroid Build Coastguard Worker                 printEnergyConsumer(pssModelProto);
155*d57664e9SAndroid Build Coastguard Worker                 printEnergyConsumerResults(pssModelProto);
156*d57664e9SAndroid Build Coastguard Worker             } else {
157*d57664e9SAndroid Build Coastguard Worker                 System.out.println("Model incident report not found.  Exiting.");
158*d57664e9SAndroid Build Coastguard Worker             }
159*d57664e9SAndroid Build Coastguard Worker 
160*d57664e9SAndroid Build Coastguard Worker             // Print state residency data.
161*d57664e9SAndroid Build Coastguard Worker             IncidentReportResidencyProto irResidencyProto =
162*d57664e9SAndroid Build Coastguard Worker                     IncidentReportResidencyProto.parseFrom(
163*d57664e9SAndroid Build Coastguard Worker                         new FileInputStream(pathToIncidentReport));
164*d57664e9SAndroid Build Coastguard Worker 
165*d57664e9SAndroid Build Coastguard Worker             if (irResidencyProto.hasIncidentReport()) {
166*d57664e9SAndroid Build Coastguard Worker                 PowerStatsServiceResidencyProto pssResidencyProto =
167*d57664e9SAndroid Build Coastguard Worker                         irResidencyProto.getIncidentReport();
168*d57664e9SAndroid Build Coastguard Worker                 printPowerEntityInfo(pssResidencyProto);
169*d57664e9SAndroid Build Coastguard Worker                 printStateResidencyResult(pssResidencyProto);
170*d57664e9SAndroid Build Coastguard Worker             } else {
171*d57664e9SAndroid Build Coastguard Worker                 System.out.println("Residency incident report not found.  Exiting.");
172*d57664e9SAndroid Build Coastguard Worker             }
173*d57664e9SAndroid Build Coastguard Worker 
174*d57664e9SAndroid Build Coastguard Worker         } catch (IOException e) {
175*d57664e9SAndroid Build Coastguard Worker             System.out.println("Unable to open incident report file: " + pathToIncidentReport);
176*d57664e9SAndroid Build Coastguard Worker             System.out.println(e);
177*d57664e9SAndroid Build Coastguard Worker         }
178*d57664e9SAndroid Build Coastguard Worker     }
179*d57664e9SAndroid Build Coastguard Worker 
180*d57664e9SAndroid Build Coastguard Worker     /**
181*d57664e9SAndroid Build Coastguard Worker      * This is the entry point to parse the ODPM data out of incident reports.
182*d57664e9SAndroid Build Coastguard Worker      * It requires one argument which is the path to the incident_report.proto
183*d57664e9SAndroid Build Coastguard Worker      * file captured in a bugreport.
184*d57664e9SAndroid Build Coastguard Worker      *
185*d57664e9SAndroid Build Coastguard Worker      * @param args Path to incident_report.proto passed in from command line.
186*d57664e9SAndroid Build Coastguard Worker      */
main(String[] args)187*d57664e9SAndroid Build Coastguard Worker     public static void main(String[] args) {
188*d57664e9SAndroid Build Coastguard Worker         if (args.length > 0) {
189*d57664e9SAndroid Build Coastguard Worker             generateCsvFile(args[0]);
190*d57664e9SAndroid Build Coastguard Worker         } else {
191*d57664e9SAndroid Build Coastguard Worker             System.err.println("Usage: PowerStatsServiceProtoParser <incident_report.proto>");
192*d57664e9SAndroid Build Coastguard Worker             System.err.println("Missing path to incident_report.proto.  Exiting.");
193*d57664e9SAndroid Build Coastguard Worker             System.exit(1);
194*d57664e9SAndroid Build Coastguard Worker         }
195*d57664e9SAndroid Build Coastguard Worker     }
196*d57664e9SAndroid Build Coastguard Worker }
197