1 /*
2  * Copyright (C) 2019 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.internal.os;
17 
18 import android.util.ArrayMap;
19 import android.util.Slog;
20 
21 import java.util.Map;
22 
23 /** Rail Stats Power Monitoring Class */
24 public final class RailStats {
25     private static final String TAG = "RailStats";
26 
27     private static final String WIFI_SUBSYSTEM = "wifi";
28     private static final String CELLULAR_SUBSYSTEM = "cellular";
29 
30     private Map<Long, RailInfoData> mRailInfoData = new ArrayMap<>();
31 
32     private long mCellularTotalEnergyUseduWs = 0;
33     private long mWifiTotalEnergyUseduWs = 0;
34     private boolean mRailStatsAvailability = true;
35 
36     /** Updates the rail data map of all power monitor rails being monitored
37      * Function is called from native side
38      * @param index
39      * @param railName
40      * @param subSystemName
41      * @param timestampSinceBootMs
42      * @param energyUsedSinceBootuWs
43      */
updateRailData(long index, String railName, String subSystemName, long timestampSinceBootMs, long energyUsedSinceBootuWs)44     public void updateRailData(long index, String railName, String subSystemName,
45             long timestampSinceBootMs, long energyUsedSinceBootuWs) {
46         if (!(subSystemName.equals(WIFI_SUBSYSTEM) || subSystemName.equals(CELLULAR_SUBSYSTEM))) {
47             return;
48         }
49         RailInfoData node = mRailInfoData.get(index);
50         if (node == null) {
51             mRailInfoData.put(index, new RailInfoData(index, railName, subSystemName,
52                     timestampSinceBootMs, energyUsedSinceBootuWs));
53             if (subSystemName.equals(WIFI_SUBSYSTEM)) {
54                 mWifiTotalEnergyUseduWs += energyUsedSinceBootuWs;
55                 return;
56             }
57             if (subSystemName.equals(CELLULAR_SUBSYSTEM)) {
58                 mCellularTotalEnergyUseduWs += energyUsedSinceBootuWs;
59             }
60             return;
61         }
62         long timeSinceLastLogMs = timestampSinceBootMs - node.timestampSinceBootMs;
63         long energyUsedSinceLastLoguWs = energyUsedSinceBootuWs - node.energyUsedSinceBootuWs;
64         if (timeSinceLastLogMs < 0 || energyUsedSinceLastLoguWs < 0) {
65             energyUsedSinceLastLoguWs = node.energyUsedSinceBootuWs;
66         }
67         node.timestampSinceBootMs = timestampSinceBootMs;
68         node.energyUsedSinceBootuWs = energyUsedSinceBootuWs;
69         if (subSystemName.equals(WIFI_SUBSYSTEM)) {
70             mWifiTotalEnergyUseduWs += energyUsedSinceLastLoguWs;
71             return;
72         }
73         if (subSystemName.equals(CELLULAR_SUBSYSTEM)) {
74             mCellularTotalEnergyUseduWs += energyUsedSinceLastLoguWs;
75         }
76     }
77 
78     /** resets the cellular total energy used aspect.
79      */
resetCellularTotalEnergyUsed()80     public void resetCellularTotalEnergyUsed() {
81         mCellularTotalEnergyUseduWs = 0;
82     }
83 
84     /** resets the wifi total energy used aspect.
85      */
resetWifiTotalEnergyUsed()86     public void resetWifiTotalEnergyUsed() {
87         mWifiTotalEnergyUseduWs = 0;
88     }
89 
getCellularTotalEnergyUseduWs()90     public long getCellularTotalEnergyUseduWs() {
91         return mCellularTotalEnergyUseduWs;
92     }
93 
getWifiTotalEnergyUseduWs()94     public long getWifiTotalEnergyUseduWs() {
95         return mWifiTotalEnergyUseduWs;
96     }
97 
98     /** reset the total energy subsystems
99      *
100      */
reset()101     public void reset() {
102         mCellularTotalEnergyUseduWs = 0;
103         mWifiTotalEnergyUseduWs = 0;
104     }
105 
getRailStats()106     public RailStats getRailStats() {
107         return this;
108     }
109 
setRailStatsAvailability(boolean railStatsAvailability)110     public void setRailStatsAvailability(boolean railStatsAvailability) {
111         mRailStatsAvailability = railStatsAvailability;
112     }
113 
isRailStatsAvailable()114     public boolean isRailStatsAvailable() {
115         return mRailStatsAvailability;
116     }
117 
118     /** Container class to contain rail data information */
119     public static class RailInfoData {
120         private static final String TAG = "RailInfoData";
121         public long index;
122         public String railName;
123         public String subSystemName;
124         public long timestampSinceBootMs;
125         public long energyUsedSinceBootuWs;
126 
RailInfoData(long index, String railName, String subSystemName, long timestampSinceBootMs, long energyUsedSinceBoot)127         private RailInfoData(long index, String railName, String subSystemName,
128                 long timestampSinceBootMs, long energyUsedSinceBoot) {
129             this.index = index;
130             this.railName = railName;
131             this.subSystemName = subSystemName;
132             this.timestampSinceBootMs = timestampSinceBootMs;
133             this.energyUsedSinceBootuWs = energyUsedSinceBoot;
134         }
135 
136         /** print the rail data
137          *
138          */
printData()139         public void printData() {
140             Slog.d(TAG, "Index = " + index);
141             Slog.d(TAG, "RailName = " + railName);
142             Slog.d(TAG, "SubSystemName = " + subSystemName);
143             Slog.d(TAG, "TimestampSinceBootMs = " + timestampSinceBootMs);
144             Slog.d(TAG, "EnergyUsedSinceBootuWs = " + energyUsedSinceBootuWs);
145         }
146     }
147 }
148