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