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