Session.java revision d76881e002cf1e266b5080b05d1aee80fc760770
1/* 2 * Copyright (C) 2011 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 17package com.android.server.wm; 18 19import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 20import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 22import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType; 23import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG; 24import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; 25import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; 26import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; 27import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 28 29import android.content.ClipData; 30import android.content.Context; 31import android.content.res.Configuration; 32import android.graphics.Rect; 33import android.graphics.Region; 34import android.os.Binder; 35import android.os.Bundle; 36import android.os.IBinder; 37import android.os.Parcel; 38import android.os.Process; 39import android.os.RemoteException; 40import android.os.ServiceManager; 41import android.os.UserHandle; 42import android.util.Slog; 43import android.view.Display; 44import android.view.IWindow; 45import android.view.IWindowId; 46import android.view.IWindowSession; 47import android.view.IWindowSessionCallback; 48import android.view.InputChannel; 49import android.view.Surface; 50import android.view.SurfaceControl; 51import android.view.SurfaceSession; 52import android.view.WindowManager; 53 54import com.android.internal.view.IInputContext; 55import com.android.internal.view.IInputMethodClient; 56import com.android.internal.view.IInputMethodManager; 57import com.android.server.wm.WindowManagerService.H; 58 59import java.io.PrintWriter; 60import java.util.HashSet; 61import java.util.Set; 62 63/** 64 * This class represents an active client session. There is generally one 65 * Session object per process that is interacting with the window manager. 66 */ 67// Needs to be public and not final so we can mock during tests...sucks I know :( 68public class Session extends IWindowSession.Stub 69 implements IBinder.DeathRecipient { 70 final WindowManagerService mService; 71 final IWindowSessionCallback mCallback; 72 final IInputMethodClient mClient; 73 final int mUid; 74 final int mPid; 75 private final String mStringName; 76 SurfaceSession mSurfaceSession; 77 private int mNumWindow = 0; 78 // Set of visible application overlay window surfaces connected to this session. 79 private final Set<WindowSurfaceController> mAppOverlaySurfaces = new HashSet<>(); 80 // Set of visible alert window surfaces connected to this session. 81 private final Set<WindowSurfaceController> mAlertWindowSurfaces = new HashSet<>(); 82 final boolean mCanAddInternalSystemWindow; 83 private AlertWindowNotification mAlertWindowNotification; 84 private boolean mClientDead = false; 85 private float mLastReportedAnimatorScale; 86 private String mPackageName; 87 88 public Session(WindowManagerService service, IWindowSessionCallback callback, 89 IInputMethodClient client, IInputContext inputContext) { 90 mService = service; 91 mCallback = callback; 92 mClient = client; 93 mUid = Binder.getCallingUid(); 94 mPid = Binder.getCallingPid(); 95 mLastReportedAnimatorScale = service.getCurrentAnimatorScale(); 96 mCanAddInternalSystemWindow = service.mContext.checkCallingOrSelfPermission( 97 INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED; 98 StringBuilder sb = new StringBuilder(); 99 sb.append("Session{"); 100 sb.append(Integer.toHexString(System.identityHashCode(this))); 101 sb.append(" "); 102 sb.append(mPid); 103 if (mUid < Process.FIRST_APPLICATION_UID) { 104 sb.append(":"); 105 sb.append(mUid); 106 } else { 107 sb.append(":u"); 108 sb.append(UserHandle.getUserId(mUid)); 109 sb.append('a'); 110 sb.append(UserHandle.getAppId(mUid)); 111 } 112 sb.append("}"); 113 mStringName = sb.toString(); 114 115 synchronized (mService.mWindowMap) { 116 if (mService.mInputMethodManager == null && mService.mHaveInputMethods) { 117 IBinder b = ServiceManager.getService( 118 Context.INPUT_METHOD_SERVICE); 119 mService.mInputMethodManager = IInputMethodManager.Stub.asInterface(b); 120 } 121 } 122 long ident = Binder.clearCallingIdentity(); 123 try { 124 // Note: it is safe to call in to the input method manager 125 // here because we are not holding our lock. 126 if (mService.mInputMethodManager != null) { 127 mService.mInputMethodManager.addClient(client, inputContext, 128 mUid, mPid); 129 } else { 130 client.setUsingInputMethod(false); 131 } 132 client.asBinder().linkToDeath(this, 0); 133 } catch (RemoteException e) { 134 // The caller has died, so we can just forget about this. 135 try { 136 if (mService.mInputMethodManager != null) { 137 mService.mInputMethodManager.removeClient(client); 138 } 139 } catch (RemoteException ee) { 140 } 141 } finally { 142 Binder.restoreCallingIdentity(ident); 143 } 144 } 145 146 @Override 147 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 148 throws RemoteException { 149 try { 150 return super.onTransact(code, data, reply, flags); 151 } catch (RuntimeException e) { 152 // Log all 'real' exceptions thrown to the caller 153 if (!(e instanceof SecurityException)) { 154 Slog.wtf(TAG_WM, "Window Session Crash", e); 155 } 156 throw e; 157 } 158 } 159 160 public void binderDied() { 161 // Note: it is safe to call in to the input method manager 162 // here because we are not holding our lock. 163 try { 164 if (mService.mInputMethodManager != null) { 165 mService.mInputMethodManager.removeClient(mClient); 166 } 167 } catch (RemoteException e) { 168 } 169 synchronized(mService.mWindowMap) { 170 mClient.asBinder().unlinkToDeath(this, 0); 171 mClientDead = true; 172 killSessionLocked(); 173 } 174 } 175 176 @Override 177 public int add(IWindow window, int seq, WindowManager.LayoutParams attrs, 178 int viewVisibility, Rect outContentInsets, Rect outStableInsets, 179 InputChannel outInputChannel) { 180 return addToDisplay(window, seq, attrs, viewVisibility, Display.DEFAULT_DISPLAY, 181 outContentInsets, outStableInsets, null /* outOutsets */, outInputChannel); 182 } 183 184 @Override 185 public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, 186 int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, 187 Rect outOutsets, InputChannel outInputChannel) { 188 return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, 189 outContentInsets, outStableInsets, outOutsets, outInputChannel); 190 } 191 192 @Override 193 public int addWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs, 194 int viewVisibility, Rect outContentInsets, Rect outStableInsets) { 195 return addToDisplayWithoutInputChannel(window, seq, attrs, viewVisibility, 196 Display.DEFAULT_DISPLAY, outContentInsets, outStableInsets); 197 } 198 199 @Override 200 public int addToDisplayWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs, 201 int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets) { 202 return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, 203 outContentInsets, outStableInsets, null /* outOutsets */, null); 204 } 205 206 public void remove(IWindow window) { 207 mService.removeWindow(this, window); 208 } 209 210 @Override 211 public void repositionChild(IWindow window, int left, int top, int right, int bottom, 212 long deferTransactionUntilFrame, Rect outFrame) { 213 mService.repositionChild(this, window, left, top, right, bottom, 214 deferTransactionUntilFrame, outFrame); 215 } 216 217 @Override 218 public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) { 219 mService.setWillReplaceWindows(appToken, childrenOnly); 220 } 221 222 public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, 223 int requestedWidth, int requestedHeight, int viewFlags, 224 int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, 225 Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Rect outBackdropFrame, 226 Configuration outConfig, Surface outSurface) { 227 if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from " 228 + Binder.getCallingPid()); 229 int res = mService.relayoutWindow(this, window, seq, attrs, 230 requestedWidth, requestedHeight, viewFlags, flags, 231 outFrame, outOverscanInsets, outContentInsets, outVisibleInsets, 232 outStableInsets, outsets, outBackdropFrame, outConfig, outSurface); 233 if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to " 234 + Binder.getCallingPid()); 235 return res; 236 } 237 238 public void performDeferredDestroy(IWindow window) { 239 mService.performDeferredDestroyWindow(this, window); 240 } 241 242 public boolean outOfMemory(IWindow window) { 243 return mService.outOfMemoryWindow(this, window); 244 } 245 246 public void setTransparentRegion(IWindow window, Region region) { 247 mService.setTransparentRegionWindow(this, window, region); 248 } 249 250 public void setInsets(IWindow window, int touchableInsets, 251 Rect contentInsets, Rect visibleInsets, Region touchableArea) { 252 mService.setInsetsWindow(this, window, touchableInsets, contentInsets, 253 visibleInsets, touchableArea); 254 } 255 256 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) { 257 mService.getWindowDisplayFrame(this, window, outDisplayFrame); 258 } 259 260 public void finishDrawing(IWindow window) { 261 if (WindowManagerService.localLOGV) Slog.v( 262 TAG_WM, "IWindow finishDrawing called for " + window); 263 mService.finishDrawingWindow(this, window); 264 } 265 266 public void setInTouchMode(boolean mode) { 267 synchronized(mService.mWindowMap) { 268 mService.mInTouchMode = mode; 269 } 270 } 271 272 public boolean getInTouchMode() { 273 synchronized(mService.mWindowMap) { 274 return mService.mInTouchMode; 275 } 276 } 277 278 public boolean performHapticFeedback(IWindow window, int effectId, 279 boolean always) { 280 synchronized(mService.mWindowMap) { 281 long ident = Binder.clearCallingIdentity(); 282 try { 283 return mService.mPolicy.performHapticFeedbackLw( 284 mService.windowForClientLocked(this, window, true), 285 effectId, always); 286 } finally { 287 Binder.restoreCallingIdentity(ident); 288 } 289 } 290 } 291 292 /* Drag/drop */ 293 public IBinder prepareDrag(IWindow window, int flags, 294 int width, int height, Surface outSurface) { 295 return mService.prepareDragSurface(window, mSurfaceSession, flags, 296 width, height, outSurface); 297 } 298 299 public boolean performDrag(IWindow window, IBinder dragToken, 300 int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY, 301 ClipData data) { 302 if (DEBUG_DRAG) { 303 Slog.d(TAG_WM, "perform drag: win=" + window + " data=" + data); 304 } 305 306 synchronized (mService.mWindowMap) { 307 if (mService.mDragState == null) { 308 Slog.w(TAG_WM, "No drag prepared"); 309 throw new IllegalStateException("performDrag() without prepareDrag()"); 310 } 311 312 if (dragToken != mService.mDragState.mToken) { 313 Slog.w(TAG_WM, "Performing mismatched drag"); 314 throw new IllegalStateException("performDrag() does not match prepareDrag()"); 315 } 316 317 WindowState callingWin = mService.windowForClientLocked(null, window, false); 318 if (callingWin == null) { 319 Slog.w(TAG_WM, "Bad requesting window " + window); 320 return false; // !!! TODO: throw here? 321 } 322 323 // !!! TODO: if input is not still focused on the initiating window, fail 324 // the drag initiation (e.g. an alarm window popped up just as the application 325 // called performDrag() 326 327 mService.mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder()); 328 329 // !!! TODO: extract the current touch (x, y) in screen coordinates. That 330 // will let us eliminate the (touchX,touchY) parameters from the API. 331 332 // !!! FIXME: put all this heavy stuff onto the mH looper, as well as 333 // the actual drag event dispatch stuff in the dragstate 334 335 final DisplayContent displayContent = callingWin.getDisplayContent(); 336 if (displayContent == null) { 337 return false; 338 } 339 Display display = displayContent.getDisplay(); 340 mService.mDragState.register(display); 341 if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel, 342 mService.mDragState.getInputChannel())) { 343 Slog.e(TAG_WM, "Unable to transfer touch focus"); 344 mService.mDragState.unregister(); 345 mService.mDragState.reset(); 346 mService.mDragState = null; 347 return false; 348 } 349 350 mService.mDragState.mDisplayContent = displayContent; 351 mService.mDragState.mData = data; 352 mService.mDragState.broadcastDragStartedLw(touchX, touchY); 353 mService.mDragState.overridePointerIconLw(touchSource); 354 355 // remember the thumb offsets for later 356 mService.mDragState.mThumbOffsetX = thumbCenterX; 357 mService.mDragState.mThumbOffsetY = thumbCenterY; 358 359 // Make the surface visible at the proper location 360 final SurfaceControl surfaceControl = mService.mDragState.mSurfaceControl; 361 if (SHOW_LIGHT_TRANSACTIONS) Slog.i( 362 TAG_WM, ">>> OPEN TRANSACTION performDrag"); 363 mService.openSurfaceTransaction(); 364 try { 365 surfaceControl.setPosition(touchX - thumbCenterX, 366 touchY - thumbCenterY); 367 surfaceControl.setLayer(mService.mDragState.getDragLayerLw()); 368 surfaceControl.setLayerStack(display.getLayerStack()); 369 surfaceControl.show(); 370 } finally { 371 mService.closeSurfaceTransaction(); 372 if (SHOW_LIGHT_TRANSACTIONS) Slog.i( 373 TAG_WM, "<<< CLOSE TRANSACTION performDrag"); 374 } 375 376 mService.mDragState.notifyLocationLw(touchX, touchY); 377 } 378 379 return true; // success! 380 } 381 382 public boolean startMovingTask(IWindow window, float startX, float startY) { 383 if (DEBUG_TASK_POSITIONING) Slog.d( 384 TAG_WM, "startMovingTask: {" + startX + "," + startY + "}"); 385 386 long ident = Binder.clearCallingIdentity(); 387 try { 388 return mService.startMovingTask(window, startX, startY); 389 } finally { 390 Binder.restoreCallingIdentity(ident); 391 } 392 } 393 394 public void reportDropResult(IWindow window, boolean consumed) { 395 IBinder token = window.asBinder(); 396 if (DEBUG_DRAG) { 397 Slog.d(TAG_WM, "Drop result=" + consumed + " reported by " + token); 398 } 399 400 synchronized (mService.mWindowMap) { 401 long ident = Binder.clearCallingIdentity(); 402 try { 403 if (mService.mDragState == null) { 404 // Most likely the drop recipient ANRed and we ended the drag 405 // out from under it. Log the issue and move on. 406 Slog.w(TAG_WM, "Drop result given but no drag in progress"); 407 return; 408 } 409 410 if (mService.mDragState.mToken != token) { 411 // We're in a drag, but the wrong window has responded. 412 Slog.w(TAG_WM, "Invalid drop-result claim by " + window); 413 throw new IllegalStateException("reportDropResult() by non-recipient"); 414 } 415 416 // The right window has responded, even if it's no longer around, 417 // so be sure to halt the timeout even if the later WindowState 418 // lookup fails. 419 mService.mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder()); 420 WindowState callingWin = mService.windowForClientLocked(null, window, false); 421 if (callingWin == null) { 422 Slog.w(TAG_WM, "Bad result-reporting window " + window); 423 return; // !!! TODO: throw here? 424 } 425 426 mService.mDragState.mDragResult = consumed; 427 mService.mDragState.endDragLw(); 428 } finally { 429 Binder.restoreCallingIdentity(ident); 430 } 431 } 432 } 433 434 public void cancelDragAndDrop(IBinder dragToken) { 435 if (DEBUG_DRAG) { 436 Slog.d(TAG_WM, "cancelDragAndDrop"); 437 } 438 439 synchronized (mService.mWindowMap) { 440 long ident = Binder.clearCallingIdentity(); 441 try { 442 if (mService.mDragState == null) { 443 Slog.w(TAG_WM, "cancelDragAndDrop() without prepareDrag()"); 444 throw new IllegalStateException("cancelDragAndDrop() without prepareDrag()"); 445 } 446 447 if (mService.mDragState.mToken != dragToken) { 448 Slog.w(TAG_WM, 449 "cancelDragAndDrop() does not match prepareDrag()"); 450 throw new IllegalStateException( 451 "cancelDragAndDrop() does not match prepareDrag()"); 452 } 453 454 mService.mDragState.mDragResult = false; 455 mService.mDragState.cancelDragLw(); 456 } finally { 457 Binder.restoreCallingIdentity(ident); 458 } 459 } 460 } 461 462 public void dragRecipientEntered(IWindow window) { 463 if (DEBUG_DRAG) { 464 Slog.d(TAG_WM, "Drag into new candidate view @ " + window.asBinder()); 465 } 466 } 467 468 public void dragRecipientExited(IWindow window) { 469 if (DEBUG_DRAG) { 470 Slog.d(TAG_WM, "Drag from old candidate view @ " + window.asBinder()); 471 } 472 } 473 474 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) { 475 synchronized(mService.mWindowMap) { 476 long ident = Binder.clearCallingIdentity(); 477 try { 478 mService.mRoot.mWallpaperController.setWindowWallpaperPosition( 479 mService.windowForClientLocked(this, window, true), 480 x, y, xStep, yStep); 481 } finally { 482 Binder.restoreCallingIdentity(ident); 483 } 484 } 485 } 486 487 public void wallpaperOffsetsComplete(IBinder window) { 488 synchronized (mService.mWindowMap) { 489 mService.mRoot.mWallpaperController.wallpaperOffsetsComplete(window); 490 } 491 } 492 493 public void setWallpaperDisplayOffset(IBinder window, int x, int y) { 494 synchronized(mService.mWindowMap) { 495 long ident = Binder.clearCallingIdentity(); 496 try { 497 mService.mRoot.mWallpaperController.setWindowWallpaperDisplayOffset( 498 mService.windowForClientLocked(this, window, true), x, y); 499 } finally { 500 Binder.restoreCallingIdentity(ident); 501 } 502 } 503 } 504 505 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y, 506 int z, Bundle extras, boolean sync) { 507 synchronized(mService.mWindowMap) { 508 long ident = Binder.clearCallingIdentity(); 509 try { 510 return mService.mRoot.mWallpaperController.sendWindowWallpaperCommand( 511 mService.windowForClientLocked(this, window, true), 512 action, x, y, z, extras, sync); 513 } finally { 514 Binder.restoreCallingIdentity(ident); 515 } 516 } 517 } 518 519 public void wallpaperCommandComplete(IBinder window, Bundle result) { 520 synchronized (mService.mWindowMap) { 521 mService.mRoot.mWallpaperController.wallpaperCommandComplete(window); 522 } 523 } 524 525 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) { 526 synchronized(mService.mWindowMap) { 527 final long identity = Binder.clearCallingIdentity(); 528 try { 529 mService.onRectangleOnScreenRequested(token, rectangle); 530 } finally { 531 Binder.restoreCallingIdentity(identity); 532 } 533 } 534 } 535 536 public IWindowId getWindowId(IBinder window) { 537 return mService.getWindowId(window); 538 } 539 540 @Override 541 public void pokeDrawLock(IBinder window) { 542 final long identity = Binder.clearCallingIdentity(); 543 try { 544 mService.pokeDrawLock(this, window); 545 } finally { 546 Binder.restoreCallingIdentity(identity); 547 } 548 } 549 550 @Override 551 public void updatePointerIcon(IWindow window) { 552 final long identity = Binder.clearCallingIdentity(); 553 try { 554 mService.updatePointerIcon(window); 555 } finally { 556 Binder.restoreCallingIdentity(identity); 557 } 558 } 559 560 void windowAddedLocked(String packageName) { 561 mPackageName = packageName; 562 if (mSurfaceSession == null) { 563 if (WindowManagerService.localLOGV) Slog.v( 564 TAG_WM, "First window added to " + this + ", creating SurfaceSession"); 565 mSurfaceSession = new SurfaceSession(); 566 if (SHOW_TRANSACTIONS) Slog.i( 567 TAG_WM, " NEW SURFACE SESSION " + mSurfaceSession); 568 mService.mSessions.add(this); 569 if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) { 570 mService.dispatchNewAnimatorScaleLocked(this); 571 } 572 } 573 mNumWindow++; 574 } 575 576 void windowRemovedLocked() { 577 mNumWindow--; 578 killSessionLocked(); 579 } 580 581 582 void onWindowSurfaceVisibilityChanged(WindowSurfaceController surfaceController, 583 boolean visible, int type) { 584 585 if (!isSystemAlertWindowType(type)) { 586 return; 587 } 588 589 boolean changed; 590 591 if (!mCanAddInternalSystemWindow) { 592 // We want to track non-system signature apps adding alert windows so we can post an 593 // on-going notification for the user to control their visibility. 594 if (visible) { 595 changed = mAlertWindowSurfaces.add(surfaceController); 596 } else { 597 changed = mAlertWindowSurfaces.remove(surfaceController); 598 } 599 600 if (changed) { 601 if (mAlertWindowSurfaces.isEmpty()) { 602 cancelAlertWindowNotification(); 603 } else if (mAlertWindowNotification == null){ 604 mAlertWindowNotification = new AlertWindowNotification(mService, mPackageName); 605 } 606 } 607 } 608 609 if (type != TYPE_APPLICATION_OVERLAY) { 610 return; 611 } 612 613 if (visible) { 614 changed = mAppOverlaySurfaces.add(surfaceController); 615 } else { 616 changed = mAppOverlaySurfaces.remove(surfaceController); 617 } 618 619 if (changed) { 620 // Notify activity manager of changes to app overlay windows so it can adjust the 621 // importance score for the process. 622 setHasOverlayUi(!mAppOverlaySurfaces.isEmpty()); 623 } 624 } 625 626 private void killSessionLocked() { 627 if (mNumWindow > 0 || !mClientDead) { 628 return; 629 } 630 631 mService.mSessions.remove(this); 632 if (mSurfaceSession == null) { 633 return; 634 } 635 636 if (WindowManagerService.localLOGV) Slog.v(TAG_WM, "Last window removed from " + this 637 + ", destroying " + mSurfaceSession); 638 if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " KILL SURFACE SESSION " + mSurfaceSession); 639 try { 640 mSurfaceSession.kill(); 641 } catch (Exception e) { 642 Slog.w(TAG_WM, "Exception thrown when killing surface session " + mSurfaceSession 643 + " in session " + this + ": " + e.toString()); 644 } 645 mSurfaceSession = null; 646 mAlertWindowSurfaces.clear(); 647 mAppOverlaySurfaces.clear(); 648 setHasOverlayUi(false); 649 cancelAlertWindowNotification(); 650 } 651 652 private void setHasOverlayUi(boolean hasOverlayUi) { 653 mService.mH.obtainMessage(H.SET_HAS_OVERLAY_UI, mPid, hasOverlayUi ? 1 : 0).sendToTarget(); 654 } 655 656 private void cancelAlertWindowNotification() { 657 if (mAlertWindowNotification == null) { 658 return; 659 } 660 mAlertWindowNotification.cancel(); 661 mAlertWindowNotification = null; 662 } 663 664 void dump(PrintWriter pw, String prefix) { 665 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow); 666 pw.print(" mCanAddInternalSystemWindow="); pw.print(mCanAddInternalSystemWindow); 667 pw.print(" mAppOverlaySurfaces="); pw.print(mAppOverlaySurfaces); 668 pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces); 669 pw.print(" mClientDead="); pw.print(mClientDead); 670 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession); 671 } 672 673 @Override 674 public String toString() { 675 return mStringName; 676 } 677} 678