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