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