• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.NonNull;
20 import android.annotation.Nullable;
21 import android.app.WindowConfiguration;
22 import android.content.res.Configuration;
23 import android.graphics.PixelFormat;
24 import android.graphics.Rect;
25 import android.graphics.Region;
26 import android.os.Bundle;
27 import android.os.IBinder;
28 import android.os.RemoteCallback;
29 import android.os.RemoteException;
30 import android.util.Log;
31 import android.util.MergedConfiguration;
32 import android.view.View.FocusDirection;
33 import android.view.WindowInsets.Type.InsetsType;
34 import android.window.ClientWindowFrames;
35 import android.window.InputTransferToken;
36 import android.window.OnBackInvokedCallbackInfo;
37 
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Objects;
41 
42 /**
43 * A simplistic implementation of IWindowSession. Rather than managing Surfaces
44 * as children of the display, it manages Surfaces as children of a given root.
45 *
46 * By parcelling the root surface, the app can offer another app content for embedding.
47 * @hide
48 */
49 public class WindowlessWindowManager implements IWindowSession {
50     private final static String TAG = "WindowlessWindowManager";
51 
52     private class State {
53         SurfaceControl mSurfaceControl;
54         final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
55         final WindowManager.LayoutParams mLastReportedParams = new WindowManager.LayoutParams();
56         int mDisplayId;
57         IBinder mInputChannelToken;
58         Region mInputRegion;
59         IWindow mClient;
60         SurfaceControl mLeash;
61         Rect mFrame;
62         Rect mAttachedFrame;
63         InputTransferToken mInputTransferToken;
64 
State(SurfaceControl sc, WindowManager.LayoutParams p, int displayId, IWindow client, SurfaceControl leash, Rect frame)65         State(SurfaceControl sc, WindowManager.LayoutParams p, int displayId, IWindow client,
66                 SurfaceControl leash, Rect frame) {
67             mSurfaceControl = sc;
68             mParams.copyFrom(p);
69             mDisplayId = displayId;
70             mClient = client;
71             mLeash = leash;
72             mFrame = frame;
73         }
74     };
75 
76     /**
77      * Used to store SurfaceControl we've built for clients to
78      * reconfigure them if relayout is called.
79      */
80     final HashMap<IBinder, State> mStateForWindow = new HashMap<IBinder, State>();
81 
82     public interface ResizeCompleteCallback {
finished(SurfaceControl.Transaction completion)83         public void finished(SurfaceControl.Transaction completion);
84     }
85 
86     final HashMap<IBinder, ResizeCompleteCallback> mResizeCompletionForWindow =
87         new HashMap<IBinder, ResizeCompleteCallback>();
88 
89     private final SurfaceSession mSurfaceSession = new SurfaceSession();
90     protected final SurfaceControl mRootSurface;
91     private final Configuration mConfiguration;
92     private final IWindowSession mRealWm;
93     final InputTransferToken mHostInputTransferToken;
94     private final InputTransferToken mInputTransferToken = new InputTransferToken();
95     private InsetsState mInsetsState;
96     private final ClientWindowFrames mTmpFrames = new ClientWindowFrames();
97     private final MergedConfiguration mTmpConfig = new MergedConfiguration();
98     private final WindowlessWindowLayout mLayout = new WindowlessWindowLayout();
99 
100     private ISurfaceControlViewHostParent mParentInterface;
101 
WindowlessWindowManager(Configuration c, SurfaceControl rootSurface, InputTransferToken hostInputTransferToken)102     public WindowlessWindowManager(Configuration c, SurfaceControl rootSurface,
103             InputTransferToken hostInputTransferToken) {
104         mRootSurface = rootSurface;
105         mConfiguration = new Configuration(c);
106         mRealWm = WindowManagerGlobal.getWindowSession();
107         mHostInputTransferToken = hostInputTransferToken;
108     }
109 
setConfiguration(Configuration configuration)110     public void setConfiguration(Configuration configuration) {
111         mConfiguration.setTo(configuration);
112     }
113 
getInputTransferToken(IBinder window)114     InputTransferToken getInputTransferToken(IBinder window) {
115         synchronized (this) {
116             // This can only happen if someone requested the focusGrantToken before setView was
117             // called for the SCVH. In that case, use the root focusGrantToken since this will be
118             // the same token sent to WMS for the root window once setView is called.
119             if (mStateForWindow.isEmpty()) {
120                 return mInputTransferToken;
121             }
122             State state = mStateForWindow.get(window);
123             if (state != null) {
124                 return state.mInputTransferToken;
125             }
126         }
127 
128         Log.w(TAG, "Failed to get focusGrantToken. Returning null token");
129         return null;
130     }
131 
132     /**
133      * Utility API.
134      */
setCompletionCallback(IBinder window, ResizeCompleteCallback callback)135     void setCompletionCallback(IBinder window, ResizeCompleteCallback callback) {
136         if (mResizeCompletionForWindow.get(window) != null) {
137             Log.w(TAG, "Unsupported overlapping resizes");
138         }
139         mResizeCompletionForWindow.put(window, callback);
140     }
141 
setTouchRegion(IBinder window, @Nullable Region region)142     protected void setTouchRegion(IBinder window, @Nullable Region region) {
143         State state;
144         synchronized (this) {
145             // Do everything while locked so that we synchronize with relayout. This should be a
146             // very infrequent operation.
147             state = mStateForWindow.get(window);
148             if (state == null) {
149                 return;
150             }
151             if (Objects.equals(region, state.mInputRegion)) {
152                 return;
153             }
154             state.mInputRegion = region != null ? new Region(region) : null;
155             if (state.mInputChannelToken != null) {
156                 try {
157                     mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
158                             state.mSurfaceControl, state.mParams.flags, state.mParams.privateFlags,
159                             state.mParams.inputFeatures, state.mInputRegion);
160                 } catch (RemoteException e) {
161                     Log.e(TAG, "Failed to update surface input channel: ", e);
162                 }
163             }
164         }
165     }
166 
getParentSurface(IWindow window, WindowManager.LayoutParams attrs)167     protected SurfaceControl getParentSurface(IWindow window, WindowManager.LayoutParams attrs) {
168         // If this is the first window, the state map is empty and the parent surface is the
169         // root. Otherwise, the parent surface is in the state map.
170         synchronized (this) {
171             if (mStateForWindow.isEmpty()) {
172                 return mRootSurface;
173             }
174             return mStateForWindow.get(attrs.token).mLeash;
175         }
176     }
177 
178     /**
179      * IWindowSession implementation.
180      */
181     @Override
addToDisplay(IWindow window, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, @InsetsType int requestedVisibleTypes, InputChannel outInputChannel, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame, float[] outSizeCompatScale)182     public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs,
183             int viewVisibility, int displayId, @InsetsType int requestedVisibleTypes,
184             InputChannel outInputChannel, InsetsState outInsetsState,
185             InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame,
186             float[] outSizeCompatScale) {
187         final SurfaceControl leash = new SurfaceControl.Builder(mSurfaceSession)
188                 .setName(attrs.getTitle().toString() + "Leash")
189                 .setCallsite("WindowlessWindowManager.addToDisplay")
190                 .setParent(getParentSurface(window, attrs))
191                 .build();
192 
193         final SurfaceControl sc = new SurfaceControl.Builder(mSurfaceSession)
194                 .setFormat(attrs.format)
195                 .setBLASTLayer()
196                 .setName(attrs.getTitle().toString())
197                 .setCallsite("WindowlessWindowManager.addToDisplay")
198                 .setHidden(false)
199                 .setParent(leash)
200                 .build();
201 
202         final State state = new State(sc, attrs, displayId, window, leash, /* frame= */ new Rect());
203         synchronized (this) {
204             State parentState = mStateForWindow.get(attrs.token);
205             if (parentState != null) {
206                 state.mAttachedFrame = parentState.mFrame;
207             }
208 
209             // Give the first window the mFocusGrantToken since that's the token the host can use
210             // to give focus to the embedded.
211             if (mStateForWindow.isEmpty()) {
212                 state.mInputTransferToken = mInputTransferToken;
213             } else {
214                 state.mInputTransferToken = new InputTransferToken();
215             }
216 
217             mStateForWindow.put(window.asBinder(), state);
218         }
219 
220         if (state.mAttachedFrame == null) {
221             outAttachedFrame.set(0, 0, -1, -1);
222         } else {
223             outAttachedFrame.set(state.mAttachedFrame);
224         }
225         outSizeCompatScale[0] = 1f;
226 
227         if (((attrs.inputFeatures &
228                 WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0)) {
229             try {
230                 if (mRealWm instanceof IWindowSession.Stub) {
231                     mRealWm.grantInputChannel(displayId,
232                             new SurfaceControl(sc, "WindowlessWindowManager.addToDisplay"),
233                             window.asBinder(), mHostInputTransferToken, attrs.flags,
234                             attrs.privateFlags, attrs.inputFeatures, attrs.type, attrs.token,
235                             state.mInputTransferToken, attrs.getTitle().toString(),
236                             outInputChannel);
237                 } else {
238                     mRealWm.grantInputChannel(displayId, sc, window.asBinder(),
239                             mHostInputTransferToken, attrs.flags, attrs.privateFlags,
240                             attrs.inputFeatures, attrs.type, attrs.token, state.mInputTransferToken,
241                             attrs.getTitle().toString(), outInputChannel);
242                 }
243                 state.mInputChannelToken =
244                         outInputChannel != null ? outInputChannel.getToken() : null;
245             } catch (RemoteException e) {
246                 Log.e(TAG, "Failed to grant input to surface: ", e);
247             }
248         }
249 
250         final int res = WindowManagerGlobal.ADD_OKAY | WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
251 
252         sendLayoutParamsToParent();
253         // Include whether the window is in touch mode.
254         return isInTouchModeInternal(displayId) ? res | WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE
255                 : res;
256     }
257 
258     /**
259      * IWindowSession implementation. Currently this class doesn't need to support for multi-user.
260      */
261     @Override
addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, int userId, @InsetsType int requestedVisibleTypes, InputChannel outInputChannel, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame, float[] outSizeCompatScale)262     public int addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs,
263             int viewVisibility, int displayId, int userId, @InsetsType int requestedVisibleTypes,
264             InputChannel outInputChannel, InsetsState outInsetsState,
265             InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame,
266             float[] outSizeCompatScale) {
267         return addToDisplay(window, attrs, viewVisibility, displayId, requestedVisibleTypes,
268                 outInputChannel, outInsetsState, outActiveControls, outAttachedFrame,
269                 outSizeCompatScale);
270     }
271 
272     @Override
addToDisplayWithoutInputChannel(android.view.IWindow window, android.view.WindowManager.LayoutParams attrs, int viewVisibility, int layerStackId, android.view.InsetsState insetsState, Rect outAttachedFrame, float[] outSizeCompatScale)273     public int addToDisplayWithoutInputChannel(android.view.IWindow window,
274             android.view.WindowManager.LayoutParams attrs, int viewVisibility, int layerStackId,
275             android.view.InsetsState insetsState, Rect outAttachedFrame,
276             float[] outSizeCompatScale) {
277         return 0;
278     }
279 
280     @Override
remove(IBinder clientToken)281     public void remove(IBinder clientToken) throws RemoteException {
282         mRealWm.remove(clientToken);
283         State state;
284         synchronized (this) {
285             state = mStateForWindow.remove(clientToken);
286         }
287         if (state == null) {
288             throw new IllegalArgumentException(
289                     "Invalid window token (never added or removed already)");
290         }
291         removeSurface(state.mSurfaceControl);
292         removeSurface(state.mLeash);
293     }
294 
295     /** Separate from {@link #remove} so that subclasses can put removal on a sync transaction. */
removeSurface(SurfaceControl sc)296     protected void removeSurface(SurfaceControl sc) {
297         try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) {
298             t.remove(sc).apply();
299         }
300     }
301 
isOpaque(WindowManager.LayoutParams attrs)302     private boolean isOpaque(WindowManager.LayoutParams attrs) {
303         if (attrs.surfaceInsets != null && attrs.surfaceInsets.left != 0 ||
304                 attrs.surfaceInsets.top != 0 || attrs.surfaceInsets.right != 0 ||
305                 attrs.surfaceInsets.bottom != 0) {
306             return false;
307         }
308         return !PixelFormat.formatHasAlpha(attrs.format);
309     }
310 
isInTouchModeInternal(int displayId)311     private boolean isInTouchModeInternal(int displayId) {
312         try {
313             return WindowManagerGlobal.getWindowManagerService().isInTouchMode(displayId);
314         } catch (RemoteException e) {
315             Log.e(TAG, "Unable to check if the window is in touch mode", e);
316         }
317         return false;
318     }
319 
320     /** Access to package members for SystemWindow leashing
321      * @hide
322      */
getWindowBinder(View rootView)323     protected IBinder getWindowBinder(View rootView) {
324         final ViewRootImpl root = rootView.getViewRootImpl();
325         if (root == null) {
326             return null;
327         }
328         return root.mWindow.asBinder();
329     }
330 
331     /** @hide */
332     @Nullable
getSurfaceControl(View rootView)333     protected SurfaceControl getSurfaceControl(View rootView) {
334         final ViewRootImpl root = rootView.getViewRootImpl();
335         if (root == null) {
336             return null;
337         }
338         return getSurfaceControl(root.mWindow);
339     }
340 
341     /** @hide */
342     @Nullable
getSurfaceControl(IWindow window)343     protected SurfaceControl getSurfaceControl(IWindow window) {
344         final State s = mStateForWindow.get(window.asBinder());
345         if (s == null) {
346             return null;
347         }
348         return s.mSurfaceControl;
349     }
350 
351     @Override
relayoutLegacy(IWindow window, WindowManager.LayoutParams inAttrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq, int lastSyncSeqId, ClientWindowFrames outFrames, MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Bundle outSyncSeqIdBundle)352     public int relayoutLegacy(IWindow window, WindowManager.LayoutParams inAttrs,
353             int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
354             int lastSyncSeqId, ClientWindowFrames outFrames,
355             MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl,
356             InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls,
357             Bundle outSyncSeqIdBundle) {
358         return relayoutInner(window, inAttrs, requestedWidth, requestedHeight, viewFlags, flags,
359                 seq, lastSyncSeqId, outFrames, outMergedConfiguration, outSurfaceControl,
360                 outInsetsState, outActiveControls);
361     }
362 
363     @Override
relayout(IWindow window, WindowManager.LayoutParams inAttrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq, int lastSyncSeqId, WindowRelayoutResult outRelayoutResult)364     public int relayout(IWindow window, WindowManager.LayoutParams inAttrs,
365             int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
366             int lastSyncSeqId, WindowRelayoutResult outRelayoutResult) {
367         final ClientWindowFrames outFrames;
368         final MergedConfiguration outMergedConfiguration;
369         final SurfaceControl outSurfaceControl;
370         final InsetsState outInsetsState;
371         final InsetsSourceControl.Array outActiveControls;
372         if (outRelayoutResult != null) {
373             outFrames = outRelayoutResult.frames;
374             outMergedConfiguration = outRelayoutResult.mergedConfiguration;
375             outSurfaceControl = outRelayoutResult.surfaceControl;
376             outInsetsState = outRelayoutResult.insetsState;
377             outActiveControls = outRelayoutResult.activeControls;
378         } else {
379             outFrames = null;
380             outMergedConfiguration = null;
381             outSurfaceControl = null;
382             outInsetsState = null;
383             outActiveControls = null;
384         }
385         return relayoutInner(window, inAttrs, requestedWidth, requestedHeight, viewFlags, flags,
386                 seq, lastSyncSeqId, outFrames, outMergedConfiguration, outSurfaceControl,
387                 outInsetsState, outActiveControls);
388     }
389 
relayoutInner(IWindow window, WindowManager.LayoutParams inAttrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq, int lastSyncSeqId, ClientWindowFrames outFrames, MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls)390     private int relayoutInner(IWindow window, WindowManager.LayoutParams inAttrs,
391             int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
392             int lastSyncSeqId, ClientWindowFrames outFrames,
393             MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl,
394             InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls) {
395         final State state;
396         synchronized (this) {
397             state = mStateForWindow.get(window.asBinder());
398         }
399         if (state == null) {
400             throw new IllegalArgumentException(
401                     "Invalid window token (never added or removed already)");
402         }
403         SurfaceControl sc = state.mSurfaceControl;
404         SurfaceControl leash = state.mLeash;
405         SurfaceControl.Transaction t = new SurfaceControl.Transaction();
406 
407         int attrChanges = 0;
408         if (inAttrs != null) {
409             attrChanges = state.mParams.copyFrom(inAttrs);
410         }
411         WindowManager.LayoutParams attrs = state.mParams;
412 
413         ClientWindowFrames frames = new ClientWindowFrames();
414         frames.attachedFrame = state.mAttachedFrame;
415 
416         mLayout.computeFrames(attrs, null, null, null, WindowConfiguration.WINDOWING_MODE_UNDEFINED,
417                 requestedWidth, requestedHeight, 0, 0,
418                 frames);
419 
420         state.mFrame.set(frames.frame);
421         if (outFrames != null) {
422             outFrames.frame.set(frames.frame);
423             outFrames.parentFrame.set(frames.parentFrame);
424             outFrames.displayFrame.set(frames.displayFrame);
425         }
426 
427         t.setPosition(leash, frames.frame.left, frames.frame.top);
428 
429         if (viewFlags == View.VISIBLE) {
430             // TODO(b/262892794) ViewRootImpl modifies the app's rendering SurfaceControl
431             // opaqueness. We shouldn't need to modify opaqueness for this SurfaceControl here or
432             // in the real WindowManager.
433             t.setOpaque(sc, isOpaque(attrs)).show(leash).apply();
434             if (outSurfaceControl != null) {
435                 outSurfaceControl.copyFrom(sc, "WindowlessWindowManager.relayout");
436             }
437         } else {
438             t.hide(leash).apply();
439             if (outSurfaceControl != null) {
440                 outSurfaceControl.release();
441             }
442         }
443 
444         if (outMergedConfiguration != null) {
445             outMergedConfiguration.setConfiguration(mConfiguration, mConfiguration);
446         }
447 
448         final int inputChangeMask = WindowManager.LayoutParams.FLAGS_CHANGED
449                 | WindowManager.LayoutParams.INPUT_FEATURES_CHANGED;
450         if ((attrChanges & inputChangeMask) != 0 && state.mInputChannelToken != null) {
451             try {
452                 if (mRealWm instanceof IWindowSession.Stub) {
453                     mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
454                             new SurfaceControl(sc, "WindowlessWindowManager.relayout"),
455                             attrs.flags, attrs.privateFlags, attrs.inputFeatures,
456                             state.mInputRegion);
457                 } else {
458                     mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId, sc,
459                             attrs.flags, attrs.privateFlags, attrs.inputFeatures,
460                             state.mInputRegion);
461                 }
462             } catch (RemoteException e) {
463                 Log.e(TAG, "Failed to update surface input channel: ", e);
464             }
465         }
466 
467         if (outInsetsState != null && mInsetsState != null) {
468             outInsetsState.set(mInsetsState);
469         }
470 
471         sendLayoutParamsToParent();
472         return 0;
473     }
474 
475     @Override
relayoutAsync(IWindow window, WindowManager.LayoutParams inAttrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq, int lastSyncSeqId)476     public void relayoutAsync(IWindow window, WindowManager.LayoutParams inAttrs,
477             int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
478             int lastSyncSeqId) {
479         relayoutInner(window, inAttrs, requestedWidth, requestedHeight, viewFlags, flags, seq,
480                 lastSyncSeqId, null /* outFrames */, null /* outMergedConfiguration */,
481                 null /* outSurfaceControl */, null /* outInsetsState */,
482                 null /* outActiveControls */);
483     }
484 
485     @Override
outOfMemory(android.view.IWindow window)486     public boolean outOfMemory(android.view.IWindow window) {
487         return false;
488     }
489 
490     @Override
setInsets(android.view.IWindow window, int touchableInsets, android.graphics.Rect contentInsets, android.graphics.Rect visibleInsets, android.graphics.Region touchableRegion)491     public void setInsets(android.view.IWindow window, int touchableInsets,
492             android.graphics.Rect contentInsets, android.graphics.Rect visibleInsets,
493             android.graphics.Region touchableRegion) {
494         setTouchRegion(window.asBinder(), touchableRegion);
495     }
496 
497     @Override
clearTouchableRegion(android.view.IWindow window)498     public void clearTouchableRegion(android.view.IWindow window) {
499         setTouchRegion(window.asBinder(), null);
500     }
501 
502     @Override
finishDrawing(android.view.IWindow window, android.view.SurfaceControl.Transaction postDrawTransaction, int seqId)503     public void finishDrawing(android.view.IWindow window,
504             android.view.SurfaceControl.Transaction postDrawTransaction, int seqId) {
505         synchronized (this) {
506             final ResizeCompleteCallback c =
507                 mResizeCompletionForWindow.get(window.asBinder());
508             if (c == null) {
509                 // No one wanted the callback, but it wasn't necessarily unexpected.
510                 postDrawTransaction.apply();
511                 return;
512             }
513             c.finished(postDrawTransaction);
514             mResizeCompletionForWindow.remove(window.asBinder());
515         }
516     }
517 
518     @Override
performHapticFeedback(int effectId, boolean always, boolean fromIme)519     public boolean performHapticFeedback(int effectId, boolean always, boolean fromIme) {
520         return false;
521     }
522 
523     @Override
performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme)524     public void performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme) {
525         performHapticFeedback(effectId, always, fromIme);
526     }
527 
528     @Override
performDrag(android.view.IWindow window, int flags, android.view.SurfaceControl surface, int touchSource, int touchDeviceId, int touchPointerId, float touchX, float touchY, float thumbCenterX, float thumbCenterY, android.content.ClipData data)529     public android.os.IBinder performDrag(android.view.IWindow window, int flags,
530             android.view.SurfaceControl surface, int touchSource, int touchDeviceId,
531             int touchPointerId, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
532             android.content.ClipData data) {
533         return null;
534     }
535 
536     @Override
reportDropResult(android.view.IWindow window, boolean consumed)537     public void reportDropResult(android.view.IWindow window, boolean consumed) {
538     }
539 
540     @Override
cancelDragAndDrop(android.os.IBinder dragToken, boolean skipAnimation)541     public void cancelDragAndDrop(android.os.IBinder dragToken, boolean skipAnimation) {
542     }
543 
544     @Override
dragRecipientEntered(android.view.IWindow window)545     public void dragRecipientEntered(android.view.IWindow window) {
546     }
547 
548     @Override
dragRecipientExited(android.view.IWindow window)549     public void dragRecipientExited(android.view.IWindow window) {
550     }
551 
552     @Override
setWallpaperPosition(android.os.IBinder windowToken, float x, float y, float xstep, float ystep)553     public void setWallpaperPosition(android.os.IBinder windowToken, float x, float y,
554             float xstep, float ystep) {
555     }
556 
557     @Override
setWallpaperZoomOut(android.os.IBinder windowToken, float zoom)558     public void setWallpaperZoomOut(android.os.IBinder windowToken, float zoom) {
559     }
560 
561     @Override
setShouldZoomOutWallpaper(android.os.IBinder windowToken, boolean shouldZoom)562     public void setShouldZoomOutWallpaper(android.os.IBinder windowToken, boolean shouldZoom) {
563     }
564 
565     @Override
wallpaperOffsetsComplete(android.os.IBinder window)566     public void wallpaperOffsetsComplete(android.os.IBinder window) {
567     }
568 
569     @Override
setWallpaperDisplayOffset(android.os.IBinder windowToken, int x, int y)570     public void setWallpaperDisplayOffset(android.os.IBinder windowToken, int x, int y) {
571     }
572 
573     @Override
sendWallpaperCommand(android.os.IBinder window, java.lang.String action, int x, int y, int z, android.os.Bundle extras, boolean sync)574     public void sendWallpaperCommand(android.os.IBinder window,
575             java.lang.String action, int x, int y, int z, android.os.Bundle extras, boolean sync) {
576     }
577 
578     @Override
wallpaperCommandComplete(android.os.IBinder window, android.os.Bundle result)579     public void wallpaperCommandComplete(android.os.IBinder window, android.os.Bundle result) {
580     }
581 
582     @Override
onRectangleOnScreenRequested(android.os.IBinder token, android.graphics.Rect rectangle)583     public void onRectangleOnScreenRequested(android.os.IBinder token,
584             android.graphics.Rect rectangle) {
585     }
586 
587     @Override
getWindowId(android.os.IBinder window)588     public android.view.IWindowId getWindowId(android.os.IBinder window) {
589         return null;
590     }
591 
592     @Override
pokeDrawLock(android.os.IBinder window)593     public void pokeDrawLock(android.os.IBinder window) {
594     }
595 
596     @Override
startMovingTask(android.view.IWindow window, float startX, float startY)597     public boolean startMovingTask(android.view.IWindow window, float startX, float startY) {
598         return false;
599     }
600 
601     @Override
finishMovingTask(android.view.IWindow window)602     public void finishMovingTask(android.view.IWindow window) {
603     }
604 
605     @Override
updateTapExcludeRegion(android.view.IWindow window, android.graphics.Region region)606     public void updateTapExcludeRegion(android.view.IWindow window,
607             android.graphics.Region region) {
608     }
609 
610     @Override
updateRequestedVisibleTypes(IWindow window, @InsetsType int requestedVisibleTypes)611     public void updateRequestedVisibleTypes(IWindow window,
612             @InsetsType int requestedVisibleTypes)  {
613     }
614 
615     @Override
reportSystemGestureExclusionChanged(android.view.IWindow window, List<Rect> exclusionRects)616     public void reportSystemGestureExclusionChanged(android.view.IWindow window,
617             List<Rect> exclusionRects) {
618     }
619 
620     @Override
reportDecorViewGestureInterceptionChanged(IWindow window, boolean intercepted)621     public void reportDecorViewGestureInterceptionChanged(IWindow window, boolean intercepted) {}
622 
623     @Override
reportKeepClearAreasChanged( android.view.IWindow window, List<Rect> restrictedRects, List<Rect> unrestrictedRects)624     public void reportKeepClearAreasChanged(
625             android.view.IWindow window,
626             List<Rect> restrictedRects,
627             List<Rect> unrestrictedRects) {}
628 
629     @Override
grantInputChannel(int displayId, SurfaceControl surface, IBinder clientToken, InputTransferToken hostInputToken, int flags, int privateFlags, int inputFeatures, int type, IBinder windowToken, InputTransferToken embeddedInputTransferToken, String inputHandleName, InputChannel outInputChannel)630     public void grantInputChannel(int displayId, SurfaceControl surface, IBinder clientToken,
631             InputTransferToken hostInputToken, int flags, int privateFlags, int inputFeatures,
632             int type, IBinder windowToken, InputTransferToken embeddedInputTransferToken,
633             String inputHandleName, InputChannel outInputChannel) {
634     }
635 
636     @Override
updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface, int flags, int privateFlags, int inputFeatures, Region region)637     public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
638             int flags, int privateFlags, int inputFeatures, Region region) {
639     }
640 
641     @Override
asBinder()642     public android.os.IBinder asBinder() {
643         return null;
644     }
645 
646     @Override
grantEmbeddedWindowFocus(IWindow callingWindow, InputTransferToken targetInputToken, boolean grantFocus)647     public void grantEmbeddedWindowFocus(IWindow callingWindow, InputTransferToken targetInputToken,
648                                          boolean grantFocus) {
649     }
650 
651     @Override
generateDisplayHash(IWindow window, Rect boundsInWindow, String hashAlgorithm, RemoteCallback callback)652     public void generateDisplayHash(IWindow window, Rect boundsInWindow, String hashAlgorithm,
653             RemoteCallback callback) {
654     }
655 
656     @Override
setOnBackInvokedCallbackInfo(IWindow iWindow, OnBackInvokedCallbackInfo callbackInfo)657     public void setOnBackInvokedCallbackInfo(IWindow iWindow,
658             OnBackInvokedCallbackInfo callbackInfo) throws RemoteException { }
659 
660     @Override
dropForAccessibility(IWindow window, int x, int y)661     public boolean dropForAccessibility(IWindow window, int x, int y) {
662         return false;
663     }
664 
setInsetsState(InsetsState state)665     public void setInsetsState(InsetsState state) {
666         mInsetsState = state;
667         for (State s : mStateForWindow.values()) {
668             try {
669                 mTmpFrames.frame.set(0, 0, s.mParams.width, s.mParams.height);
670                 mTmpFrames.displayFrame.set(mTmpFrames.frame);
671                 mTmpConfig.setConfiguration(mConfiguration, mConfiguration);
672                 s.mClient.resized(mTmpFrames, false /* reportDraw */, mTmpConfig, state,
673                         false /* forceLayout */, false /* alwaysConsumeSystemBars */, s.mDisplayId,
674                         Integer.MAX_VALUE, false /* dragResizing */, null /* activityWindowInfo */);
675             } catch (RemoteException e) {
676                 // Too bad
677             }
678         }
679     }
680 
681     @Override
cancelDraw(IWindow window)682     public boolean cancelDraw(IWindow window) {
683         return false;
684     }
685 
686     @Override
moveFocusToAdjacentWindow(IWindow fromWindow, @FocusDirection int direction)687     public boolean moveFocusToAdjacentWindow(IWindow fromWindow, @FocusDirection int direction) {
688         Log.e(TAG, "Received request to moveFocusToAdjacentWindow on"
689                 + " WindowlessWindowManager. We shouldn't get here!");
690         return false;
691     }
692 
setParentInterface(@ullable ISurfaceControlViewHostParent parentInterface)693     void setParentInterface(@Nullable ISurfaceControlViewHostParent parentInterface) {
694         IBinder oldInterface = mParentInterface == null ? null : mParentInterface.asBinder();
695         IBinder newInterface = parentInterface == null ? null : parentInterface.asBinder();
696         // If the parent interface has changed, it needs to clear the last reported params so it
697         // will update the new interface with the params.
698         if (oldInterface != newInterface) {
699             clearLastReportedParams();
700         }
701         mParentInterface = parentInterface;
702         sendLayoutParamsToParent();
703     }
704 
clearLastReportedParams()705     private void clearLastReportedParams() {
706         WindowManager.LayoutParams emptyParam = new WindowManager.LayoutParams();
707         for (State windowInfo : mStateForWindow.values()) {
708             windowInfo.mLastReportedParams.copyFrom(emptyParam);
709         }
710     }
711 
sendLayoutParamsToParent()712     private void sendLayoutParamsToParent() {
713         if (mParentInterface == null) {
714             return;
715         }
716         WindowManager.LayoutParams[] params =
717                 new WindowManager.LayoutParams[mStateForWindow.size()];
718         int index = 0;
719         boolean hasChanges = false;
720         for (State windowInfo : mStateForWindow.values()) {
721             int changes = windowInfo.mLastReportedParams.copyFrom(windowInfo.mParams);
722             hasChanges |= (changes != 0);
723             params[index++] = windowInfo.mParams;
724         }
725 
726         if (hasChanges) {
727             try {
728                 mParentInterface.updateParams(params);
729             } catch (RemoteException e) {
730             }
731         }
732     }
733 
forwardBackKeyToParent(@onNull KeyEvent keyEvent)734     boolean forwardBackKeyToParent(@NonNull KeyEvent keyEvent) {
735         if (mParentInterface == null) {
736             return false;
737         }
738         try {
739             mParentInterface.forwardBackKeyToParent(keyEvent);
740         } catch (RemoteException e) {
741             Log.e(TAG, "Failed to forward back key To Parent: ", e);
742             return false;
743         }
744         return true;
745     }
746 }
747