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