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