1 /* 2 * Copyright (C) 2024 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; 18 19 import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE; 20 21 import static com.android.server.power.PowerManagerService.WAKE_LOCK_BUTTON_BRIGHT; 22 import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIGHT; 23 import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_DIM; 24 import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_TIMEOUT_OVERRIDE; 25 26 import android.annotation.IntDef; 27 import android.content.Context; 28 import android.os.PowerManager; 29 import android.util.IndentingPrintWriter; 30 import android.util.Slog; 31 32 import com.android.internal.annotations.VisibleForTesting; 33 34 import java.io.PrintWriter; 35 import java.lang.annotation.Retention; 36 import java.lang.annotation.RetentionPolicy; 37 38 /** 39 * Policy that handle the screen timeout override wake lock behavior. 40 */ 41 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 42 final class ScreenTimeoutOverridePolicy { 43 private static final String TAG = "ScreenTimeoutOverridePolicy"; 44 45 /** 46 * Release reason code: The wake lock is never acquired. 47 */ 48 public static final int RELEASE_REASON_UNKNOWN = -1; 49 50 /** 51 * Release reason code: The wake lock can't be acquired because of screen off. 52 */ 53 public static final int RELEASE_REASON_NON_INTERACTIVE = 1; 54 55 /** 56 * Release reason code: Release because a screen lock is acquired. 57 */ 58 public static final int RELEASE_REASON_SCREEN_LOCK = 2; 59 60 /** 61 * Release reason code: Release because user activity attention occurs. 62 */ 63 public static final int RELEASE_REASON_USER_ACTIVITY_ATTENTION = 3; 64 65 /** 66 * Release reason code: Release because user activity other occurs. 67 */ 68 public static final int RELEASE_REASON_USER_ACTIVITY_OTHER = 4; 69 70 /** 71 * Release reason code: Release because user activity button occurs. 72 */ 73 public static final int RELEASE_REASON_USER_ACTIVITY_BUTTON = 5; 74 75 /** 76 * Release reason code: Release because user activity touch occurs. 77 */ 78 public static final int RELEASE_REASON_USER_ACTIVITY_TOUCH = 6; 79 80 /** 81 * Release reason code: Release because user activity accessibility occurs. 82 */ 83 public static final int RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY = 7; 84 85 /** 86 * Release reason code: Release because wakelock dies. 87 */ 88 public static final int RELEASE_REASON_WAKE_LOCK_DEATH = 8; 89 90 /** 91 * @hide 92 */ 93 @IntDef(prefix = { "RELEASE_REASON_" }, value = { 94 RELEASE_REASON_UNKNOWN, 95 RELEASE_REASON_NON_INTERACTIVE, 96 RELEASE_REASON_SCREEN_LOCK, 97 RELEASE_REASON_USER_ACTIVITY_ATTENTION, 98 RELEASE_REASON_USER_ACTIVITY_OTHER, 99 RELEASE_REASON_USER_ACTIVITY_BUTTON, 100 RELEASE_REASON_USER_ACTIVITY_TOUCH, 101 RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY, 102 RELEASE_REASON_WAKE_LOCK_DEATH 103 }) 104 @Retention(RetentionPolicy.SOURCE) 105 public @interface ReleaseReason{} 106 107 // The screen timeout override config in milliseconds. 108 private long mScreenTimeoutOverrideConfig; 109 110 // The last reason that wake locks had been released by service. 111 private @ReleaseReason int mLastAutoReleaseReason = RELEASE_REASON_UNKNOWN; 112 113 interface PolicyCallback { 114 /** 115 * Notify {@link PowerManagerService} to release all override wake locks. 116 */ releaseAllScreenTimeoutOverrideWakelocks(@eleaseReason int reason)117 void releaseAllScreenTimeoutOverrideWakelocks(@ReleaseReason int reason); 118 } 119 private PolicyCallback mPolicyCallback; 120 ScreenTimeoutOverridePolicy(Context context, long minimumScreenOffTimeoutConfig, PolicyCallback callback)121 ScreenTimeoutOverridePolicy(Context context, long minimumScreenOffTimeoutConfig, 122 PolicyCallback callback) { 123 mScreenTimeoutOverrideConfig = context.getResources().getInteger( 124 com.android.internal.R.integer.config_screenTimeoutOverride); 125 if (mScreenTimeoutOverrideConfig < minimumScreenOffTimeoutConfig) { 126 Slog.w(TAG, "Screen timeout override is smaller than the minimum timeout : " 127 + mScreenTimeoutOverrideConfig); 128 mScreenTimeoutOverrideConfig = -1; 129 } 130 mPolicyCallback = callback; 131 } 132 133 /** 134 * Return the valid screen timeout override value. 135 */ getScreenTimeoutOverrideLocked(int wakeLockSummary, long screenOffTimeout)136 long getScreenTimeoutOverrideLocked(int wakeLockSummary, long screenOffTimeout) { 137 if (!isWakeLockAcquired(wakeLockSummary)) { 138 return screenOffTimeout; 139 } 140 141 if (mScreenTimeoutOverrideConfig < 0) { 142 return screenOffTimeout; 143 } 144 145 // If screen timeout overlay wake lock is acquired, return the policy timeout. 146 return Math.min(mScreenTimeoutOverrideConfig, screenOffTimeout); 147 } 148 149 /** 150 * Called when the policy have to release all wake lock when user activity occurred. 151 */ onUserActivity(int wakeLockSummary, @PowerManager.UserActivityEvent int event)152 void onUserActivity(int wakeLockSummary, @PowerManager.UserActivityEvent int event) { 153 if (!isWakeLockAcquired(wakeLockSummary)) { 154 return; 155 } 156 157 switch (event) { 158 case PowerManager.USER_ACTIVITY_EVENT_ATTENTION: 159 releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_ATTENTION); 160 return; 161 case PowerManager.USER_ACTIVITY_EVENT_OTHER: 162 releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_OTHER); 163 return; 164 case PowerManager.USER_ACTIVITY_EVENT_BUTTON: 165 releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_BUTTON); 166 return; 167 case PowerManager.USER_ACTIVITY_EVENT_TOUCH: 168 releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_TOUCH); 169 return; 170 case PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY: 171 releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY); 172 return; 173 } 174 } 175 176 /** 177 * Check the summary whether a screen wake lock acquired . 178 */ checkScreenWakeLock(int wakeLockSummary)179 void checkScreenWakeLock(int wakeLockSummary) { 180 if (!isWakeLockAcquired(wakeLockSummary)) { 181 return; 182 } 183 184 if ((wakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM 185 | WAKE_LOCK_BUTTON_BRIGHT)) != 0) { 186 releaseAllWakeLocks(RELEASE_REASON_SCREEN_LOCK); 187 } 188 } 189 190 /** 191 * Check the device is in non-interactive 192 */ onWakefulnessChange(int wakeLockSummary, int globalWakefulness)193 void onWakefulnessChange(int wakeLockSummary, int globalWakefulness) { 194 if (!isWakeLockAcquired(wakeLockSummary)) { 195 return; 196 } 197 198 if (globalWakefulness != WAKEFULNESS_AWAKE) { 199 releaseAllWakeLocks(RELEASE_REASON_NON_INTERACTIVE); 200 } 201 } 202 isWakeLockAcquired(int wakeLockSummary)203 private boolean isWakeLockAcquired(int wakeLockSummary) { 204 return (wakeLockSummary & WAKE_LOCK_SCREEN_TIMEOUT_OVERRIDE) != 0; 205 } 206 logReleaseReason()207 private void logReleaseReason() { 208 Slog.i(TAG, "Releasing all screen timeout override wake lock." 209 + " (reason=" + mLastAutoReleaseReason + ")"); 210 } 211 releaseAllWakeLocks(@eleaseReason int reason)212 private void releaseAllWakeLocks(@ReleaseReason int reason) { 213 mPolicyCallback.releaseAllScreenTimeoutOverrideWakelocks(reason); 214 mLastAutoReleaseReason = reason; 215 logReleaseReason(); 216 } 217 dump(PrintWriter pw)218 void dump(PrintWriter pw) { 219 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 220 221 ipw.println(); 222 ipw.println("ScreenTimeoutOverridePolicy:"); 223 ipw.increaseIndent(); 224 225 ipw.println("mScreenTimeoutOverrideConfig=" + mScreenTimeoutOverrideConfig); 226 ipw.println("mLastAutoReleaseReason=" + mLastAutoReleaseReason); 227 } 228 } 229