• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 android.view;
18 
19 import android.annotation.IntDef;
20 import android.annotation.Nullable;
21 import android.graphics.Matrix;
22 import android.graphics.Region;
23 import android.gui.TouchOcclusionMode;
24 import android.os.IBinder;
25 import android.os.InputConfig;
26 
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 import java.lang.ref.WeakReference;
30 
31 /**
32  * Functions as a handle for a window that can receive input, and allows for the behavior of the
33  * input window to be configured.
34  * @hide
35  */
36 public final class InputWindowHandle {
37 
38     /**
39      * An internal annotation for all the {@link android.os.InputConfig} flags that can be
40      * specified to {@link #inputConfig} to control the behavior of an input window. Only the
41      * flags listed here are valid for use in Java.
42      *
43      * The default flag value is 0, which is what we expect for a normal application window. Adding
44      * a flag indicates that the window's behavior deviates from that of a normal application
45      * window.
46      *
47      * The flags are defined as an AIDL enum to keep it in sync with native code.
48      * {@link android.os.InputConfig} flags that are not listed here should not be used in Java, and
49      * are only meant to be used in native code.
50      */
51     @Retention(RetentionPolicy.SOURCE)
52     @IntDef(flag = true, value = {
53             InputConfig.DEFAULT,
54             InputConfig.NO_INPUT_CHANNEL,
55             InputConfig.NOT_FOCUSABLE,
56             InputConfig.NOT_TOUCHABLE,
57             InputConfig.PREVENT_SPLITTING,
58             InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER,
59             InputConfig.IS_WALLPAPER,
60             InputConfig.PAUSE_DISPATCHING,
61             InputConfig.TRUSTED_OVERLAY,
62             InputConfig.WATCH_OUTSIDE_TOUCH,
63             InputConfig.SLIPPERY,
64             InputConfig.DISABLE_USER_ACTIVITY,
65             InputConfig.SPY,
66             InputConfig.INTERCEPTS_STYLUS,
67     })
68     public @interface InputConfigFlags {}
69 
70     // Pointer to the native input window handle.
71     // This field is lazily initialized via JNI.
72     @SuppressWarnings("unused")
73     private long ptr;
74 
75     // The input application handle.
76     public InputApplicationHandle inputApplicationHandle;
77 
78     // The token associates input data with a window and its input channel. The client input
79     // channel and the server input channel will both contain this token.
80     public IBinder token;
81 
82     /**
83      * The {@link IWindow} handle if InputWindowHandle is associated with a window, null otherwise.
84      */
85     @Nullable
86     private IBinder windowToken;
87     /**
88      * Used to cache IWindow from the windowToken so we don't need to convert every time getWindow
89      * is called.
90      */
91     private IWindow window;
92 
93     // The window name.
94     public String name;
95 
96     // Window layout params attributes. (WindowManager.LayoutParams)
97     // These values do not affect any input configurations. Use {@link #inputConfig} instead.
98     public int layoutParamsFlags;
99     public int layoutParamsType;
100 
101     // Dispatching timeout.
102     public long dispatchingTimeoutMillis;
103 
104     // Window frame.
105     public int frameLeft;
106     public int frameTop;
107     public int frameRight;
108     public int frameBottom;
109 
110     public int surfaceInset;
111 
112     // Global scaling factor applied to touch events when they are dispatched
113     // to the window
114     public float scaleFactor;
115 
116     // Window touchable region.
117     public final Region touchableRegion = new Region();
118 
119     // Flags that specify the behavior of this input window. See {@link #InputConfigFlags}.
120     @InputConfigFlags
121     public int inputConfig;
122 
123     // What effect this window has on touch occlusion if it lets touches pass through
124     // By default windows will block touches if they are untrusted and from a different UID due to
125     // security concerns
126     public int touchOcclusionMode = TouchOcclusionMode.BLOCK_UNTRUSTED;
127 
128     // Id of process and user that owns the window.
129     public int ownerPid;
130     public int ownerUid;
131 
132     // Owner package of the window
133     public String packageName;
134 
135     // Display this input window is on.
136     public int displayId;
137 
138     /**
139      * Crops the {@link #touchableRegion} to the bounds of the surface provided.
140      *
141      * This can be used in cases where the window should be constrained to the bounds of a parent
142      * window. That is, the window should receive touch events outside its window frame, but be
143      * limited to its stack bounds, such as in the case of split screen.
144      */
145     public WeakReference<SurfaceControl> touchableRegionSurfaceControl = new WeakReference<>(null);
146 
147     /**
148      * Replace {@link #touchableRegion} with the bounds of {@link #touchableRegionSurfaceControl}.
149      * If the handle is {@code null}, the bounds of the surface associated with this window is used
150      * as the touchable region.
151      */
152     public boolean replaceTouchableRegionWithCrop;
153 
154     /**
155      * The transform that should be applied to the Window to get it from screen coordinates to
156      * window coordinates
157      */
158     public Matrix transform;
159 
160     /**
161      * Whether this window is a clone or the original window.
162      */
163     public boolean isClone;
164 
nativeDispose()165     private native void nativeDispose();
166 
InputWindowHandle(InputApplicationHandle inputApplicationHandle, int displayId)167     public InputWindowHandle(InputApplicationHandle inputApplicationHandle, int displayId) {
168         this.inputApplicationHandle = inputApplicationHandle;
169         this.displayId = displayId;
170     }
171 
InputWindowHandle(InputWindowHandle other)172     public InputWindowHandle(InputWindowHandle other) {
173         // Do not copy ptr to prevent this copy from sharing the same native object.
174         ptr = 0;
175         inputApplicationHandle = new InputApplicationHandle(other.inputApplicationHandle);
176         token = other.token;
177         windowToken = other.windowToken;
178         window = other.window;
179         name = other.name;
180         layoutParamsFlags = other.layoutParamsFlags;
181         layoutParamsType = other.layoutParamsType;
182         dispatchingTimeoutMillis = other.dispatchingTimeoutMillis;
183         frameLeft = other.frameLeft;
184         frameTop = other.frameTop;
185         frameRight = other.frameRight;
186         frameBottom = other.frameBottom;
187         surfaceInset = other.surfaceInset;
188         scaleFactor = other.scaleFactor;
189         touchableRegion.set(other.touchableRegion);
190         inputConfig = other.inputConfig;
191         touchOcclusionMode = other.touchOcclusionMode;
192         ownerPid = other.ownerPid;
193         ownerUid = other.ownerUid;
194         packageName = other.packageName;
195         displayId = other.displayId;
196         touchableRegionSurfaceControl = other.touchableRegionSurfaceControl;
197         replaceTouchableRegionWithCrop = other.replaceTouchableRegionWithCrop;
198         if (other.transform != null) {
199             transform = new Matrix();
200             transform.set(other.transform);
201         }
202     }
203 
204     @Override
toString()205     public String toString() {
206         return new StringBuilder(name != null ? name : "")
207                 .append(", frame=[").append(frameLeft).append(",").append(frameTop).append(",")
208                         .append(frameRight).append(",").append(frameBottom).append("]")
209                 .append(", touchableRegion=").append(touchableRegion)
210                 .append(", scaleFactor=").append(scaleFactor)
211                 .append(", transform=").append(transform)
212                 .append(", windowToken=").append(windowToken)
213                 .append(", isClone=").append(isClone)
214                 .toString();
215 
216     }
217 
218     @Override
finalize()219     protected void finalize() throws Throwable {
220         try {
221             nativeDispose();
222         } finally {
223             super.finalize();
224         }
225     }
226 
227     /**
228      * Set the window's touchable region to the bounds of {@link #touchableRegionSurfaceControl}
229      * and ignore the value of {@link #touchableRegion}.
230      *
231      * @param bounds surface to set the touchable region to. Set to {@code null} to set the
232      *               touchable region as the current surface bounds.
233      */
replaceTouchableRegionWithCrop(@ullable SurfaceControl bounds)234     public void replaceTouchableRegionWithCrop(@Nullable SurfaceControl bounds) {
235         setTouchableRegionCrop(bounds);
236         replaceTouchableRegionWithCrop = true;
237     }
238 
239     /**
240      * Crop the window touchable region to the bounds of the surface provided.
241      */
setTouchableRegionCrop(@ullable SurfaceControl bounds)242     public void setTouchableRegionCrop(@Nullable SurfaceControl bounds) {
243         touchableRegionSurfaceControl = new WeakReference<>(bounds);
244     }
245 
setWindowToken(IWindow iwindow)246     public void setWindowToken(IWindow iwindow) {
247         windowToken = iwindow.asBinder();
248         window = iwindow;
249     }
250 
getWindow()251     public IWindow getWindow() {
252         if (window != null) {
253             return window;
254         }
255         window = IWindow.Stub.asInterface(windowToken);
256         return window;
257     }
258 
259     /**
260      * Set the provided inputConfig flag values.
261      * @param inputConfig the flag values to change
262      * @param value the provided flag values are set when true, and cleared when false
263      */
setInputConfig(@nputConfigFlags int inputConfig, boolean value)264     public void setInputConfig(@InputConfigFlags int inputConfig, boolean value) {
265         if (value) {
266             this.inputConfig |= inputConfig;
267             return;
268         }
269         this.inputConfig &= ~inputConfig;
270     }
271 }
272