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