• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 com.android.server.power.feature;
18 
19 import android.os.Build;
20 import android.os.SystemProperties;
21 import android.text.TextUtils;
22 import android.util.Slog;
23 
24 import com.android.server.power.feature.flags.Flags;
25 
26 import java.io.PrintWriter;
27 import java.util.function.Supplier;
28 
29 /**
30  * Utility class to read the flags used in the power manager server.
31  */
32 public class PowerManagerFlags {
33     private static final boolean DEBUG = false;
34     private static final String TAG = "PowerManagerFlags";
35 
36     private final FlagState mEarlyScreenTimeoutDetectorFlagState = new FlagState(
37             Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR,
38             Flags::enableEarlyScreenTimeoutDetector);
39 
40     private final FlagState mEnableScreenTimeoutPolicyListenerApi = new FlagState(
41             Flags.FLAG_ENABLE_SCREEN_TIMEOUT_POLICY_LISTENER_API,
42             Flags::enableScreenTimeoutPolicyListenerApi
43     );
44 
45     private final FlagState mImproveWakelockLatency = new FlagState(
46             Flags.FLAG_IMPROVE_WAKELOCK_LATENCY,
47             Flags::improveWakelockLatency
48     );
49 
50     private final FlagState mPerDisplayWakeByTouch = new FlagState(
51             Flags.FLAG_PER_DISPLAY_WAKE_BY_TOUCH,
52             Flags::perDisplayWakeByTouch
53     );
54 
55     private final FlagState mFrameworkWakelockInfo =
56             new FlagState(Flags.FLAG_FRAMEWORK_WAKELOCK_INFO, Flags::frameworkWakelockInfo);
57 
58     private final FlagState mPolicyReasonInDisplayPowerRequest = new FlagState(
59             Flags.FLAG_POLICY_REASON_IN_DISPLAY_POWER_REQUEST,
60             Flags::policyReasonInDisplayPowerRequest
61     );
62 
63     private final FlagState mMoveWscLoggingToNotifier =
64             new FlagState(Flags.FLAG_MOVE_WSC_LOGGING_TO_NOTIFIER, Flags::moveWscLoggingToNotifier);
65 
66     private final FlagState mWakelockAttributionViaWorkchain =
67             new FlagState(Flags.FLAG_WAKELOCK_ATTRIBUTION_VIA_WORKCHAIN,
68                     Flags::wakelockAttributionViaWorkchain);
69 
70     private final FlagState mDisableFrozenProcessWakelocks =
71             new FlagState(Flags.FLAG_DISABLE_FROZEN_PROCESS_WAKELOCKS,
72                     Flags::disableFrozenProcessWakelocks);
73 
74     /** Returns whether early-screen-timeout-detector is enabled on not. */
isEarlyScreenTimeoutDetectorEnabled()75     public boolean isEarlyScreenTimeoutDetectorEnabled() {
76         return mEarlyScreenTimeoutDetectorFlagState.isEnabled();
77     }
78 
79     /** Returns whether screen timeout policy listener APIs are enabled on not. */
isScreenTimeoutPolicyListenerApiEnabled()80     public boolean isScreenTimeoutPolicyListenerApiEnabled() {
81         return mEnableScreenTimeoutPolicyListenerApi.isEnabled();
82     }
83 
84     /**
85      * @return Whether to improve the wakelock acquire/release latency or not
86      */
improveWakelockLatency()87     public boolean improveWakelockLatency() {
88         return mImproveWakelockLatency.isEnabled();
89     }
90 
91     /**
92      * @return Whether per-display wake by touch is enabled or not.
93      */
isPerDisplayWakeByTouchEnabled()94     public boolean isPerDisplayWakeByTouchEnabled() {
95         return mPerDisplayWakeByTouch.isEnabled();
96     }
97 
98     /**
99      * @return Whether FrameworkWakelockInfo atom logging is enabled or not.
100      */
isFrameworkWakelockInfoEnabled()101     public boolean isFrameworkWakelockInfoEnabled() {
102         return mFrameworkWakelockInfo.isEnabled();
103     }
104 
105     /**
106      * @return Whether the wakefulness reason is populated in DisplayPowerRequest.
107      */
isPolicyReasonInDisplayPowerRequestEnabled()108     public boolean isPolicyReasonInDisplayPowerRequestEnabled() {
109         return mPolicyReasonInDisplayPowerRequest.isEnabled();
110     }
111 
112     /**
113      * @return Whether we move WakelockStateChanged atom logging to Notifier (enabled) or leave it
114      *     in BatteryStatsImpl (disabled).
115      */
isMoveWscLoggingToNotifierEnabled()116     public boolean isMoveWscLoggingToNotifierEnabled() {
117         return mMoveWscLoggingToNotifier.isEnabled();
118     }
119 
120     /**
121      * @return Whether the wakelock attribution via workchain is enabled
122      */
isWakelockAttributionViaWorkchainEnabled()123     public boolean isWakelockAttributionViaWorkchainEnabled() {
124         return mWakelockAttributionViaWorkchain.isEnabled();
125     }
126 
127     /**
128      * @return Whether the feature to disable the frozen process wakelocks is enabled
129      */
isDisableFrozenProcessWakelocksEnabled()130     public boolean isDisableFrozenProcessWakelocksEnabled() {
131         return mDisableFrozenProcessWakelocks.isEnabled();
132     }
133 
134     /**
135      * dumps all flagstates
136      * @param pw printWriter
137      */
dump(PrintWriter pw)138     public void dump(PrintWriter pw) {
139         pw.println("PowerManagerFlags:");
140         pw.println(" " + mEarlyScreenTimeoutDetectorFlagState);
141         pw.println(" " + mImproveWakelockLatency);
142         pw.println(" " + mPerDisplayWakeByTouch);
143         pw.println(" " + mFrameworkWakelockInfo);
144         pw.println(" " + mMoveWscLoggingToNotifier);
145         pw.println(" " + mWakelockAttributionViaWorkchain);
146         pw.println(" " + mDisableFrozenProcessWakelocks);
147     }
148 
149     private static class FlagState {
150 
151         private final String mName;
152 
153         private final Supplier<Boolean> mFlagFunction;
154         private boolean mEnabledSet;
155         private boolean mEnabled;
156 
FlagState(String name, Supplier<Boolean> flagFunction)157         private FlagState(String name, Supplier<Boolean> flagFunction) {
158             mName = name;
159             mFlagFunction = flagFunction;
160         }
161 
isEnabled()162         private boolean isEnabled() {
163             if (mEnabledSet) {
164                 if (DEBUG) {
165                     Slog.d(TAG, mName + ": mEnabled. Recall = " + mEnabled);
166                 }
167                 return mEnabled;
168             }
169             mEnabled = flagOrSystemProperty(mFlagFunction, mName);
170             if (DEBUG) {
171                 Slog.d(TAG, mName + ": mEnabled. Flag value = " + mEnabled);
172             }
173             mEnabledSet = true;
174             return mEnabled;
175         }
176 
flagOrSystemProperty(Supplier<Boolean> flagFunction, String flagName)177         private boolean flagOrSystemProperty(Supplier<Boolean> flagFunction, String flagName) {
178             boolean flagValue = flagFunction.get();
179             if (Build.IS_ENG || Build.IS_USERDEBUG) {
180                 return SystemProperties.getBoolean("persist.sys." + flagName + "-override",
181                         flagValue);
182             }
183             return flagValue;
184         }
185 
186         @Override
toString()187         public String toString() {
188             // remove com.android.server.power.feature.flags. from the beginning of the name.
189             // align all isEnabled() values.
190             // Adjust lengths if we end up with longer names
191             final int nameLength = mName.length();
192             return TextUtils.substring(mName,  39, nameLength) + ": "
193                     + TextUtils.formatSimple("%" + (91 - nameLength) + "s%s", " " , isEnabled())
194                     + " (def:" + mFlagFunction.get() + ")";
195         }
196     }
197 }
198