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