1 /* 2 * Copyright (C) 2022 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 android.os.InputConfig; 20 import android.view.InputWindowHandle.InputConfigFlags; 21 import android.view.WindowManager.LayoutParams; 22 23 /** 24 * A helper to determine the {@link InputConfigFlags} that control the behavior of an input window 25 * from several WM attributes. 26 */ 27 class InputConfigAdapter { InputConfigAdapter()28 private InputConfigAdapter() {} 29 30 /** Describes a mapping from a flag value to a {@link InputConfigFlags} value. */ 31 private static class FlagMapping { 32 final int mFlag; 33 final int mInputConfig; 34 final boolean mInverted; 35 FlagMapping(int flag, int inputConfig, boolean inverted)36 FlagMapping(int flag, int inputConfig, boolean inverted) { 37 mFlag = flag; 38 mInputConfig = inputConfig; 39 mInverted = inverted; 40 } 41 } 42 43 /** 44 * A mapping from {@link LayoutParams.InputFeatureFlags} to {@link InputConfigFlags} for 45 * input configurations that can be mapped directly from a corresponding LayoutParams input 46 * feature. 47 */ 48 private static final FlagMapping[] INPUT_FEATURE_TO_CONFIG_MAP = { 49 new FlagMapping( 50 LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL, 51 InputConfig.NO_INPUT_CHANNEL, false /* inverted */), 52 new FlagMapping( 53 LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY, 54 InputConfig.DISABLE_USER_ACTIVITY, false /* inverted */), 55 new FlagMapping( 56 LayoutParams.INPUT_FEATURE_SPY, 57 InputConfig.SPY, false /* inverted */), 58 new FlagMapping( 59 LayoutParams.INPUT_FEATURE_SENSITIVE_FOR_PRIVACY, 60 InputConfig.SENSITIVE_FOR_PRIVACY, false /* inverted */) 61 }; 62 63 @InputConfigFlags 64 private static final int INPUT_FEATURE_TO_CONFIG_MASK = 65 computeMask(INPUT_FEATURE_TO_CONFIG_MAP); 66 67 /** 68 * A mapping from {@link LayoutParams.Flags} to {@link InputConfigFlags} for input 69 * configurations that can be mapped directly from a corresponding LayoutParams flag. 70 * 71 * NOTE: The layout params flag {@link LayoutParams#FLAG_NOT_FOCUSABLE} is not handled by this 72 * adapter, and must be handled explicitly. 73 */ 74 private static final FlagMapping[] LAYOUT_PARAM_FLAG_TO_CONFIG_MAP = { 75 new FlagMapping( 76 LayoutParams.FLAG_NOT_TOUCHABLE, 77 InputConfig.NOT_TOUCHABLE, false /* inverted */), 78 new FlagMapping( 79 LayoutParams.FLAG_SPLIT_TOUCH, 80 InputConfig.PREVENT_SPLITTING, true /* inverted */), 81 new FlagMapping( 82 LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 83 InputConfig.WATCH_OUTSIDE_TOUCH, false /* inverted */), 84 new FlagMapping( 85 LayoutParams.FLAG_SLIPPERY, 86 InputConfig.SLIPPERY, false /* inverted */) 87 }; 88 89 @InputConfigFlags 90 private static final int LAYOUT_PARAM_FLAG_TO_CONFIG_MASK = 91 computeMask(LAYOUT_PARAM_FLAG_TO_CONFIG_MAP); 92 93 /** 94 * Returns a mask of all the input config flags configured by 95 * {@link #getInputConfigFromWindowParams(int, int, int)}. 96 */ 97 @InputConfigFlags getMask()98 static int getMask() { 99 return LAYOUT_PARAM_FLAG_TO_CONFIG_MASK | INPUT_FEATURE_TO_CONFIG_MASK 100 | InputConfig.IS_WALLPAPER; 101 } 102 103 /** 104 * Get the {@link InputConfigFlags} value that provides the input window behavior specified by 105 * the given WindowManager attributes. 106 * 107 * Use {@link #getMask()} to get the mask of all the input config flags set by this method. 108 * 109 * @param type the window type 110 * @param flags the window flags 111 * @param inputFeatures the input feature flags 112 */ 113 @InputConfigFlags getInputConfigFromWindowParams(@ayoutParams.WindowType int type, @LayoutParams.Flags int flags, @LayoutParams.InputFeatureFlags int inputFeatures)114 static int getInputConfigFromWindowParams(@LayoutParams.WindowType int type, 115 @LayoutParams.Flags int flags, @LayoutParams.InputFeatureFlags int inputFeatures) { 116 return (type == LayoutParams.TYPE_WALLPAPER ? InputConfig.IS_WALLPAPER : 0) 117 | applyMapping(flags, LAYOUT_PARAM_FLAG_TO_CONFIG_MAP) 118 | applyMapping(inputFeatures, INPUT_FEATURE_TO_CONFIG_MAP); 119 } 120 121 @InputConfigFlags applyMapping(int flags, FlagMapping[] flagToConfigMap)122 private static int applyMapping(int flags, FlagMapping[] flagToConfigMap) { 123 int inputConfig = 0; 124 for (final FlagMapping mapping : flagToConfigMap) { 125 final boolean flagSet = (flags & mapping.mFlag) != 0; 126 if (flagSet != mapping.mInverted) { 127 inputConfig |= mapping.mInputConfig; 128 } 129 } 130 return inputConfig; 131 } 132 133 @InputConfigFlags computeMask(FlagMapping[] flagToConfigMap)134 private static int computeMask(FlagMapping[] flagToConfigMap) { 135 int mask = 0; 136 for (final FlagMapping mapping : flagToConfigMap) { 137 mask |= mapping.mInputConfig; 138 } 139 return mask; 140 } 141 } 142