Android WindowManagerService相关的Session

本文基于Android7.0

Session类路径

framework/base/services/core/java/com/android/server/wm/Session.java

内容

/** * This class represents an active client session. There is generally one * Session object per process that is interacting with the window manager. */
final class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
    final WindowManagerService mService;
    final IWindowSessionCallback mCallback;
    final IInputMethodClient mClient;
    final IInputContext mInputContext;
    final int mUid;
    final int mPid;
    final String mStringName;
    SurfaceSession mSurfaceSession;
    int mNumWindow = 0;
    boolean mClientDead = false;
    float mLastReportedAnimatorScale;

那么这个类继承自IWindowSession.Stub,所以他是个AIDL服务器端的实现,客户端要使用它时,会通过IWindowSession.Stub.asInterface这种调用获取aidl的对应代理,不过搜索了一下源码,没找到对应的代码,这就非常奇怪了,有待后续调查

一个函数

    public void remove(IWindow window) {
        mService.removeWindow(this, window);
    }

其实该类中大部分函数都是调用mService的方法
而mService就是WindowManagerService
所以本质上Session其实用来调用WindowManagerService中方法的一个类

从网上的一些文章看,这个Session是每个app一个Session
一个Session可以对应多个WindowState,或者叫多个Window
当然,一个app可以有多个Window,比如:主画面是一个Window,弹出菜单是另外一个Window

以Android7.0刚启动的情况,进入adb shell
执行dumpsys window
找到WINDOW MANAGER WINDOWS (dumpsys window windows)部分内容如下:

WINDOW MANAGER WINDOWS (dumpsys window windows)
  Window #5 Window{125c9d7 u0 NavigationBar}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} mClient=android.os.BinderProxy@f07a556
    mOwnerUid=10026 mShowToOwnerOnly=false package=com.android.systemui appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=2019 fl=#1840068 fmt=-3}
    Requested w=1280 h=544 mLayoutSeq=87
    mHasSurface=true mShownPosition=[0,624] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{5066eb7 NavigationBar}:
      Surface: shown=true layer=211000 alpha=1.0 rect=(0.0,624.0) 1280.0 x 96.0
    mLastFreezeDuration=+165ms
  Window #4 Window{1669639 u0 StatusBar}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} mClient=android.os.BinderProxy@3083e00
    mOwnerUid=10026 mShowToOwnerOnly=false package=com.android.systemui appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(fillx96) gr=#30 sim=#10 ty=2000 fl=#81840048 fmt=-3 vsysui=0x600}
    Requested w=1280 h=96 mLayoutSeq=87
    mHasSurface=true mShownPosition=[0,0] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{3e251b6 StatusBar}:
      Surface: shown=true layer=161000 alpha=1.0 rect=(0.0,0.0) 1280.0 x 96.0
    mLastFreezeDuration=+257ms
  Window #3 Window{4581587 u0 KeyguardScrim}:
    mDisplayId=0 stackId=0 mSession=Session{ef9f4e4 1505:1000} mClient=android.view.ViewRootImpl$W@f8a11c6
    mOwnerUid=1000 mShowToOwnerOnly=false package=android appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#10 ty=2029 fl=#1110900 pfl=0x1 fmt=-3 or=5 vsysui=0x3610000}
    Requested w=1280 h=624 mLayoutSeq=44
    mHasSurface=false mShownPosition=[0,0] isReadyForDisplay()=false hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{649f551 KeyguardScrim}:
  Window #2 Window{45af05b u0 DockedStackDivider}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} mClient=android.os.BinderProxy@abf036a
    mOwnerUid=10026 mShowToOwnerOnly=false package=com.android.systemui appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(48xfill) sim=#20 ty=2034 fl=#21840028 pfl=0x40 fmt=-3 vsysui=0x700}
    Requested w=48 h=528 mLayoutSeq=87
    mPolicyVisibility=false mPolicyVisibilityAfterAnim=false mAppOpVisibility=true mAttachedHidden=false
    mHasSurface=false mShownPosition=[0,0] isReadyForDisplay()=false hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{15fca78 DockedStackDivider}:
      mShownAlpha=0.0 mAlpha=1.0 mLastAlpha=0.0
  Window #1 Window{a1fb83b u0 com.android.launcher/com.android.launcher2.Launcher}:
    mDisplayId=0 stackId=0 mSession=Session{3fca46c 1958:u0a10016} mClient=android.os.BinderProxy@5bc7eca
    mOwnerUid=10016 mShowToOwnerOnly=true package=com.android.launcher appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=1 fl=#d910100 pfl=0x20000 fmt=-2 wanim=0x10303ea vsysui=0x700 needsMenuKey=2}
    Requested w=1280 h=528 mLayoutSeq=87
    mHasSurface=true mShownPosition=[0,0] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{6d6afdb com.android.launcher/com.android.launcher2.Launcher}:
      Surface: shown=true layer=21005 alpha=1.0 rect=(0.0,0.0) 1280.0 x 720.0
    mLastFreezeDuration=+1s119ms
    mWallpaperX=0.0 mWallpaperY=0.5
    mWallpaperXStep=0.0 mWallpaperYStep=0.0
  Window #0 Window{cf21006 u0 com.android.systemui.ImageWallpaper}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} mClient=android.os.BinderProxy@5037ae1
    mOwnerUid=10026 mShowToOwnerOnly=true package=com.android.systemui appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(1280x720) gr=#800033 ty=2013 fl=#10318 fmt=2 wanim=0x10302f2}
    Requested w=1280 h=720 mLayoutSeq=87
    mIsImWindow=false mIsWallpaper=true mIsFloatingLayer=true mWallpaperVisible=true
    mHasSurface=true mShownPosition=[0,0] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{1dc10ea com.android.systemui.ImageWallpaper}:
      Surface: shown=true layer=21000 alpha=1.0 rect=(0.0,0.0) 1280.0 x 720.0
    mLastFreezeDuration=+1s120ms
    mWallpaperX=0.0 mWallpaperY=0.5
    mWallpaperXStep=0.0 mWallpaperYStep=0.0

可以看到开机刚启动结束,桌面显示出来的情况下,系统就已经有6个Window,我们把这部分内容浓缩一下

  Window #5 Window{125c9d7 u0 NavigationBar}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} 
  Window #4 Window{1669639 u0 StatusBar}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} 
  Window #3 Window{4581587 u0 KeyguardScrim}:
    mDisplayId=0 stackId=0 mSession=Session{ef9f4e4 1505:1000} 
  Window #2 Window{45af05b u0 DockedStackDivider}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} 
  Window #1 Window{a1fb83b u0 com.android.launcher/com.android.launcher2.Launcher}:
    mDisplayId=0 stackId=0 mSession=Session{3fca46c 1958:u0a10016} 
  Window #0 Window{cf21006 u0 com.android.systemui.ImageWallpaper}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} 

他们分别是
NavigationBar,
StatusBar,
KeyguardScrim,
DockedStackDivider,com.android.launcher/com.android.launcher2.Launcher
com.android.systemui.ImageWallpaper

从上面的dump log可以看出
NavigationBar,
StatusBar,
DockedStackDivider,
com.android.systemui.ImageWallpaper
的Session是同一个

mSession=Session{1b0f084 1627:u0a10026} 

这个Session对应的app就是SystemUI
路径为

frameworks/base/packages/SystemUI

Launcher的Session是

mSession=Session{3fca46c 1958:u0a10016} 

对应的app是Launcher就是桌面或者Home,路径为

packages/apps/Launcher2

KeyguardScrim的Session是

mSession=Session{ef9f4e4 1505:1000} 

这个Session对应的app没做过相关调查,不清楚属于哪个app进程,有待调查

从上面的内容可以得出结论,一个Session确实对应一个app进程,一个Session确实可以对应多个Window,SystemUI就是4个Window

下面我们再来试试启动一个普通的app Calculator
你会发现dump log中多了一个Window,

  Window #2 Window{982977b u0 com.android.calculator2/com.android.calculator2.Calculator}:
    mDisplayId=0 stackId=1 mSession=Session{3c2ceac 2224:u0a10043} mClient=android.os.BinderProxy@fee530a
    mOwnerUid=10043 mShowToOwnerOnly=true package=com.android.calculator2 appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#123 ty=1 fl=#81810100 pfl=0x20000 wanim=0x1030468 vsysui=0x600 needsMenuKey=2}
    Requested w=1280 h=528 mLayoutSeq=112
    mHasSurface=true mShownPosition=[0,0] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{9be4744 com.android.calculator2/com.android.calculator2.Calculator}:
      Surface: shown=true layer=21010 alpha=1.0 rect=(0.0,0.0) 1280.0 x 720.0

Session是

mSession=Session{3c2ceac 2224:u0a10043}

之后我们弹出Calculator的菜单,再dumpsys window看一下
多了一个PopupWindow

  Window #3 Window{d4992ba u0 PopupWindow:822a2fb}:
    mDisplayId=0 stackId=1 mSession=Session{3c2ceac 2224:u0a10043} mClient=android.os.BinderProxy@89947e5
    mOwnerUid=10043 mShowToOwnerOnly=true package=com.android.calculator2 appop=NONE
    mAttrs=WM.LayoutParams{(1072,104)(196x48) gr=#33 sim=#11 ty=1002 fl=#41860200 pfl=0x18000 fmt=-3 surfaceInsets=Rect(32, 32 - 32, 32) (manual)}
    Requested w=196 h=48 mLayoutSeq=116
    mAttachedWindow=Window{982977b u0 com.android.calculator2/com.android.calculator2.Calculator} mLayoutAttached=true
    mHasSurface=true mShownPosition=[1072,104] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{8e4556b PopupWindow:822a2fb}:
      Surface: shown=true layer=21015 alpha=1.0 rect=(1040.0,72.0) 260.0 x 112.0

Session是

mSession=Session{3c2ceac 2224:u0a10043}

与Calculator相同的Session,这也充分证明了前面的结论是正确的

其实这个Session类还有个很重要的成员

    SurfaceSession mSurfaceSession;

对应有3个关键方法


    void windowAddedLocked() {
        if (mSurfaceSession == null) {
            if (WindowManagerService.localLOGV) Slog.v(
                TAG_WM, "First window added to " + this + ", creating SurfaceSession");
            mSurfaceSession = new SurfaceSession();
            if (SHOW_TRANSACTIONS) Slog.i(
                    TAG_WM, " NEW SURFACE SESSION " + mSurfaceSession);
            mService.mSessions.add(this);
            if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
                mService.dispatchNewAnimatorScaleLocked(this);
            }
        }
        mNumWindow++;
    }

    void windowRemovedLocked() {
        mNumWindow--;
        killSessionLocked();
    }

    void killSessionLocked() {
        if (mNumWindow <= 0 && mClientDead) {
            mService.mSessions.remove(this);
            if (mSurfaceSession != null) {
                if (WindowManagerService.localLOGV) Slog.v(
                    TAG_WM, "Last window removed from " + this
                    + ", destroying " + mSurfaceSession);
                if (SHOW_TRANSACTIONS) Slog.i(
                        TAG_WM, " KILL SURFACE SESSION " + mSurfaceSession);
                try {
                    mSurfaceSession.kill();
                } catch (Exception e) {
                    Slog.w(TAG_WM, "Exception thrown when killing surface session "
                        + mSurfaceSession + " in session " + this
                        + ": " + e.toString());
                }
                mSurfaceSession = null;
            }
        }
    }

这样看起来
windowAddedLocked()
windowRemovedLocked()
是成对的方法,对应Window追加和删除
第一次追加Window时,如果mSurfaceSession为null就创建一个并且将自己放到WindowManagerService的mSessions列表中
删除时如果mNumWindow小于等于0就从mSessions列表中删除,并kill掉SurfaceSession

至于SurfaceSession具体是什么,不得而知
猜测跟SurfaceFlinger有关系,具体可以参考下面的文章
http://blog.csdn.net/jamikabin/article/details/54411769

    原文作者:jamikabin
    原文地址: https://blog.csdn.net/jamikabin/article/details/54411544
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞