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