1 /*
2  * Copyright (C) 2021 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.car.cts.powerpolicy;
18 
19 import java.util.ArrayList;
20 import java.util.Objects;
21 
22 public final class CpmsSystemLayerStateInfo {
23     private static final int STRING_BUILDER_BUF_SIZE = 4096;
24 
25     public static final String COMMAND = "dumpsys "
26             + "android.frameworks.automotive.powerpolicy.ICarPowerPolicyServer/default";
27     public static final String CURRENT_POLICY_ID_HDR = "Current power policy:";
28     public static final String PENDING_POLICY_ID_HDR = "Pending power policy ID:";
29     public static final String CURRENT_POLICY_GROUP_ID_HDR = "Current power policy group ID:";
30     public static final String REGISTERED_POLICIES_HDR = "Registered power policies:";
31     public static final String POLICY_GROUPS_HDR = "Power policy groups:";
32     public static final String NO_USER_INTERACTION_POLICY_HDR =
33             "No user interaction power policy:";
34     public static final String CURRENT_POWER_COMPONENTS_HDR =
35             "Current state of power components:";
36     public static final String FORCED_SILENT_MODE_HDR = "Forced silent mode:";
37 
38     private final ArrayList<String> mPolicyGroups = new ArrayList<String>();
39     private final ArrayList<PowerPolicyDef> mRegisteredPolicies;
40 
41     private final PowerPolicyDef mNoUserInteractionPolicy;
42     private final PowerPolicyDef mCurrentComponentStates;
43     private final String mCurrentPolicyId;
44     private final String mPendingPolicyId;
45     private final String mCurrentPolicyGroupId;
46     private final boolean mForcedSilentMode;
47 
CpmsSystemLayerStateInfo(String currentPolicyId, String pendingPolicyId, String currentPolicyGroupId, boolean forcedSilentMode, PowerPolicyDef noUserInteract, PowerPolicyDef currentComponents, ArrayList<PowerPolicyDef> registeredPolicies)48     private CpmsSystemLayerStateInfo(String currentPolicyId, String pendingPolicyId,
49             String currentPolicyGroupId, boolean forcedSilentMode, PowerPolicyDef noUserInteract,
50             PowerPolicyDef currentComponents, ArrayList<PowerPolicyDef> registeredPolicies) {
51         mCurrentPolicyId = currentPolicyId;
52         mPendingPolicyId = pendingPolicyId;
53         mCurrentPolicyGroupId = currentPolicyGroupId;
54         mForcedSilentMode = forcedSilentMode;
55         mNoUserInteractionPolicy = noUserInteract;
56         mCurrentComponentStates = currentComponents;
57         mRegisteredPolicies = registeredPolicies;
58     }
59 
getCurrentPolicyId()60     public String getCurrentPolicyId() {
61         return mCurrentPolicyId;
62     }
63 
getForcedSilentMode()64     public boolean getForcedSilentMode() {
65         return mForcedSilentMode;
66     }
67 
getPendingPolicyId()68     public String getPendingPolicyId() {
69         return mPendingPolicyId;
70     }
71 
getTotalRegisteredPolicies()72     public int getTotalRegisteredPolicies() {
73         return mRegisteredPolicies.size();
74     }
75 
getRegisteredPolicies()76     public ArrayList<PowerPolicyDef> getRegisteredPolicies() {
77         return mRegisteredPolicies;
78     }
79 
80     @Override
toString()81     public String toString() {
82         StringBuilder sb = new StringBuilder(STRING_BUILDER_BUF_SIZE);
83         sb.append("CpmsSystemLayerStateInfo:\n");
84         sb.append(CURRENT_POLICY_ID_HDR).append(' ').append(mCurrentPolicyId).append('\n');
85         sb.append(PENDING_POLICY_ID_HDR).append(' ').append(mPendingPolicyId).append('\n');
86         sb.append(CURRENT_POLICY_GROUP_ID_HDR).append(' ');
87         sb.append(mCurrentPolicyGroupId).append('\n');
88         sb.append(REGISTERED_POLICIES_HDR).append('\n');
89         mRegisteredPolicies.forEach(p->sb.append(p).append('\n'));
90         sb.append(NO_USER_INTERACTION_POLICY_HDR).append(' ');
91         sb.append(mNoUserInteractionPolicy).append('\n');
92         return sb.toString();
93     }
94 
95     @Override
equals(Object o)96     public boolean equals(Object o) {
97         if (this == o) return true;
98         if (o == null || getClass() != o.getClass()) return false;
99         CpmsSystemLayerStateInfo that = (CpmsSystemLayerStateInfo) o;
100         return mForcedSilentMode == that.mForcedSilentMode
101                 && mRegisteredPolicies.equals(that.mRegisteredPolicies)
102                 && mPolicyGroups.equals(that.mPolicyGroups)
103                 && Objects.equals(mNoUserInteractionPolicy, that.mNoUserInteractionPolicy)
104                 && Objects.equals(mCurrentComponentStates, that.mCurrentComponentStates)
105                 && Objects.equals(mCurrentPolicyId, that.mCurrentPolicyId)
106                 && Objects.equals(mPendingPolicyId, that.mPendingPolicyId)
107                 && Objects.equals(mCurrentPolicyGroupId, that.mCurrentPolicyGroupId);
108     }
109 
110     @Override
hashCode()111     public int hashCode() {
112         return Objects.hash(mRegisteredPolicies, mPolicyGroups, mNoUserInteractionPolicy,
113                 mCurrentComponentStates, mCurrentPolicyId, mPendingPolicyId, mCurrentPolicyGroupId,
114                 mForcedSilentMode);
115     }
116 
parse(String cmdOutput)117     public static CpmsSystemLayerStateInfo parse(String cmdOutput) throws Exception {
118         String[] lines = cmdOutput.split("\n");
119         CpmsSystemLayerStateInfoData infoData = new CpmsSystemLayerStateInfoData(lines);
120 
121         String currentPolicyId = infoData.getStringData(CURRENT_POLICY_ID_HDR);
122         String pendingPolicyId = infoData.getStringData(PENDING_POLICY_ID_HDR);
123         String currentPolicyGroupId = infoData.getStringData(CURRENT_POLICY_GROUP_ID_HDR);
124         ArrayList<PowerPolicyDef> registeredPolicies =
125                 infoData.getArrayPolicyData(REGISTERED_POLICIES_HDR, POLICY_GROUPS_HDR);
126         PowerPolicyDef noUserInteractionPolicy =
127                 infoData.getSinglePolicyData(NO_USER_INTERACTION_POLICY_HDR);
128         PowerPolicyDef currentComponentStates =
129                 infoData.getComponentStateData(CURRENT_POWER_COMPONENTS_HDR);
130         boolean forcedSilentMode = infoData.getBooleanData(FORCED_SILENT_MODE_HDR);
131 
132         return new CpmsSystemLayerStateInfo(currentPolicyId, pendingPolicyId, currentPolicyGroupId,
133                 forcedSilentMode, noUserInteractionPolicy, currentComponentStates,
134                 registeredPolicies);
135     }
136 
137     private static final class CpmsSystemLayerStateInfoData {
138         private final String[] mLines;
139         private int mIdx = 0;
140 
CpmsSystemLayerStateInfoData(String[] lines)141         private CpmsSystemLayerStateInfoData(String[]  lines) {
142             mLines = lines;
143         }
144 
getStringData(String hdr)145         private String getStringData(String hdr) throws Exception {
146             String val;
147             searchHeader(hdr);
148             if (mLines[mIdx].trim().length() == hdr.length()) {
149                 val = null;
150             } else {
151                 val = mLines[mIdx].trim().substring(hdr.length()).trim();
152             }
153             return val;
154         }
155 
getBooleanData(String hdr)156         private boolean getBooleanData(String hdr) throws Exception {
157             searchHeader(hdr);
158             return Boolean.parseBoolean(mLines[mIdx].trim().substring(hdr.length()).trim());
159         }
160 
getArrayPolicyData(String startHdr, String endHdr)161         private ArrayList<PowerPolicyDef> getArrayPolicyData(String startHdr, String endHdr)
162                 throws Exception {
163             ArrayList<PowerPolicyDef> policies = new ArrayList<PowerPolicyDef>();
164             searchHeader(startHdr);
165             while (!mLines[++mIdx].contains(endHdr)) {
166                 policies.add(PowerPolicyDef.parse(mLines[mIdx], true, 1));
167             }
168             return policies;
169         }
170 
getSinglePolicyData(String hdr)171         private PowerPolicyDef getSinglePolicyData(String hdr) throws Exception {
172             searchHeader(hdr);
173             return PowerPolicyDef.parse(mLines[mIdx].trim().substring(hdr.length()).trim(),
174                     true, 0);
175         }
176 
getComponentStateData(String hdr)177         private PowerPolicyDef getComponentStateData(String hdr) throws Exception {
178             searchHeader(hdr);
179             return PowerPolicyDef.parse(mLines[++mIdx] + " " + mLines[++mIdx], false, 0);
180         }
181 
searchHeader(String header)182         private void searchHeader(String header) throws Exception {
183             while (mIdx < mLines.length && !mLines[mIdx].contains(header)) {
184                 mIdx++;
185             }
186             if (mIdx == mLines.length) {
187                 throw new IllegalArgumentException(String.format(
188                         "CPMS dumpsys output (total %d lines) misses header: %s", mIdx, header));
189             }
190         }
191     }
192 }
193