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