本文基于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