blob: a5ebf9ac74b9b21b156ad594e88e2abed66f0a3d [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wm;
import static android.provider.AndroidDeviceConfig.KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE;
import static android.provider.AndroidDeviceConfig.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP;
import android.provider.AndroidDeviceConfig;
import android.provider.DeviceConfig;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.utils.DeviceConfigInterface;
import java.io.PrintWriter;
import java.util.Objects;
import java.util.concurrent.Executor;
/**
* Settings constants that can modify the window manager's behavior.
*/
final class WindowManagerConstants {
/**
* The minimum duration between gesture exclusion logging for a given window in
* milliseconds.
*
* Events that happen in-between will be silently dropped.
*
* A non-positive value disables logging.
*
* <p>Note: On Devices running Q, this key is in the "android:window_manager" namespace.
*
* @see android.provider.DeviceConfig#NAMESPACE_WINDOW_MANAGER
*/
static final String KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS =
"system_gesture_exclusion_log_debounce_millis";
private static final int MIN_GESTURE_EXCLUSION_LIMIT_DP = 200;
/** @see #KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS */
long mSystemGestureExclusionLogDebounceTimeoutMillis;
/** @see AndroidDeviceConfig#KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP */
int mSystemGestureExclusionLimitDp;
/** @see AndroidDeviceConfig#KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE */
boolean mSystemGestureExcludedByPreQStickyImmersive;
private final WindowManagerGlobalLock mGlobalLock;
private final Runnable mUpdateSystemGestureExclusionCallback;
private final DeviceConfigInterface mDeviceConfig;
private final DeviceConfig.OnPropertiesChangedListener mListenerAndroid;
private final DeviceConfig.OnPropertiesChangedListener mListenerWindowManager;
WindowManagerConstants(WindowManagerService service, DeviceConfigInterface deviceConfig) {
this(service.mGlobalLock, () -> service.mRoot.forAllDisplays(
DisplayContent::updateSystemGestureExclusionLimit), deviceConfig);
}
@VisibleForTesting
WindowManagerConstants(WindowManagerGlobalLock globalLock,
Runnable updateSystemGestureExclusionCallback,
DeviceConfigInterface deviceConfig) {
mGlobalLock = Objects.requireNonNull(globalLock);
mUpdateSystemGestureExclusionCallback = Objects.requireNonNull(updateSystemGestureExclusionCallback);
mDeviceConfig = deviceConfig;
mListenerAndroid = this::onAndroidPropertiesChanged;
mListenerWindowManager = this::onWindowPropertiesChanged;
}
void start(Executor executor) {
mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ANDROID, executor,
mListenerAndroid);
mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
executor, mListenerWindowManager);
updateSystemGestureExclusionLogDebounceMillis();
updateSystemGestureExclusionLimitDp();
updateSystemGestureExcludedByPreQStickyImmersive();
}
@VisibleForTesting
void dispose() {
mDeviceConfig.removeOnPropertiesChangedListener(mListenerAndroid);
mDeviceConfig.removeOnPropertiesChangedListener(mListenerWindowManager);
}
private void onAndroidPropertiesChanged(DeviceConfig.Properties properties) {
synchronized (mGlobalLock) {
boolean updateSystemGestureExclusionLimit = false;
for (String name : properties.getKeyset()) {
if (name == null) {
return;
}
switch (name) {
case KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP:
updateSystemGestureExclusionLimitDp();
updateSystemGestureExclusionLimit = true;
break;
case KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE:
updateSystemGestureExcludedByPreQStickyImmersive();
updateSystemGestureExclusionLimit = true;
break;
default:
break;
}
}
if (updateSystemGestureExclusionLimit) {
mUpdateSystemGestureExclusionCallback.run();
}
}
}
private void onWindowPropertiesChanged(DeviceConfig.Properties properties) {
synchronized (mGlobalLock) {
for (String name : properties.getKeyset()) {
if (name == null) {
return;
}
switch (name) {
case KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS:
updateSystemGestureExclusionLogDebounceMillis();
break;
default:
break;
}
}
}
}
private void updateSystemGestureExclusionLogDebounceMillis() {
mSystemGestureExclusionLogDebounceTimeoutMillis =
mDeviceConfig.getLong(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS, 0);
}
private void updateSystemGestureExclusionLimitDp() {
mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
mDeviceConfig.getInt(DeviceConfig.NAMESPACE_ANDROID,
KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
}
private void updateSystemGestureExcludedByPreQStickyImmersive() {
mSystemGestureExcludedByPreQStickyImmersive = mDeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ANDROID,
KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
}
void dump(PrintWriter pw) {
pw.println("WINDOW MANAGER CONSTANTS (dumpsys window constants):");
pw.print(" "); pw.print(KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS);
pw.print("="); pw.println(mSystemGestureExclusionLogDebounceTimeoutMillis);
pw.print(" "); pw.print(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP);
pw.print("="); pw.println(mSystemGestureExclusionLimitDp);
pw.print(" "); pw.print(KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE);
pw.print("="); pw.println(mSystemGestureExcludedByPreQStickyImmersive);
pw.println();
}
}