代码人生的小狗窝

一行行枯燥的代码,却描绘出人生的点点滴滴

您现在的位置是:首页>_移动开发

Activity与WindowManagerService连接的进程(三)

发布时间:2019-11-22浏览(2585)

    Activity与WindowManagerService连接的过程(三)
    page11
        WindowManagerService的getDisplayContentLocked函数的定义如下:
        1     public DisplayContent getDisplayContentLocked(final int displayId) {
        2         DisplayContent displayContent = mDisplayContents.get(displayId);
        3         if (displayContent == null) {
        4             final Display display = mDisplayManager.getDisplay(displayId);
        5             if (display != null) {
        6                 displayContent = new DisplayContent(display);
        7                 mDisplayContents.put(displayId, displayContent);
        8             }
        9         }
        10         return displayContent;
        11     }
        getDisplayContentLocked函数的逻辑还是比较简单的.
    page12
        在这篇文章里, 我们分析一下WindowState的创建过程.
        WindowState类的定义如下:
        final class WindowState implements WindowManagerPolicy.WindowState
        WindowState类的定义如下:
        1     WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
        2            WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
        3            int viewVisibility, final DisplayContent displayContent) {
        4         mService = service;
        5         mSession = s;
        6         mClient = c;
        7         mToken = token;
        8         mOwnerUid = s.mUid;
        9         mAttrs.copyFrom(a);
        10         mViewVisibility = viewVisibility;
        11         mDisplayContent = displayContent;
        12         mPolicy = mService.mPolicy;
        13         mContext = mService.mContext;
        14         DeathRecipient deathRecipient = new DeathRecipient();
        15         mSeq = seq;
        16         mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
        17         if (WindowManagerService.localLOGV) Slog.v(
        18             TAG, "Window " + this + " client=" + c.asBinder()
        19             + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);
        20         try {
        21             c.asBinder().linkToDeath(deathRecipient, 0);
        22         } catch (RemoteException e) {
        23             mDeathRecipient = null;
        24             mAttachedWindow = null;
        25             mLayoutAttached = false;
        26             mIsImWindow = false;
        27             mIsWallpaper = false;
        28             mIsFloatingLayer = false;
        29             mBaseLayer = 0;
        30             mSubLayer = 0;
        31             mInputWindowHandle = null;
        32             mWinAnimator = null;
        33             return;
        34         }
        35         mDeathRecipient = deathRecipient;
        36
        37         if ((mAttrs.type >= FIRST_SUB_WINDOW &&
        38                 mAttrs.type <= LAST_SUB_WINDOW)) {
        39             // The multiplier here is to reserve space for multiple
        40             // windows in the same type layer.
        41             mBaseLayer = mPolicy.windowTypeToLayerLw(
        42                     attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER
        43                     + WindowManagerService.TYPE_LAYER_OFFSET;
        44             mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
        45             mAttachedWindow = attachedWindow;
        46             if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
        47             mAttachedWindow.mChildWindows.add(this);
        48             mLayoutAttached = mAttrs.type !=
        49                     WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
        50             mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
        51                     || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
        52             mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
        53             mIsFloatingLayer = mIsImWindow || mIsWallpaper;
        54         } else {
        55             // The multiplier here is to reserve space for multiple
        56             // windows in the same type layer.
        57             mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
        58                     * WindowManagerService.TYPE_LAYER_MULTIPLIER
        59                     + WindowManagerService.TYPE_LAYER_OFFSET;
        60             mSubLayer = 0;
        61             mAttachedWindow = null;
        62             mLayoutAttached = false;
        63             mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
        64                     || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
        65             mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
        66             mIsFloatingLayer = mIsImWindow || mIsWallpaper;
        67         }
        68
        69         WindowState appWin = this;
        70         while (appWin.mAttachedWindow != null) {
        71             appWin = appWin.mAttachedWindow;
        72         }
        73         WindowToken appToken = appWin.mToken;
        74         while (appToken.appWindowToken == null) {
        75             WindowToken parent = mService.mTokenMap.get(appToken.token);
        76             if (parent == null || appToken == parent) {
        77                 break;
        78             }
        79             appToken = parent;
        80         }
        81         mRootToken = appToken;
        82         mAppToken = appToken.appWindowToken;
        83
        84         mWinAnimator = new WindowStateAnimator(this);
        85         mWinAnimator.mAlpha = a.alpha;
        86
        87         mRequestedWidth = 0;
        88         mRequestedHeight = 0;
        89         mLastRequestedWidth = 0;
        90         mLastRequestedHeight = 0;
        91         mXOffset = 0;
        92         mYOffset = 0;
        93         mLayer = 0;
        94         mInputWindowHandle = new InputWindowHandle(
        95                 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this,
        96                 displayContent.getDisplayId());
        97     }
        第6行(WindowState->WindowState)会将IWindow接口保存到成员变量mClient中去.
    page13
    WindowState的attach函数的定义如下:
    1     void attach() {
    2         if (WindowManagerService.localLOGV) Slog.v(
    3             TAG, "Attaching " + this + " token=" + mToken
    4             + ", list=" + mToken.windows);
    5         mSession.windowAddedLocked();
    6     }
    第5行(WindowState->attach)会调用Session的windowAddedLocked函数, 关于Session的windowAddedLocked函数的详细分析可以参考page14文件.
    page14
    这里我们分析一下Session的windowAddedLocked函数的实现, Session的windowAddedLocked函数的定义如下:
    1     void windowAddedLocked() {
        2         if (mSurfaceSession == null) {
        3             if (WindowManagerService.localLOGV) Slog.v(
        4                 WindowManagerService.TAG, "First window added to " + this + ", creating SurfaceSession");
        5             mSurfaceSession = new SurfaceSession();
        6             if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
        7                     WindowManagerService.TAG, "  NEW SURFACE SESSION " + mSurfaceSession);
        8             mService.mSessions.add(this);
        9         }
        10         mNumWindow++;
        11     }
        第2行(Session->windowAddedLocked)判断是否已经创建过SurfaceSession, 如果是就不用在创建了. 由此可知, 每一个Activity都对应有一个SurfaceSession对象.
        第5行(Session->windowAddedLocked)会创建一个SurfaceSession对象, 关于SurfaceSession对象的创建过程可以参考page15文件.
        第8行(Session->windowAddedLocked)会将本Session加入到mService.mSessions中去, mService.mSessions的定义如下:
        final HashSet<Session> mSessions = new HashSet<Session>();
        mSessions保存着当前活跃的连接
        最后, 第10行(Session->windowAddedLocked)会将window的数量加1.
    page15
    这里我们关注一下SurfaceSession对象的创建, SurfaceSession类的构造函数的定义如下:
    1 public SurfaceSession() {
    2 mNativeClient = nativeCreate();
    3 }
    第2行(SurfaceSession->SurfaceSession)会调用nativeCreate函数, nativeCreate函数的定义如下:
    private static native int nativeCreate();
    这是个native函数, 最终会调用android_view_surfaceSession.cpp中的nativeCreate函数, android_view_surfaceSession.cpp中的nativeCreate函数的定义如下:
    1 static jint nativeCreate(JNIEnv* env, jclass clazz) {
    2     SurfaceComposerClient* client = new SurfaceComposerClient();
    3     client->incStrong(clazz);
    4     return reinterpret_cast<jint>(client);
    5 }
    我靠, 我靠, 我靠!看到了吧, 第三行(android_view_surfaceSession.cpp::nativeCreate)会创建一个SurfaceComposerClient, 是不是很熟悉.