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 17 package com.android.server.wm; 18 19 import static android.Manifest.permission.DEVICE_POWER; 20 import static android.Manifest.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS; 21 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 22 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; 24 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 25 import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType; 26 27 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; 28 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; 29 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 30 31 import android.content.ClipData; 32 import android.content.Context; 33 import android.graphics.Rect; 34 import android.graphics.Region; 35 import android.os.Binder; 36 import android.os.Bundle; 37 import android.os.IBinder; 38 import android.os.Parcel; 39 import android.os.Process; 40 import android.os.RemoteException; 41 import android.os.ServiceManager; 42 import android.os.Trace; 43 import android.os.UserHandle; 44 import android.util.MergedConfiguration; 45 import android.util.Slog; 46 import android.view.Display; 47 import android.view.DisplayCutout; 48 import android.view.IWindow; 49 import android.view.IWindowId; 50 import android.view.IWindowSession; 51 import android.view.IWindowSessionCallback; 52 import android.view.InputChannel; 53 import android.view.Surface; 54 import android.view.SurfaceControl; 55 import android.view.SurfaceSession; 56 import android.view.WindowManager; 57 58 import com.android.internal.os.logging.MetricsLoggerWrapper; 59 import com.android.internal.view.IInputContext; 60 import com.android.internal.view.IInputMethodClient; 61 import com.android.internal.view.IInputMethodManager; 62 import com.android.server.wm.WindowManagerService.H; 63 64 import java.io.PrintWriter; 65 import java.util.HashSet; 66 import java.util.Set; 67 68 /** 69 * This class represents an active client session. There is generally one 70 * Session object per process that is interacting with the window manager. 71 */ 72 class Session extends IWindowSession.Stub 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 private final DragDropController mDragDropController; 86 final boolean mCanAddInternalSystemWindow; 87 final boolean mCanHideNonSystemOverlayWindows; 88 final boolean mCanAcquireSleepToken; 89 private AlertWindowNotification mAlertWindowNotification; 90 private boolean mShowingAlertWindowNotificationAllowed; 91 private boolean mClientDead = false; 92 private float mLastReportedAnimatorScale; 93 private String mPackageName; 94 private String mRelayoutTag; 95 Session(WindowManagerService service, IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext)96 public Session(WindowManagerService service, IWindowSessionCallback callback, 97 IInputMethodClient client, IInputContext inputContext) { 98 mService = service; 99 mCallback = callback; 100 mClient = client; 101 mUid = Binder.getCallingUid(); 102 mPid = Binder.getCallingPid(); 103 mLastReportedAnimatorScale = service.getCurrentAnimatorScale(); 104 mCanAddInternalSystemWindow = service.mContext.checkCallingOrSelfPermission( 105 INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED; 106 mCanHideNonSystemOverlayWindows = service.mContext.checkCallingOrSelfPermission( 107 HIDE_NON_SYSTEM_OVERLAY_WINDOWS) == PERMISSION_GRANTED; 108 mCanAcquireSleepToken = service.mContext.checkCallingOrSelfPermission(DEVICE_POWER) 109 == PERMISSION_GRANTED; 110 mShowingAlertWindowNotificationAllowed = mService.mShowAlertWindowNotifications; 111 mDragDropController = mService.mDragDropController; 112 StringBuilder sb = new StringBuilder(); 113 sb.append("Session{"); 114 sb.append(Integer.toHexString(System.identityHashCode(this))); 115 sb.append(" "); 116 sb.append(mPid); 117 if (mUid < Process.FIRST_APPLICATION_UID) { 118 sb.append(":"); 119 sb.append(mUid); 120 } else { 121 sb.append(":u"); 122 sb.append(UserHandle.getUserId(mUid)); 123 sb.append('a'); 124 sb.append(UserHandle.getAppId(mUid)); 125 } 126 sb.append("}"); 127 mStringName = sb.toString(); 128 129 synchronized (mService.mWindowMap) { 130 if (mService.mInputMethodManager == null && mService.mHaveInputMethods) { 131 IBinder b = ServiceManager.getService( 132 Context.INPUT_METHOD_SERVICE); 133 mService.mInputMethodManager = IInputMethodManager.Stub.asInterface(b); 134 } 135 } 136 long ident = Binder.clearCallingIdentity(); 137 try { 138 // Note: it is safe to call in to the input method manager 139 // here because we are not holding our lock. 140 if (mService.mInputMethodManager != null) { 141 mService.mInputMethodManager.addClient(client, inputContext, 142 mUid, mPid); 143 } else { 144 client.setUsingInputMethod(false); 145 } 146 client.asBinder().linkToDeath(this, 0); 147 } catch (RemoteException e) { 148 // The caller has died, so we can just forget about this. 149 try { 150 if (mService.mInputMethodManager != null) { 151 mService.mInputMethodManager.removeClient(client); 152 } 153 } catch (RemoteException ee) { 154 } 155 } finally { 156 Binder.restoreCallingIdentity(ident); 157 } 158 } 159 160 @Override onTransact(int code, Parcel data, Parcel reply, int flags)161 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 162 throws RemoteException { 163 try { 164 return super.onTransact(code, data, reply, flags); 165 } catch (RuntimeException e) { 166 // Log all 'real' exceptions thrown to the caller 167 if (!(e instanceof SecurityException)) { 168 Slog.wtf(TAG_WM, "Window Session Crash", e); 169 } 170 throw e; 171 } 172 } 173 174 @Override binderDied()175 public void binderDied() { 176 // Note: it is safe to call in to the input method manager 177 // here because we are not holding our lock. 178 try { 179 if (mService.mInputMethodManager != null) { 180 mService.mInputMethodManager.removeClient(mClient); 181 } 182 } catch (RemoteException e) { 183 } 184 synchronized(mService.mWindowMap) { 185 mClient.asBinder().unlinkToDeath(this, 0); 186 mClientDead = true; 187 killSessionLocked(); 188 } 189 } 190 191 @Override add(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, Rect outContentInsets, Rect outStableInsets, InputChannel outInputChannel)192 public int add(IWindow window, int seq, WindowManager.LayoutParams attrs, 193 int viewVisibility, Rect outContentInsets, Rect outStableInsets, 194 InputChannel outInputChannel) { 195 return addToDisplay(window, seq, attrs, viewVisibility, Display.DEFAULT_DISPLAY, 196 new Rect() /* outFrame */, outContentInsets, outStableInsets, null /* outOutsets */, 197 new DisplayCutout.ParcelableWrapper() /* cutout */, outInputChannel); 198 } 199 200 @Override addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel)201 public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, 202 int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets, 203 Rect outStableInsets, Rect outOutsets, 204 DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) { 205 return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame, 206 outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel); 207 } 208 209 @Override addWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, Rect outContentInsets, Rect outStableInsets)210 public int addWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs, 211 int viewVisibility, Rect outContentInsets, Rect outStableInsets) { 212 return addToDisplayWithoutInputChannel(window, seq, attrs, viewVisibility, 213 Display.DEFAULT_DISPLAY, outContentInsets, outStableInsets); 214 } 215 216 @Override addToDisplayWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets)217 public int addToDisplayWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs, 218 int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets) { 219 return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, 220 new Rect() /* outFrame */, outContentInsets, outStableInsets, null /* outOutsets */, 221 new DisplayCutout.ParcelableWrapper() /* cutout */, null /* outInputChannel */); 222 } 223 224 @Override remove(IWindow window)225 public void remove(IWindow window) { 226 mService.removeWindow(this, window); 227 } 228 229 @Override prepareToReplaceWindows(IBinder appToken, boolean childrenOnly)230 public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) { 231 mService.setWillReplaceWindows(appToken, childrenOnly); 232 } 233 234 @Override relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, Surface outSurface)235 public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, 236 int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber, 237 Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, 238 Rect outStableInsets, Rect outsets, Rect outBackdropFrame, 239 DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, 240 Surface outSurface) { 241 if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from " 242 + Binder.getCallingPid()); 243 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag); 244 int res = mService.relayoutWindow(this, window, seq, attrs, 245 requestedWidth, requestedHeight, viewFlags, flags, frameNumber, 246 outFrame, outOverscanInsets, outContentInsets, outVisibleInsets, 247 outStableInsets, outsets, outBackdropFrame, cutout, 248 mergedConfiguration, outSurface); 249 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 250 if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to " 251 + Binder.getCallingPid()); 252 return res; 253 } 254 255 @Override outOfMemory(IWindow window)256 public boolean outOfMemory(IWindow window) { 257 return mService.outOfMemoryWindow(this, window); 258 } 259 260 @Override setTransparentRegion(IWindow window, Region region)261 public void setTransparentRegion(IWindow window, Region region) { 262 mService.setTransparentRegionWindow(this, window, region); 263 } 264 265 @Override setInsets(IWindow window, int touchableInsets, Rect contentInsets, Rect visibleInsets, Region touchableArea)266 public void setInsets(IWindow window, int touchableInsets, 267 Rect contentInsets, Rect visibleInsets, Region touchableArea) { 268 mService.setInsetsWindow(this, window, touchableInsets, contentInsets, 269 visibleInsets, touchableArea); 270 } 271 272 @Override getDisplayFrame(IWindow window, Rect outDisplayFrame)273 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) { 274 mService.getWindowDisplayFrame(this, window, outDisplayFrame); 275 } 276 277 @Override finishDrawing(IWindow window)278 public void finishDrawing(IWindow window) { 279 if (WindowManagerService.localLOGV) Slog.v( 280 TAG_WM, "IWindow finishDrawing called for " + window); 281 mService.finishDrawingWindow(this, window); 282 } 283 284 @Override setInTouchMode(boolean mode)285 public void setInTouchMode(boolean mode) { 286 synchronized(mService.mWindowMap) { 287 mService.mInTouchMode = mode; 288 } 289 } 290 291 @Override getInTouchMode()292 public boolean getInTouchMode() { 293 synchronized(mService.mWindowMap) { 294 return mService.mInTouchMode; 295 } 296 } 297 298 @Override performHapticFeedback(IWindow window, int effectId, boolean always)299 public boolean performHapticFeedback(IWindow window, int effectId, 300 boolean always) { 301 synchronized(mService.mWindowMap) { 302 long ident = Binder.clearCallingIdentity(); 303 try { 304 return mService.mPolicy.performHapticFeedbackLw( 305 mService.windowForClientLocked(this, window, true), 306 effectId, always); 307 } finally { 308 Binder.restoreCallingIdentity(ident); 309 } 310 } 311 } 312 313 /* Drag/drop */ 314 315 @Override performDrag(IWindow window, int flags, SurfaceControl surface, int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY, ClipData data)316 public IBinder performDrag(IWindow window, int flags, SurfaceControl surface, int touchSource, 317 float touchX, float touchY, float thumbCenterX, float thumbCenterY, ClipData data) { 318 final int callerPid = Binder.getCallingPid(); 319 final int callerUid = Binder.getCallingUid(); 320 final long ident = Binder.clearCallingIdentity(); 321 try { 322 return mDragDropController.performDrag(mSurfaceSession, callerPid, callerUid, window, 323 flags, surface, touchSource, touchX, touchY, thumbCenterX, thumbCenterY, data); 324 } finally { 325 Binder.restoreCallingIdentity(ident); 326 } 327 } 328 329 @Override reportDropResult(IWindow window, boolean consumed)330 public void reportDropResult(IWindow window, boolean consumed) { 331 final long ident = Binder.clearCallingIdentity(); 332 try { 333 mDragDropController.reportDropResult(window, consumed); 334 } finally { 335 Binder.restoreCallingIdentity(ident); 336 } 337 } 338 339 @Override cancelDragAndDrop(IBinder dragToken)340 public void cancelDragAndDrop(IBinder dragToken) { 341 final long ident = Binder.clearCallingIdentity(); 342 try { 343 mDragDropController.cancelDragAndDrop(dragToken); 344 } finally { 345 Binder.restoreCallingIdentity(ident); 346 } 347 } 348 349 @Override dragRecipientEntered(IWindow window)350 public void dragRecipientEntered(IWindow window) { 351 mDragDropController.dragRecipientEntered(window); 352 } 353 354 @Override dragRecipientExited(IWindow window)355 public void dragRecipientExited(IWindow window) { 356 mDragDropController.dragRecipientExited(window); 357 } 358 359 @Override startMovingTask(IWindow window, float startX, float startY)360 public boolean startMovingTask(IWindow window, float startX, float startY) { 361 if (DEBUG_TASK_POSITIONING) Slog.d( 362 TAG_WM, "startMovingTask: {" + startX + "," + startY + "}"); 363 364 long ident = Binder.clearCallingIdentity(); 365 try { 366 return mService.mTaskPositioningController.startMovingTask(window, startX, startY); 367 } finally { 368 Binder.restoreCallingIdentity(ident); 369 } 370 } 371 372 @Override setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep)373 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) { 374 synchronized(mService.mWindowMap) { 375 long ident = Binder.clearCallingIdentity(); 376 try { 377 mService.mRoot.mWallpaperController.setWindowWallpaperPosition( 378 mService.windowForClientLocked(this, window, true), 379 x, y, xStep, yStep); 380 } finally { 381 Binder.restoreCallingIdentity(ident); 382 } 383 } 384 } 385 386 @Override wallpaperOffsetsComplete(IBinder window)387 public void wallpaperOffsetsComplete(IBinder window) { 388 synchronized (mService.mWindowMap) { 389 mService.mRoot.mWallpaperController.wallpaperOffsetsComplete(window); 390 } 391 } 392 393 @Override setWallpaperDisplayOffset(IBinder window, int x, int y)394 public void setWallpaperDisplayOffset(IBinder window, int x, int y) { 395 synchronized(mService.mWindowMap) { 396 long ident = Binder.clearCallingIdentity(); 397 try { 398 mService.mRoot.mWallpaperController.setWindowWallpaperDisplayOffset( 399 mService.windowForClientLocked(this, window, true), x, y); 400 } finally { 401 Binder.restoreCallingIdentity(ident); 402 } 403 } 404 } 405 406 @Override sendWallpaperCommand(IBinder window, String action, int x, int y, int z, Bundle extras, boolean sync)407 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y, 408 int z, Bundle extras, boolean sync) { 409 synchronized(mService.mWindowMap) { 410 long ident = Binder.clearCallingIdentity(); 411 try { 412 return mService.mRoot.mWallpaperController.sendWindowWallpaperCommand( 413 mService.windowForClientLocked(this, window, true), 414 action, x, y, z, extras, sync); 415 } finally { 416 Binder.restoreCallingIdentity(ident); 417 } 418 } 419 } 420 421 @Override wallpaperCommandComplete(IBinder window, Bundle result)422 public void wallpaperCommandComplete(IBinder window, Bundle result) { 423 synchronized (mService.mWindowMap) { 424 mService.mRoot.mWallpaperController.wallpaperCommandComplete(window); 425 } 426 } 427 428 @Override onRectangleOnScreenRequested(IBinder token, Rect rectangle)429 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) { 430 synchronized(mService.mWindowMap) { 431 final long identity = Binder.clearCallingIdentity(); 432 try { 433 mService.onRectangleOnScreenRequested(token, rectangle); 434 } finally { 435 Binder.restoreCallingIdentity(identity); 436 } 437 } 438 } 439 440 @Override getWindowId(IBinder window)441 public IWindowId getWindowId(IBinder window) { 442 return mService.getWindowId(window); 443 } 444 445 @Override pokeDrawLock(IBinder window)446 public void pokeDrawLock(IBinder window) { 447 final long identity = Binder.clearCallingIdentity(); 448 try { 449 mService.pokeDrawLock(this, window); 450 } finally { 451 Binder.restoreCallingIdentity(identity); 452 } 453 } 454 455 @Override updatePointerIcon(IWindow window)456 public void updatePointerIcon(IWindow window) { 457 final long identity = Binder.clearCallingIdentity(); 458 try { 459 mService.updatePointerIcon(window); 460 } finally { 461 Binder.restoreCallingIdentity(identity); 462 } 463 } 464 465 @Override updateTapExcludeRegion(IWindow window, int regionId, int left, int top, int width, int height)466 public void updateTapExcludeRegion(IWindow window, int regionId, int left, int top, int width, 467 int height) { 468 final long identity = Binder.clearCallingIdentity(); 469 try { 470 mService.updateTapExcludeRegion(window, regionId, left, top, width, height); 471 } finally { 472 Binder.restoreCallingIdentity(identity); 473 } 474 } 475 windowAddedLocked(String packageName)476 void windowAddedLocked(String packageName) { 477 mPackageName = packageName; 478 mRelayoutTag = "relayoutWindow: " + mPackageName; 479 if (mSurfaceSession == null) { 480 if (WindowManagerService.localLOGV) Slog.v( 481 TAG_WM, "First window added to " + this + ", creating SurfaceSession"); 482 mSurfaceSession = new SurfaceSession(); 483 if (SHOW_TRANSACTIONS) Slog.i( 484 TAG_WM, " NEW SURFACE SESSION " + mSurfaceSession); 485 mService.mSessions.add(this); 486 if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) { 487 mService.dispatchNewAnimatorScaleLocked(this); 488 } 489 } 490 mNumWindow++; 491 } 492 windowRemovedLocked()493 void windowRemovedLocked() { 494 mNumWindow--; 495 killSessionLocked(); 496 } 497 498 onWindowSurfaceVisibilityChanged(WindowSurfaceController surfaceController, boolean visible, int type)499 void onWindowSurfaceVisibilityChanged(WindowSurfaceController surfaceController, 500 boolean visible, int type) { 501 502 if (!isSystemAlertWindowType(type)) { 503 return; 504 } 505 506 boolean changed; 507 508 if (!mCanAddInternalSystemWindow) { 509 // We want to track non-system signature apps adding alert windows so we can post an 510 // on-going notification for the user to control their visibility. 511 if (visible) { 512 changed = mAlertWindowSurfaces.add(surfaceController); 513 MetricsLoggerWrapper.logAppOverlayEnter(mUid, mPackageName, changed, type, true); 514 } else { 515 changed = mAlertWindowSurfaces.remove(surfaceController); 516 MetricsLoggerWrapper.logAppOverlayExit(mUid, mPackageName, changed, type, true); 517 } 518 519 if (changed) { 520 if (mAlertWindowSurfaces.isEmpty()) { 521 cancelAlertWindowNotification(); 522 } else if (mAlertWindowNotification == null){ 523 mAlertWindowNotification = new AlertWindowNotification(mService, mPackageName); 524 if (mShowingAlertWindowNotificationAllowed) { 525 mAlertWindowNotification.post(); 526 } 527 } 528 } 529 } 530 531 if (type != TYPE_APPLICATION_OVERLAY) { 532 return; 533 } 534 535 if (visible) { 536 changed = mAppOverlaySurfaces.add(surfaceController); 537 MetricsLoggerWrapper.logAppOverlayEnter(mUid, mPackageName, changed, type, false); 538 } else { 539 changed = mAppOverlaySurfaces.remove(surfaceController); 540 MetricsLoggerWrapper.logAppOverlayExit(mUid, mPackageName, changed, type, false); 541 } 542 543 if (changed) { 544 // Notify activity manager of changes to app overlay windows so it can adjust the 545 // importance score for the process. 546 setHasOverlayUi(!mAppOverlaySurfaces.isEmpty()); 547 } 548 } 549 setShowingAlertWindowNotificationAllowed(boolean allowed)550 void setShowingAlertWindowNotificationAllowed(boolean allowed) { 551 mShowingAlertWindowNotificationAllowed = allowed; 552 if (mAlertWindowNotification != null) { 553 if (allowed) { 554 mAlertWindowNotification.post(); 555 } else { 556 mAlertWindowNotification.cancel(false /* deleteChannel */); 557 } 558 } 559 } 560 killSessionLocked()561 private void killSessionLocked() { 562 if (mNumWindow > 0 || !mClientDead) { 563 return; 564 } 565 566 mService.mSessions.remove(this); 567 if (mSurfaceSession == null) { 568 return; 569 } 570 571 if (WindowManagerService.localLOGV) Slog.v(TAG_WM, "Last window removed from " + this 572 + ", destroying " + mSurfaceSession); 573 if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " KILL SURFACE SESSION " + mSurfaceSession); 574 try { 575 mSurfaceSession.kill(); 576 } catch (Exception e) { 577 Slog.w(TAG_WM, "Exception thrown when killing surface session " + mSurfaceSession 578 + " in session " + this + ": " + e.toString()); 579 } 580 mSurfaceSession = null; 581 mAlertWindowSurfaces.clear(); 582 mAppOverlaySurfaces.clear(); 583 setHasOverlayUi(false); 584 cancelAlertWindowNotification(); 585 } 586 setHasOverlayUi(boolean hasOverlayUi)587 private void setHasOverlayUi(boolean hasOverlayUi) { 588 mService.mH.obtainMessage(H.SET_HAS_OVERLAY_UI, mPid, hasOverlayUi ? 1 : 0).sendToTarget(); 589 } 590 cancelAlertWindowNotification()591 private void cancelAlertWindowNotification() { 592 if (mAlertWindowNotification == null) { 593 return; 594 } 595 mAlertWindowNotification.cancel(true /* deleteChannel */); 596 mAlertWindowNotification = null; 597 } 598 dump(PrintWriter pw, String prefix)599 void dump(PrintWriter pw, String prefix) { 600 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow); 601 pw.print(" mCanAddInternalSystemWindow="); pw.print(mCanAddInternalSystemWindow); 602 pw.print(" mAppOverlaySurfaces="); pw.print(mAppOverlaySurfaces); 603 pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces); 604 pw.print(" mClientDead="); pw.print(mClientDead); 605 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession); 606 pw.print(prefix); pw.print("mPackageName="); pw.println(mPackageName); 607 } 608 609 @Override toString()610 public String toString() { 611 return mStringName; 612 } 613 hasAlertWindowSurfaces()614 boolean hasAlertWindowSurfaces() { 615 return !mAlertWindowSurfaces.isEmpty(); 616 } 617 } 618