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 17 package com.android.server.wm; 18 19 import static android.provider.AndroidDeviceConfig.KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE; 20 import static android.provider.AndroidDeviceConfig.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP; 21 22 import android.provider.AndroidDeviceConfig; 23 import android.provider.DeviceConfig; 24 25 import com.android.internal.annotations.VisibleForTesting; 26 import com.android.server.wm.utils.DeviceConfigInterface; 27 28 import java.io.PrintWriter; 29 import java.util.Objects; 30 import java.util.concurrent.Executor; 31 32 /** 33 * Settings constants that can modify the window manager's behavior. 34 */ 35 final class WindowManagerConstants { 36 37 /** 38 * The minimum duration between gesture exclusion logging for a given window in 39 * milliseconds. 40 * 41 * Events that happen in-between will be silently dropped. 42 * 43 * A non-positive value disables logging. 44 * 45 * <p>Note: On Devices running Q, this key is in the "android:window_manager" namespace. 46 * 47 * @see android.provider.DeviceConfig#NAMESPACE_WINDOW_MANAGER 48 */ 49 static final String KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS = 50 "system_gesture_exclusion_log_debounce_millis"; 51 52 private static final int MIN_GESTURE_EXCLUSION_LIMIT_DP = 200; 53 54 /** @see #KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS */ 55 long mSystemGestureExclusionLogDebounceTimeoutMillis; 56 /** @see AndroidDeviceConfig#KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP */ 57 int mSystemGestureExclusionLimitDp; 58 /** @see AndroidDeviceConfig#KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE */ 59 boolean mSystemGestureExcludedByPreQStickyImmersive; 60 61 private final WindowManagerGlobalLock mGlobalLock; 62 private final Runnable mUpdateSystemGestureExclusionCallback; 63 private final DeviceConfigInterface mDeviceConfig; 64 private final DeviceConfig.OnPropertiesChangedListener mListenerAndroid; 65 private final DeviceConfig.OnPropertiesChangedListener mListenerWindowManager; 66 WindowManagerConstants(WindowManagerService service, DeviceConfigInterface deviceConfig)67 WindowManagerConstants(WindowManagerService service, DeviceConfigInterface deviceConfig) { 68 this(service.mGlobalLock, () -> service.mRoot.forAllDisplays( 69 DisplayContent::updateSystemGestureExclusionLimit), deviceConfig); 70 } 71 72 @VisibleForTesting WindowManagerConstants(WindowManagerGlobalLock globalLock, Runnable updateSystemGestureExclusionCallback, DeviceConfigInterface deviceConfig)73 WindowManagerConstants(WindowManagerGlobalLock globalLock, 74 Runnable updateSystemGestureExclusionCallback, 75 DeviceConfigInterface deviceConfig) { 76 mGlobalLock = Objects.requireNonNull(globalLock); 77 mUpdateSystemGestureExclusionCallback = Objects.requireNonNull(updateSystemGestureExclusionCallback); 78 mDeviceConfig = deviceConfig; 79 mListenerAndroid = this::onAndroidPropertiesChanged; 80 mListenerWindowManager = this::onWindowPropertiesChanged; 81 } 82 start(Executor executor)83 void start(Executor executor) { 84 mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ANDROID, executor, 85 mListenerAndroid); 86 mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER, 87 executor, mListenerWindowManager); 88 89 updateSystemGestureExclusionLogDebounceMillis(); 90 updateSystemGestureExclusionLimitDp(); 91 updateSystemGestureExcludedByPreQStickyImmersive(); 92 } 93 94 @VisibleForTesting dispose()95 void dispose() { 96 mDeviceConfig.removeOnPropertiesChangedListener(mListenerAndroid); 97 mDeviceConfig.removeOnPropertiesChangedListener(mListenerWindowManager); 98 } 99 onAndroidPropertiesChanged(DeviceConfig.Properties properties)100 private void onAndroidPropertiesChanged(DeviceConfig.Properties properties) { 101 synchronized (mGlobalLock) { 102 boolean updateSystemGestureExclusionLimit = false; 103 for (String name : properties.getKeyset()) { 104 if (name == null) { 105 return; 106 } 107 switch (name) { 108 case KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP: 109 updateSystemGestureExclusionLimitDp(); 110 updateSystemGestureExclusionLimit = true; 111 break; 112 case KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE: 113 updateSystemGestureExcludedByPreQStickyImmersive(); 114 updateSystemGestureExclusionLimit = true; 115 break; 116 default: 117 break; 118 } 119 } 120 if (updateSystemGestureExclusionLimit) { 121 mUpdateSystemGestureExclusionCallback.run(); 122 } 123 } 124 } 125 onWindowPropertiesChanged(DeviceConfig.Properties properties)126 private void onWindowPropertiesChanged(DeviceConfig.Properties properties) { 127 synchronized (mGlobalLock) { 128 for (String name : properties.getKeyset()) { 129 if (name == null) { 130 return; 131 } 132 switch (name) { 133 case KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS: 134 updateSystemGestureExclusionLogDebounceMillis(); 135 break; 136 default: 137 break; 138 } 139 } 140 } 141 } 142 updateSystemGestureExclusionLogDebounceMillis()143 private void updateSystemGestureExclusionLogDebounceMillis() { 144 mSystemGestureExclusionLogDebounceTimeoutMillis = 145 mDeviceConfig.getLong(DeviceConfig.NAMESPACE_WINDOW_MANAGER, 146 KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS, 0); 147 } 148 updateSystemGestureExclusionLimitDp()149 private void updateSystemGestureExclusionLimitDp() { 150 mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP, 151 mDeviceConfig.getInt(DeviceConfig.NAMESPACE_ANDROID, 152 KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0)); 153 } 154 updateSystemGestureExcludedByPreQStickyImmersive()155 private void updateSystemGestureExcludedByPreQStickyImmersive() { 156 mSystemGestureExcludedByPreQStickyImmersive = mDeviceConfig.getBoolean( 157 DeviceConfig.NAMESPACE_ANDROID, 158 KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false); 159 } 160 dump(PrintWriter pw)161 void dump(PrintWriter pw) { 162 pw.println("WINDOW MANAGER CONSTANTS (dumpsys window constants):"); 163 164 pw.print(" "); pw.print(KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS); 165 pw.print("="); pw.println(mSystemGestureExclusionLogDebounceTimeoutMillis); 166 pw.print(" "); pw.print(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP); 167 pw.print("="); pw.println(mSystemGestureExclusionLimitDp); 168 pw.print(" "); pw.print(KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE); 169 pw.print("="); pw.println(mSystemGestureExcludedByPreQStickyImmersive); 170 pw.println(); 171 } 172 } 173