Android應(yīng)用與SurfaceFlinger建立連接的過(guò)程

基于Android 9.0源碼分析

類圖

  • DecorView
    • Android窗口的頂級(jí)View
  • PhoneWindow
    • 代表Android窗口
  • WindowManagerImpl
    • 應(yīng)用通過(guò)該類與系統(tǒng)窗口管理服務(wù)通信,關(guān)聯(lián)特定的窗口
  • WindowManagerGlobal
    • 進(jìn)程全局對(duì)象,實(shí)現(xiàn)WindowManagerImpl與系統(tǒng)窗口管理服務(wù)的通信
  • ViewRootImpl
    • 實(shí)現(xiàn)了View與窗口管理之間的協(xié)議
  • Choreographer
    • Choreographer收到顯示子系統(tǒng)發(fā)送的Vsync信號(hào)后,協(xié)調(diào)下一幀渲染中的動(dòng)畫(huà)、輸入和繪制過(guò)程
  • FrameDisplayEventReceiver
    • 在應(yīng)用內(nèi)請(qǐng)求、接收顯示事件(Vsync信號(hào)等)
  • ISurfaceComposer
    • 定義訪問(wèn)SurfaceFlinger的Binder IPC接口
  • BitTube
    • Socket的封裝,用于進(jìn)程間通信,可跨進(jìn)程傳遞

Android應(yīng)用與SurfaceFlinger建立連接的過(guò)程

Android應(yīng)用在執(zhí)行完Activity的onResume()后會(huì)建立與SurfaceFlinger的連接,以便接受SurfaceFlinger發(fā)送的Vsync信號(hào),下面從ActivityThreadhandleResumeActivity()開(kāi)始分析。

public void handleResumeActivity(IBinder token, boolean finalStateRequest, booleanisForward,
        String reason) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;
    // TODO Push resumeArgs into the activity for consideration
    // 調(diào)用Activity的onResume的方法
    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
    if (r == null) {
        // We didn't actually resume the activity, so skipping any follow-up actions.
        return;
    }
    ......
    if (r.window == null && !a.mFinished && willBeVisible) {
        // PhoneWindow對(duì)象
        r.window = r.activity.getWindow();
        // DecorView對(duì)象
        View decor = r.window.getDecorView();
        decor.setVisibility(View.INVISIBLE);
        // wm為WindowManagerImpl對(duì)象
        ViewManager wm = a.getWindowManager();
        // 窗口布局參數(shù)
        WindowManager.LayoutParams l = r.window.getAttributes();
        // 設(shè)置Activity的DecorView
        a.mDecor = decor;
        l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
        l.softInputMode |= forwardBit;
        if (r.mPreserveWindow) {
            a.mWindowAdded = true;
            r.mPreserveWindow = false;
            // Normally the ViewRoot sets up callbacks with the Activity
            // in addView->ViewRootImpl#setView. If we are instead reusing
            // the decor view we have to notify the view root that the
            // callbacks may have changed.
            ViewRootImpl impl = decor.getViewRootImpl();
            if (impl != null) {
                impl.notifyChildRebuilt();
            }
        }
        // 通常mVisibleFromClient為true
        if (a.mVisibleFromClient) {
            // mWindowAdded這里為false
            if (!a.mWindowAdded) {
                a.mWindowAdded = true;
                // 設(shè)置DecorView的LayoutParams,添加DecorView到Window
                wm.addView(decor, l);
            } else {
                // The activity will get a callback for this {@link LayoutParams} change
                // earlier. However, at that time the decor will not be set (this is set
                // in this method), so no action will be taken. This call ensures the
                // callback occurs with the decor set.
                a.onWindowAttributesChanged(l);
            }
        }
        // If the window has already been added, but during resume
        // we started another activity, then don't yet make the
        // window visible.
    } else if (!willBeVisible) {
        if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
        r.hideForNow = true;
    }
    ......
}

下面看WindowManagerImpladdView()的實(shí)現(xiàn)

public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
    // 設(shè)置params的token
    applyDefaultToken(params);
    // 調(diào)用WindowManagerGlobal的addView
    mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}

public void addView(View view, ViewGroup.LayoutParams params,
        Display display, Window parentWindow) {
    // view為DecorView
    // params為DecorView關(guān)聯(lián)的LayoutParams
    // parentWindow為PhoneWindow
    if (view == null) {
        throw new IllegalArgumentException("view must not be null");
    }
    if (display == null) {
        throw new IllegalArgumentException("display must not be null");
    }
    if (!(params instanceof WindowManager.LayoutParams)) {
        throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
    }
    final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
    if (parentWindow != null) {
        // 設(shè)置LayoutParams的token、Title和包名等
        parentWindow.adjustLayoutParamsForSubWindow(wparams);
    } else {
        // If there's no parent, then hardware acceleration for this view is
        // set from the application's hardware acceleration setting.
        final Context context = view.getContext();
        if (context != null
                && (context.getApplicationInfo().flags
                        & ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
            wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
        }
    }
    synchronized (mLock) {
        // Start watching for system property changes.
        // 監(jiān)聽(tīng)系統(tǒng)屬性的改變,觀察者模式
        if (mSystemPropertyUpdater == null) {
            mSystemPropertyUpdater = new Runnable() {
                @Override public void run() {
                    synchronized (mLock) {
                        for (int i = mRoots.size() - 1; i >= 0; --i) {
                            mRoots.get(i).loadSystemProperties();
                        }
                    }
                }
            };
            SystemProperties.addChangeCallback(mSystemPropertyUpdater);
        }
        // 查找DecorView
        int index = findViewLocked(view, false);
        if (index >= 0) {
            if (mDyingViews.contains(view)) {
                // Don't wait for MSG_DIE to make it's way through root's queue.
                mRoots.get(index).doDie();
            } else {
                throw new IllegalStateException("View " + view
                        + " has already been added to the window manager.");
            }
            // The previous removeView() had not completed executing. Now it has.
        }
        // If this is a panel window, then find the window it is being
        // attached to for future reference.
        if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
                wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
            final int count = mViews.size();
            for (int i = 0; i < count; i++) {
                if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
                    panelParentView = mViews.get(i);
                }
            }
        }
        // 創(chuàng)建ViewRootImpl
        root = new ViewRootImpl(view.getContext(), display);
        // 設(shè)置View布局參數(shù)
        view.setLayoutParams(wparams);
        // DecorView/ViewRootImpl/LayoutParams添加到WindowManagerGlobal
        mViews.add(view);
        mRoots.add(root);
        mParams.add(wparams);
        // do this last because it fires off messages to start doing things
        try {
            // 調(diào)用ViewRootImpl的setView()
            root.setView(view, wparams, panelParentView);
        } catch (RuntimeException e) {
            // BadTokenException or InvalidDisplayException, clean up.
            if (index >= 0) {
                removeViewLocked(index, true);
            }
            throw e;
        }
    }
}

ViewRootImpl的構(gòu)造方法中建立與SurfaceFlinger的連接,下面看ViewRootImpl的構(gòu)造方法

public ViewRootImpl(Context context, Display display) {
    mContext = context;
    // mWindowSession為IWindowSession.Stub.Proxy對(duì)象,單例模式
    mWindowSession = WindowManagerGlobal.getWindowSession();
    mDisplay = display;
    mBasePackageName = context.getBasePackageName();
    mThread = Thread.currentThread();
    mLocation = new WindowLeaked(null);
    mLocation.fillInStackTrace();
    mWidth = -1;
    mHeight = -1;
    mDirty = new Rect();
    mTempRect = new Rect();
    mVisRect = new Rect();
    mWinFrame = new Rect();
    // 創(chuàng)建W對(duì)象,Binder服務(wù)對(duì)象
    // 用于接收WindowManager發(fā)送的應(yīng)用窗口感興趣的事件
    mWindow = new W(this);
    mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
    mViewVisibility = View.GONE;
    mTransparentRegion = new Region();
    mPreviousTransparentRegion = new Region();
    mFirst = true; // true for the first time the view is added
    mAdded = false;
    // 創(chuàng)建View.AttachInfo記錄添加到窗口的View的信息
    mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this,
            context);
    mAccessibilityManager = AccessibilityManager.getInstance(context);
    mAccessibilityManager.addAccessibilityStateChangeListener(
            mAccessibilityInteractionConnectionManager, mHandler);
    mHighContrastTextManager = new HighContrastTextManager();
    mAccessibilityManager.addHighTextContrastStateChangeListener(
            mHighContrastTextManager, mHandler);
    mViewConfiguration = ViewConfiguration.get(context);
    mDensity = context.getResources().getDisplayMetrics().densityDpi;
    mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
    mFallbackEventHandler = new PhoneFallbackEventHandler(context);
    // 獲取Choreographer對(duì)象,在Choreographer構(gòu)造函數(shù)中建立與SurfaceFlinger的連接
    mChoreographer = Choreographer.getInstance();
    mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
    if (!sCompatibilityDone) {
        sAlwaysAssignFocus = mTargetSdkVersion < Build.VERSION_CODES.P;
        sCompatibilityDone = true;
    }
    loadSystemProperties();
}

下面看ChoreographergetInstance()的實(shí)現(xiàn)

// Choreographer為T(mén)hreadLocal對(duì)象,關(guān)聯(lián)的線程必須有l(wèi)ooper
public static Choreographer getInstance() {
    // 調(diào)用initialValue()創(chuàng)建Choreographer
    return sThreadInstance.get();
}

private static final ThreadLocal<Choreographer> sThreadInstance =
        new ThreadLocal<Choreographer>() {
    @Override
    protected Choreographer initialValue() {
        Looper looper = Looper.myLooper();
        if (looper == null) {
            throw new IllegalStateException("The current thread must have a looper!");
        }
        Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
        if (looper == Looper.getMainLooper()) {
            mMainInstance = choreographer;
        }
        return choreographer;
    }
};

private Choreographer(Looper looper, int vsyncSource) {
    mLooper = looper;
    mHandler = new FrameHandler(looper);
    // 創(chuàng)建FrameDisplayEventReceiver,用于接收SurfaceFlinger發(fā)給應(yīng)用的Vsync信號(hào)
    mDisplayEventReceiver = USE_VSYNC
            ? new FrameDisplayEventReceiver(looper, vsyncSource)
            : null;
    mLastFrameTimeNanos = Long.MIN_VALUE;
    mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());
    // 創(chuàng)建CallbackQueue
    mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
    for (int i = 0; i <= CALLBACK_LAST; i++) {
        mCallbackQueues[i] = new CallbackQueue();
    }
    // b/68769804: For low FPS experiments.
    setFPSDivisor(SystemProperties.getInt(ThreadedRenderer.DEBUG_FPS_DIVISOR, 1));
}

mCallbackQueues是一個(gè)CallbackQueue數(shù)組,包含四個(gè)鏈表

  • CALLBACK_INPUT
    • 輸入回調(diào),當(dāng)接收到Vsync信號(hào)時(shí)首先運(yùn)行,如處理Move事件
  • CALLBACK_ANIMATION
    • 動(dòng)畫(huà)回調(diào),在TRAVERSAL之前運(yùn)行
  • CALLBACK_TRAVERSAL
    • TRAVERSAL回調(diào),執(zhí)行Measure/Layout/Draw
  • CALLBACK_COMMIT
    • COMMIT回調(diào),處理幀繪制完成后的操作,如應(yīng)用整理內(nèi)存等

FrameDisplayEventReceiver繼承自DisplayEventReceiver,下面分析它構(gòu)造方法

public DisplayEventReceiver(Looper looper, int vsyncSource) {
    if (looper == null) {
        throw new IllegalArgumentException("looper must not be null");
    }
    // Looper關(guān)聯(lián)的MessageQueue
    mMessageQueue = looper.getQueue();
    // Native層的DisplayEventReceiver初始化
    mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
            vsyncSource);
    // CloseGuard用于當(dāng)DisplayEventReceiver被回收時(shí),釋放資源
    mCloseGuard.open("dispose");
}

static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
        jobject messageQueueObj, jint vsyncSource) {
    // 所在線程的MessageQueue
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == NULL) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }
    // 創(chuàng)建NativeDisplayEventReceiver,與SurfaceFlinger建立連接
    // 獲取顯示事件socket接收端
    sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env,
            receiverWeak, messageQueue, vsyncSource);
    // 監(jiān)聽(tīng)顯示事件socket接收端
    status_t status = receiver->initialize();
    if (status) {
        String8 message;
        message.appendFormat("Failed to initialize display event receiver.  status=%d", status);
        jniThrowRuntimeException(env, message.string());
        return 0;
    }

    receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object
    return reinterpret_cast<jlong>(receiver.get());
}

下面看NativeDisplayEventReceiver的構(gòu)造方法

NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env,
        jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource) :
        // 創(chuàng)建DisplayEventDispatcher
        DisplayEventDispatcher(messageQueue->getLooper(),
                static_cast<ISurfaceComposer::VsyncSource>(vsyncSource)),
        // Java層DisplayEventReceiver弱引用的JNI全局引用保存在mReceiverWeakGlobal中
        // 用于后續(xù)向Java層DisplayEventReceiver傳遞顯示事件(Vsync/Hotplug)
        mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
        mMessageQueue(messageQueue) {
    ALOGV("receiver %p ~ Initializing display event receiver.", this);
}

// 成員子對(duì)象mReceiver為DisplayEventReceiver對(duì)象
DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper,
        ISurfaceComposer::VsyncSource vsyncSource) :
        mLooper(looper), mReceiver(vsyncSource), mWaitingForVsync(false) {
    ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
}

DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource) {
    // sf是BpSurfaceComposer對(duì)象的強(qiáng)指針(對(duì)象)
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != NULL) {
        // mEventConnection為BpDisplayEventConnection的強(qiáng)指針
        // 為客戶端創(chuàng)建顯示事件連接,通過(guò)該連接可以請(qǐng)求SurfaceFlinger發(fā)送Vsync以及接收
        // SurfaceFlinger發(fā)送的顯示事件
        mEventConnection = sf->createDisplayEventConnection(vsyncSource);
        if (mEventConnection != NULL) {
            // 創(chuàng)建BitTube
            mDataChannel = std::make_unique<gui::BitTube>();
            // 通過(guò)Binder IPC獲取對(duì)應(yīng)的Connection的socket接收端
            mEventConnection->stealReceiveChannel(mDataChannel.get());
        }
    }
}

createDisplayEventConnection()是一個(gè)Binder IPC,它的實(shí)現(xiàn)在ISurfaceComposer中。

virtual sp<IDisplayEventConnection> createDisplayEventConnection(VsyncSourcevsyncSource)
{
    Parcel data, reply;
    sp<IDisplayEventConnection> result;
    // 接口描述字符串寫(xiě)入Parcel中
    int err = data.writeInterfaceToken(
            ISurfaceComposer::getInterfaceDescriptor());
    if (err != NO_ERROR) {
        return result;
    }
    // vsyncSource寫(xiě)入Parcel中
    data.writeInt32(static_cast<int32_t>(vsyncSource));
    // 請(qǐng)求SurfaceFlinger處理CREATE_DISPLAY_EVENT_CONNECTION
    err = remote()->transact(
            BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,
            data, &reply);
    if (err != NO_ERROR) {
        ALOGE("ISurfaceComposer::createDisplayEventConnection: error performing "
                "transaction: %s (%d)", strerror(-err), -err);
        return result;
    }
    // 在應(yīng)用端reply.readStrongBinder()返回BpBinder的強(qiáng)指針
    // interface_case是模板方法
    // result為BpDisplayEventConnection的強(qiáng)指針
    result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder());
    return result;
}

下面看SurfaceFlinger處理CREATE_DISPLAY_EVENT_CONNECTION請(qǐng)求。

status_t BnSurfaceComposer::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        ......
        case CREATE_DISPLAY_EVENT_CONNECTION: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            // 為客戶端創(chuàng)建連接
            sp<IDisplayEventConnection> connection(createDisplayEventConnection(
                    static_cast<ISurfaceComposer::VsyncSource>(data.readInt32())));
            // connection寫(xiě)入reply Parcel中
            reply->writeStrongBinder(IInterface::asBinder(connection));
            return NO_ERROR;
        }
        ......
    }
}

sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
        ISurfaceComposer::VsyncSource vsyncSource) {
    if (vsyncSource == eVsyncSourceSurfaceFlinger) {
        return mSFEventThread->createEventConnection();
    } else {
        // 調(diào)用EventThread的createEventConnection()
        return mEventThread->createEventConnection();
    }
}

sp<BnDisplayEventConnection> EventThread::createEventConnection() const {
    // 創(chuàng)建Connection
    return new Connection(const_cast<EventThread*>(this));
}

Connection是一個(gè)Binder服務(wù)類,繼承自BnDisplayEventConnection,它的作用

  • 處理客戶端應(yīng)用的Vsync請(qǐng)求
  • 向客戶端應(yīng)用發(fā)送顯示事件(Vsync/Hotplug)

下面看Connection的構(gòu)造方法

EventThread::Connection::Connection(EventThread* eventThread)
      // 創(chuàng)建BitTube
      : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}

BitTube::BitTube(size_t bufsize) {
    // 創(chuàng)建socket pair,用于發(fā)送顯示事件
    init(bufsize, bufsize);
}

void BitTube::init(size_t rcvbuf, size_t sndbuf) {
    int sockets[2];
    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
        size_t size = DEFAULT_SOCKET_BUFFER_SIZE;
        // 設(shè)置socket buffer
        setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
        setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
        // since we don't use the "return channel", we keep it small...
        setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
        setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
        fcntl(sockets[0], F_SETFL, O_NONBLOCK);
        fcntl(sockets[1], F_SETFL, O_NONBLOCK);
        // socket[0]用于接收端,最終通過(guò)Binder IPC返回給客戶端應(yīng)用
        mReceiveFd.reset(sockets[0]);
        // socket[1]用于發(fā)送端
        mSendFd.reset(sockets[1]);
    } else {
        mReceiveFd.reset();
        ALOGE("BitTube: pipe creation failed (%s)", strerror(errno));
    }
}

BitTube的作用主要有

  • 封裝用于顯示事件的socket通信
  • 跨進(jìn)程傳遞socket文件描述符

回到createEventConnection()方法中,由于返回Connection的強(qiáng)指針,在sp的構(gòu)造函數(shù)中會(huì)增加強(qiáng)引用計(jì)數(shù)從而調(diào)用ConnectiononFirstRef()方法。

void EventThread::Connection::onFirstRef() {
    // NOTE: mEventThread doesn't hold a strong reference on us
    // 向EventThread注冊(cè)連接
    mEventThread->registerDisplayEventConnection(this);
}

status_t EventThread::registerDisplayEventConnection(
        const sp<EventThread::Connection>& connection) {
    std::lock_guard<std::mutex> lock(mMutex);
    // Connection添加到mDisplayEventConnections中
    mDisplayEventConnections.add(connection);
    mCondition.notify_all();
    return NO_ERROR;
}

ConnectionEventThread采用觀察者模式,當(dāng)有顯示事件發(fā)生時(shí),EventThreadConnection傳遞事件。至此,createDisplayEventConnection()的實(shí)現(xiàn)就分析完了,下面看stealReceiveChannel()的實(shí)現(xiàn)

status_t stealReceiveChannel(gui::BitTube* outChannel) override {
    // callRemote是一個(gè)模板方法,用于實(shí)現(xiàn)同步Binder IPC
    return callRemote<decltype(
            &IDisplayEventConnection::stealReceiveChannel)>(Tag::STEAL_RECEIVE_CHANNEL,
                                                            outChannel);
}

下面看Connection處理STEAL_RECEIVE_CHANNEL請(qǐng)求

status_t BnDisplayEventConnection::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                              uint32_t flags) {
    if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
        return BBinder::onTransact(code, data, reply, flags);
    }
    auto tag = static_cast<Tag>(code);
    switch (tag) {
        case Tag::STEAL_RECEIVE_CHANNEL:
            // 調(diào)用stealReceiveChannel處理請(qǐng)求
            // 最終通過(guò)BitTube(outChannel)的writeToParcel將socket接收端文件描述符寫(xiě)入reply
            return callLocal(data, reply, &IDisplayEventConnection::stealReceiveChannel);
        ......
    }
}

status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {
    // 設(shè)置socket接收端文件描述符
    outChannel->setReceiveFd(mChannel.moveReceiveFd());
    return NO_ERROR;
}

最終,客戶端應(yīng)用通過(guò)BitTubereadFromParcel()獲取來(lái)自SurfaceFlinger的socket文件描述符。這樣客戶端就可以接收SurfaceFlinger發(fā)送的顯示事件了。回到nativeInit()中,繼續(xù)看監(jiān)聽(tīng)socket接收端文件描述符的過(guò)程。

status_t DisplayEventDispatcher::initialize() {
    status_t result = mReceiver.initCheck();
    if (result) {
        ALOGW("Failed to initialize display event receiver, status=%d", result);
        return result;
    }
    // Looper監(jiān)聽(tīng)socket文件描述符
    int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,
            this, NULL);
    if (rc < 0) {
        return UNKNOWN_ERROR;
    }
    return OK;
}

DisplayEventDispatcher繼承自LooperCallback,當(dāng)有顯示事件到來(lái)時(shí),Looper關(guān)聯(lián)的線程將調(diào)用DisplayEventDispatcherhandleEvent()處理事件。這樣Android應(yīng)用與SurfaceFlinger就建立了連接,可以接收SurfaceFlinger發(fā)送的顯示事件了。

為了后續(xù)分析,下面繼續(xù)分析ViewRootImplsetView()

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView {
    synchronized (this) {
        if (mView == null) {
            mView = view;
            mAttachInfo.mDisplayState = mDisplay.getState();
            mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
            mViewLayoutDirectionInitial = mView.getRawLayoutDirection();
            mFallbackEventHandler.setView(view);
            mWindowAttributes.copyFrom(attrs);
            if (mWindowAttributes.packageName == null) {
                mWindowAttributes.packageName = mBasePackageName;
            }
            attrs = mWindowAttributes;
            setTag();
            ......
            // If the application owns the surface, don't enable hardware acceleration
            // 如果應(yīng)用有自己的Surface,不使能硬件加速
            if (mSurfaceHolder == null) {
                // While this is supposed to enable only, it can effectively disable
                // the acceleration too.
                // 使能硬件加速,也可以禁止
                enableHardwareAcceleration(attrs);
                final boolean useMTRenderer = MT_RENDERER_AVAILABLE
                        && mAttachInfo.mThreadedRenderer != null;
                if (mUseMTRenderer != useMTRenderer) {
                    // Shouldn't be resizing, as it's done only in window setup,
                    // but end just in case.
                    endDragResizing();
                    mUseMTRenderer = useMTRenderer;
                }
            }
            ......
            // Schedule the first layout -before- adding to the window
            // manager, to make sure we do the relayout before receiving
            // any other events from the system.
            // 調(diào)度首次layout, 請(qǐng)求SurfaceFlinger發(fā)送Vsync
            requestLayout();
            ......
            try {
                mOrigWindowType = mWindowAttributes.type;
                mAttachInfo.mRecomputeGlobalAttributes = true;
                collectViewAttributes();
                // 窗口注冊(cè)到WindowManagerService
                res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                        getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
                        mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                        mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
            } catch (RemoteException e) {
                mAdded = false;
                mView = null;
                mAttachInfo.mRootView = null;
                mInputChannel = null;
                mFallbackEventHandler.setView(null);
                unscheduleTraversals();
                setAccessibilityFocus(null, null);
                throw new RuntimeException("Adding window failed", e);
            } finally {
                if (restore) {
                    attrs.restore();
                }
            }
            ......
        }
    }
}                                

下面重點(diǎn)分析上述方法中的以下三個(gè)過(guò)程

  • 使能硬件加速的過(guò)程
  • 調(diào)度首次layout的過(guò)程
  • 窗口注冊(cè)到WindowManagerService的過(guò)程

使能硬件加速的過(guò)程

下面從enableHardwareAcceleration()開(kāi)始分析。

private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
    mAttachInfo.mHardwareAccelerated = false;
    mAttachInfo.mHardwareAccelerationRequested = false;
    // Don't enable hardware acceleration when the application is in compatibility mode
    if (mTranslator != null) return;
    // Try to enable hardware acceleration if requested
    // 默認(rèn)hardwareAccelerated為true
    // 在低端設(shè)備上,Persistent進(jìn)程(包括system進(jìn)程)不應(yīng)該使用hardwareAccelerated,因?yàn)閔ardwareAccelerated消耗更多的資源,比如內(nèi)存
    final boolean hardwareAccelerated =
            (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
    if (hardwareAccelerated) {
        if (!ThreadedRenderer.isAvailable()) {
            return;
        }
        ......
        // 對(duì)于startingWindow,設(shè)置窗口的FLAG_HARDWARE_ACCELERATED及PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED使得繪制與應(yīng)用窗口繪制相似(并非真正的hardwareAccelerated)
        final boolean fakeHwAccelerated = (attrs.privateFlags &
                WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED) != 0;
        // 用于在system進(jìn)程中,某些UI繪制強(qiáng)制使用hardwareAccelerated
        final boolean forceHwAccelerated = (attrs.privateFlags &
                WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED) != 0;
        if (fakeHwAccelerated) {
            // This is exclusively for the preview windows the window manager
            // shows for launching applications, so they will look more like
            // the app being launched.
            mAttachInfo.mHardwareAccelerationRequested = true;
        } else if (!ThreadedRenderer.sRendererDisabled
                || (ThreadedRenderer.sSystemRendererDisabled && forceHwAccelerated)) {
            // 使能硬件加速
            if (mAttachInfo.mThreadedRenderer != null) {
                mAttachInfo.mThreadedRenderer.destroy();
            }
            final Rect insets = attrs.surfaceInsets;
            final boolean hasSurfaceInsets = insets.left != 0 || insets.right != 0
                    || insets.top != 0 || insets.bottom != 0;
            // 是否透明
            final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
            final boolean wideGamut =
                    mContext.getResources().getConfiguration().isScreenWideColorGamut()
                    && attrs.getColorMode() == ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT;
            // 創(chuàng)建ThreadedRenderer
            mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
                    attrs.getTitle().toString());
            mAttachInfo.mThreadedRenderer.setWideGamut(wideGamut);
            if (mAttachInfo.mThreadedRenderer != null) {
                mAttachInfo.mHardwareAccelerated =
                        mAttachInfo.mHardwareAccelerationRequested = true;
            }
        }
    }
}
  • ThreaderedRenderer用于將渲染工作委托給RenderThread

下面看ThreaderedRenderercreate()方法

public static ThreadedRenderer create(Context context, boolean translucent, Stringname) {
    ThreadedRenderer renderer = null;
    if (isAvailable()) {
        // 檢查是否支持Threaded rendering
        // 舊版本的模擬器可能不支持
        renderer = new ThreadedRenderer(context, translucent, name);
    }
    return renderer;
}

ThreadedRenderer(Context context, boolean translucent, String name) {
    final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
    mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
    mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
    mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
    mAmbientShadowAlpha =
            (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
    mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
    a.recycle();
    // 創(chuàng)建Native RootRenderNode對(duì)象,rootNodePtr為對(duì)象的地址
    long rootNodePtr = nCreateRootRenderNode();
    // 產(chǎn)生一個(gè)Java RenderNode關(guān)聯(lián)Native RenderNode
    mRootNode = RenderNode.adopt(rootNodePtr);
    mRootNode.setClipToBounds(false);
    mIsOpaque = !translucent;
    // 創(chuàng)建RenderProxy及RenderThread
    mNativeProxy = nCreateProxy(translucent, rootNodePtr);
    nSetName(mNativeProxy, name);
    // 1) 設(shè)置RenderThread的調(diào)度信息
    // 2) 請(qǐng)求系統(tǒng)GraphicsStatsService創(chuàng)建匿名共享內(nèi)存,用于存儲(chǔ)應(yīng)用渲染信息(dumpsys gfxinfo)
    ProcessInitializer.sInstance.init(context, mNativeProxy);
    // 加載渲染所需的系統(tǒng)屬性
    loadSystemProperties();
}
  • RenderNode
    • 存儲(chǔ)記錄的畫(huà)布命令,以及View/ViewGroup的顯示屬性
  • RenderProxy
    • 創(chuàng)建以及管理RenderThread中的CanvasContext
  • RenderThread
    • 真正的渲染線程
      下面首先看RootRenderNode的創(chuàng)建,然后分析RenderProxy及RenderThread。
static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) {
    // 創(chuàng)建RootRenderNode
    RootRenderNode* node = new RootRenderNode(env);
    node->incStrong(0);
    node->setName("RootRenderNode");
    return reinterpret_cast<jlong>(node);
}

explicit RootRenderNode(JNIEnv* env) : RenderNode() {
    // 獲取調(diào)用線程關(guān)聯(lián)的Looper
    mLooper = Looper::getForThread();
    LOG_ALWAYS_FATAL_IF(!mLooper.get(),
            "Must create RootRenderNode on a thread with a looper!");
    // 返回JavaVM
    env->GetJavaVM(&mVm);
}

這里只是簡(jiǎn)單的創(chuàng)建RootRenderNode,下面看RenderProxy及RenderThread的創(chuàng)建。

static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,
        jboolean translucent, jlong rootRenderNodePtr) {
    RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr);
    // 創(chuàng)建ContextFactoryImpl
    ContextFactoryImpl factory(rootRenderNode);
    // 創(chuàng)建RenderProxy
    return (jlong) new RenderProxy(translucent, rootRenderNode, &factory);
}

RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode,
                         IContextFactory* contextFactory)
        // 創(chuàng)建啟動(dòng)RenderThread線程
        : mRenderThread(RenderThread::getInstance()), mContext(nullptr) {
    // 匿名函數(shù)創(chuàng)建CanvasContext
    mContext = mRenderThread.queue().runSync([&]() -> CanvasContext* {
        return CanvasContext::create(mRenderThread, translucent, rootRenderNode, contextFactory);
    });
    設(shè)置DrawFrameTask關(guān)聯(lián)的RenderThread、CanvasContext、RootRenderNode
    mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode);
}

RenderThread& RenderThread::getInstance() {
    // This is a pointer because otherwise __cxa_finalize
    // will try to delete it like a Good Citizen but that causes us to crash
    // because we don't want to delete the RenderThread normally.
    static RenderThread* sInstance = new RenderThread();
    gHasRenderThreadInstance = true;
    return *sInstance;
}

RenderThread::RenderThread()
        : ThreadBase()
        , mVsyncSource(nullptr)
        , mVsyncRequested(false)
        , mFrameCallbackTaskPending(false)
        , mRenderState(nullptr)
        , mEglManager(nullptr)
        , mVkManager(nullptr) {
    Properties::load();
    // 啟動(dòng)線程,最終執(zhí)行RenderThread的threadLoop方法
    start("RenderThread");
}

bool RenderThread::threadLoop() {
    // 設(shè)置RenderThread的優(yōu)先級(jí)
    setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY);
    if (gOnStartHook) {
        gOnStartHook();
    }
    // 與SurfaceFlinger建立連接
    // 設(shè)置EglManager、RenderState、VulkanManager等
    initThreadLocals();

    while (true) {
        // 等待工作
        waitForWork();
        // 處理工作項(xiàng)
        processQueue();

        if (mPendingRegistrationFrameCallbacks.size() && !mFrameCallbackTaskPending) {
            drainDisplayEventQueue();
            mFrameCallbacks.insert(mPendingRegistrationFrameCallbacks.begin(),
                                   mPendingRegistrationFrameCallbacks.end());
            mPendingRegistrationFrameCallbacks.clear();
            requestVsync();
        }

        if (!mFrameCallbackTaskPending && !mVsyncRequested && mFrameCallbacks.size()) {
            // TODO: Clean this up. This is working around an issue where a combination
            // of bad timing and slow drawing can result in dropping a stale vsync
            // on the floor (correct!) but fails to schedule to listen for the
            // next vsync (oops), so none of the callbacks are run.
            requestVsync();
        }
    }

    return false;
}

RenderThread啟動(dòng)后,RenderProxy向RenderThread發(fā)送創(chuàng)建CanvasContext的同步請(qǐng)求。下面看CanvasContext的創(chuàng)建。

CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent,
                                     RenderNode* rootRenderNode, IContextFactory* contextFactory) {
    // 獲取RenderPipeline類型,默認(rèn)是SkiaGL
    auto renderType = Properties::getRenderPipelineType();

    switch (renderType) {
        case RenderPipelineType::OpenGL:
            return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
                                     std::make_unique<OpenGLPipeline>(thread));
        case RenderPipelineType::SkiaGL:
            // 根據(jù)renderType創(chuàng)建CanvasContext
            return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
                                     std::make_unique<skiapipeline::SkiaOpenGLPipeline>(thread));
        case RenderPipelineType::SkiaVulkan:
            return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
                                     std::make_unique<skiapipeline::SkiaVulkanPipeline>(thread));
        default:
            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
            break;
    }
    return nullptr;
}

調(diào)度首次layout的過(guò)程

下面從requestLayout()開(kāi)始分析。

public void requestLayout() {
    if (!mHandlingLayoutInLayoutRequest) {
        checkThread();
        mLayoutRequested = true;
        scheduleTraversals();
    }
}

void scheduleTraversals() {
    if (!mTraversalScheduled) {
        mTraversalScheduled = true;
        // 向Looper關(guān)聯(lián)的消息隊(duì)列中投遞SyncBarrier
        // 下一次執(zhí)行performTraversal時(shí)移除SyncBarrier
        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
        // 添加CALLBACK_TRAVERSAL回調(diào),當(dāng)下一幀(Vsync)到來(lái)時(shí)執(zhí)行繪制
        mChoreographer.postCallback(
                Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        if (!mUnbufferedInputDispatch) {
            scheduleConsumeBatchedInput();
        }
        // 通知ThreadedRenderer下一幀很快到來(lái)
        notifyRendererOfFramePending();
        pokeDrawLockIfNeeded();
    }
}

關(guān)于synchronization barrier(target為null的特殊消息), 一般的,消息隊(duì)列中的消息為同步消息,按照時(shí)間先后進(jìn)行處理。當(dāng)synchronization barrier進(jìn)入消息隊(duì)列中,隊(duì)列中的同步消息被掛起(異步消息可以處理),直到synchronization barrier從消息隊(duì)列中移除。盡管postAtFrontOfQueue()可以使同步消息不被掛起,請(qǐng)不要濫用。

下面看ChoreographerpostCallback()的實(shí)現(xiàn)。

public void postCallback(int callbackType, Runnable action, Object token) {
    postCallbackDelayed(callbackType, action, token, 0);
}

public void postCallbackDelayed(int callbackType,
        Runnable action, Object token, long delayMillis) {
    ......
    postCallbackDelayedInternal(callbackType, action, token, delayMillis);
}

private void postCallbackDelayedInternal(int callbackType,
        Object action, Object token, long delayMillis) {
    ......
    synchronized (mLock) {
        final long now = SystemClock.uptimeMillis();
        final long dueTime = now + delayMillis;
        // 添加到CALLBACK_TRAVERSAL類型的CallbackQueue中
        mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
        if (dueTime <= now) {
            // 請(qǐng)求Vsync信號(hào)
            scheduleFrameLocked(now);
        } else {
            ......
        }
    }
}

下面看scheduleFrameLocked()的實(shí)現(xiàn)

private void scheduleFrameLocked(long now) {
    if (!mFrameScheduled) {
        mFrameScheduled = true;
        if (USE_VSYNC) {
            if (DEBUG_FRAMES) {
                Log.d(TAG, "Scheduling next frame on vsync.");
            }
            // If running on the Looper thread, then schedule the vsync immediately,
            // otherwise post a message to schedule the vsync from the UI thread
            // as soon as possible.
            if (isRunningOnLooperThreadLocked()) {
                // 立即請(qǐng)求Vsync
                scheduleVsyncLocked();
            } else {
                Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
                msg.setAsynchronous(true);
                mHandler.sendMessageAtFrontOfQueue(msg);
            }
        } else {
            ......
        }
    }
}

private void scheduleVsyncLocked() {
    // 調(diào)用FrameDisplayEventReceiver的scheduleVsync()
    mDisplayEventReceiver.scheduleVsync();
}

public void scheduleVsync() {
    if (mReceiverPtr == 0) {
        Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event "
                + "receiver has already been disposed.");
    } else {
        // 當(dāng)下一幀到來(lái)時(shí)請(qǐng)求SurfaceFlinger發(fā)送Vsync
        nativeScheduleVsync(mReceiverPtr);
    }
}

static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
    sp<NativeDisplayEventReceiver> receiver =
            reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
    // 調(diào)用NativeDisplayEventReceiver的scheduleVsync()
    status_t status = receiver->scheduleVsync();
    ......
}

NativeDisplayEventReceiver繼承自DisplayEventDispatcher,下面scheduleVsync()的實(shí)現(xiàn)

status_t DisplayEventDispatcher::scheduleVsync() {
    if (!mWaitingForVsync) {
        ALOGV("dispatcher %p ~ Scheduling vsync.", this);

        // Drain all pending events.
        nsecs_t vsyncTimestamp;
        int32_t vsyncDisplayId;
        uint32_t vsyncCount;
        // 如果有待處理的事件(Vsync/Hotplug),丟棄
        if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
            ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "",
                    this, ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));
        }
        // 調(diào)用DisplayEventReceiver的requestNextVsync(),請(qǐng)求SurfaceFlinger發(fā)送Vsync
        status_t status = mReceiver.requestNextVsync();
        if (status) {
            ALOGW("Failed to request next vsync, status=%d", status);
            return status;
        }

        mWaitingForVsync = true;
    }
    return OK;
}

status_t DisplayEventReceiver::requestNextVsync() {
    if (mEventConnection != NULL) {
        // mEventConnection是BpDisplayEventConnection的強(qiáng)指針
        mEventConnection->requestNextVsync();
        return NO_ERROR;
    }
    return NO_INIT;
}

requestNextVsync()是一個(gè)異步Binder IPC,它的實(shí)現(xiàn)在IDisplayEventConnection中,下面直接看Binder服務(wù)端Connection處理REQUEST_NEXT_VSYNC請(qǐng)求。

void EventThread::Connection::requestNextVsync() {
    // 調(diào)用EventThread的requestNextVsync處理客戶端Vsync請(qǐng)求
    mEventThread->requestNextVsync(this);
}

void EventThread::requestNextVsync(const sp<EventThread::Connection>& connection) {
    std::lock_guard<std::mutex> lock(mMutex);

    ......
    // 修改連接狀態(tài)
    if (connection->count < 0) {
        connection->count = 0;
        mCondition.notify_all();
    }
}

客戶端請(qǐng)求Vsync的過(guò)程相對(duì)簡(jiǎn)單,主要是修改Connection的狀態(tài)。當(dāng)EventThread收到Vsync時(shí),根據(jù)Connection的狀態(tài)決定是否向Connection發(fā)送Vsync。

使用dumpsys SurfaceFlinger命令可以查看所有Connection的狀態(tài)
****chn:/ $ dumpsys SurfaceFlinger
......
VSYNC state: enabled
  soft-vsync: disabled
  numListeners=43,
  events-delivered: 11406
    0x7b3a052300: count=-1
    0x7b3a052360: count=-1
    0x7b3a0523c0: count=-1
    0x7b3a052420: count=-1
    0x7b3a0524e0: count=-1
    0x7b3a052960: count=-1
    0x7b3a0529c0: count=-1
    ......
    0x7b3abfe200: count=1
    ......

其中,numListeners表示連接數(shù)量,count的值表示狀態(tài)
  • count >= 1
    • 連續(xù)的Vsync請(qǐng)求
  • count = 0
    • 單次Vsync請(qǐng)求(還沒(méi)有收到Vsync)
  • count = -1
    • 單次Vsync請(qǐng)求(已經(jīng)收到Vsync)或者不請(qǐng)求Vsync

窗口注冊(cè)到WindowManagerService的過(guò)程

下面從addToDisplay()開(kāi)始分析,addToDisplay()是一個(gè)Binder IPC,對(duì)應(yīng)的服務(wù)端的實(shí)現(xiàn)在Session中。

public int 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) {
    // 調(diào)用WindowManagerService的addWindow
    return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,
            outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel);
}

public int addWindow(Session session, IWindow client, int seq,
        LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
        Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
        DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
    // client為IWindow.Stub.Proxy對(duì)象
    ......
    boolean reportNewConfig = false;
    WindowState parentWindow = null;
    long origId;
    final int callingUid = Binder.getCallingUid();
    final int type = attrs.type; 
    synchronized(mWindowMap) {
        if (!mDisplayReady) {
            throw new IllegalStateException("Display has not been initialialized");
        }
        // DisplayContent用于記錄特定屏幕的WindowStates以及相關(guān)的內(nèi)容
        final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
        ......
        // 檢查應(yīng)用是否有權(quán)限向特定屏幕添加窗口
        if (!displayContent.hasAccess(session.mUid)
                && !mDisplayManagerInternal.isUidPresentOnDisplay(session.mUid, displayId)) {
            Slog.w(TAG_WM, "Attempted to add window to a display for which the application "
                    + "does not have access: " + displayId + ".  Aborting.");
            return WindowManagerGlobal.ADD_INVALID_DISPLAY;
        }
        ......
        // 檢查窗口是否已經(jīng)添加
        // mWindowMap為IWindow IBinder(BinderProxy)到WindowState的映射
        if (mWindowMap.containsKey(client.asBinder())) {
            Slog.w(TAG_WM, "Window " + client + " is already added");
            return WindowManagerGlobal.ADD_DUPLICATE_ADD;
        }
        ......
        AppWindowToken atoken = null;
        final boolean hasParent = parentWindow != null;
        // Use existing parent window token for child windows since they go in the same token
        // as there parent window so we can apply the same policy on them.
        // 對(duì)于Activity窗口,根據(jù)token(IApplicationToken.Stub)查找對(duì)應(yīng)的AppWindowToken
        // AppWindowToken是在之前Activity啟動(dòng)時(shí)創(chuàng)建
        WindowToken token = displayContent.getWindowToken(
                hasParent ? parentWindow.mAttrs.token : attrs.token);
        // If this is a child window, we want to apply the same type checking rules as the
        // parent window type.
        final int rootType = hasParent ? parentWindow.mAttrs.type : type;
        boolean addToastWindowRequiresToken = false;
        ......
        // 創(chuàng)建WindowState用于描述一個(gè)窗口
        final WindowState win = new WindowState(this, session, client, token, parentWindow,
                appOp[0], seq, attrs, viewVisibility, session.mUid,
                session.mCanAddInternalSystemWindow);
        ......
        // 根據(jù)窗口類型調(diào)整布局參數(shù)
        mPolicy.adjustWindowParamsLw(win, win.mAttrs, hasStatusBarServicePermission);
        win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
        // 窗口添加到系統(tǒng)前的檢查
        res = mPolicy.prepareAddWindowLw(win, attrs);
        ......
        // 創(chuàng)建SurfaceSession,添加Session到WindowManagerService
        win.attach();
        // WindowState添加到mWindowMap
        mWindowMap.put(client.asBinder(), win);
        win.initAppOpsState(); 
        ......
        // 窗口WindowState添加到系統(tǒng)
        win.mToken.addWindow(win); 
        ......
        // 這里WindowState的Parent為AppWindowToken
        win.getParent().assignChildLayers();
    }                               
}

下面重點(diǎn)分析WindowStateattach()方法

void attach() {
    if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
    // 調(diào)用Session的windowAddedLocked
    mSession.windowAddedLocked(mAttrs.packageName);
}

void windowAddedLocked(String packageName) {
    mPackageName = packageName;
    mRelayoutTag = "relayoutWindow: " + mPackageName;
    if (mSurfaceSession == null) {
        if (WindowManagerService.localLOGV) Slog.v(
            TAG_WM, "First window added to " + this + ", creating SurfaceSession");
        // SurfaceSession代表一個(gè)到SurfaceFlinger的連接
        // 可以有一個(gè)或多個(gè)參與合成的Surface
        mSurfaceSession = new SurfaceSession();
        if (SHOW_TRANSACTIONS) Slog.i(
                TAG_WM, "  NEW SURFACE SESSION " + mSurfaceSession);
        // Session添加到WindowManagerService的mSessions中
        mService.mSessions.add(this);
        if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
            mService.dispatchNewAnimatorScaleLocked(this);
        }
    }
    mNumWindow++;
}

下面看SurfaceSession的構(gòu)造方法。

public SurfaceSession() {
    mNativeClient = nativeCreate();
}

static jlong nativeCreate(JNIEnv* env, jclass clazz) {
    // 創(chuàng)建SurfaceComposerClient
    SurfaceComposerClient* client = new SurfaceComposerClient();
    // SurfaceComposerClient繼承自RefBase,增加強(qiáng)引用計(jì)數(shù),會(huì)調(diào)用onFirstRef
    client->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(client);
}

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != 0 && mStatus == NO_INIT) {
        // 這里rootProducer為nullptr
        auto rootProducer = mParent.promote();
        sp<ISurfaceComposerClient> conn;
        // 請(qǐng)求SurfaceFlinger為客戶端創(chuàng)建連接
        // conn為BpSurfaceComposerClient對(duì)象的智能指針
        conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
                sf->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

createConnection()是一個(gè)Binder IPC,下面直接看SurfaceFlinger處理CREATE_CONNECTION請(qǐng)求。

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
    return initClient(new Client(this));
}

Client為參與合成的客戶端在SurfaceFlinger側(cè)的代表,是一個(gè)Binder服務(wù)對(duì)象,通過(guò)Binder IPC傳遞后,在客戶端得到BpSurfaceComposerClient對(duì)象。

小結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。