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