基于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),下面從ActivityThread
的handleResumeActivity()
開(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;
}
......
}
下面看WindowManagerImpl
的addView()
的實(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();
}
下面看Choreographer
的getInstance()
的實(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)用Connection
的onFirstRef()
方法。
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;
}
Connection
與EventThread
采用觀察者模式,當(dāng)有顯示事件發(fā)生時(shí),EventThread
向Connection
傳遞事件。至此,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ò)BitTube
的readFromParcel()
獲取來(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)用DisplayEventDispatcher
的handleEvent()
處理事件。這樣Android應(yīng)用與SurfaceFlinger就建立了連接,可以接收SurfaceFlinger發(fā)送的顯示事件了。
為了后續(xù)分析,下面繼續(xù)分析ViewRootImpl
的setView()
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
下面看ThreaderedRenderer
的create()
方法
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)不要濫用。
下面看Choreographer
的postCallback()
的實(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)分析WindowState
的attach()
方法
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ì)象。