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