- 浏览: 23888 次
- 性别:
- 来自: 北京
最新评论
page11
我们来看一下SurfaceFlinger的onFirstRef函数的定义:
1void EventThread::onFirstRef() {
2 run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
3}
我靠, 又调用run函数, 这会导致又启动了一个线程.
同样的, 这也会导致readyToRun和threadLoop函数的.
EventThread的readyToRun函数是从Thread类继承而来的, 是个空函数.
而EventThread的threadLoop函数的定义如下:
1 bool EventThread::threadLoop() {
2 DisplayEventReceiver::Event event;
3 Vector< sp<EventThread::Connection> > signalConnections;
4 signalConnections = waitForEvent(&event);
5
6 // dispatch events to listeners...
7 const size_t count = signalConnections.size();
8 for (size_t i=0 ; i<count ; i++) {
9 const sp<Connection>& conn(signalConnections[i]);
10 // now see if we still need to report this event
11 status_t err = conn->postEvent(event);
12 if (err == -EAGAIN || err == -EWOULDBLOCK) {
13 // The destination doesn't accept events anymore, it's probably
14 // full. For now, we just drop the events on the floor.
15 // FIXME: Note that some events cannot be dropped and would have
16 // to be re-sent later.
17 // Right-now we don't have the ability to do this.
18 ALOGW("EventThread: dropping event (%08x) for connection %p",
19 event.header.type, conn.get());
20 } else if (err < 0) {
21 // handle any other error on the pipe as fatal. the only
22 // reasonable thing to do is to clean-up this connection.
23 // The most common error we'll get here is -EPIPE.
24 removeDisplayEventConnection(signalConnections[i]);
25 }
26 }
27 return true;
28 }
EventThread的threadLoop函数的主要逻辑就是不停地等待事件, 然后交给Connection去处理.
page12
我们来分析一下MessageQueue的setEventThread函数的逻辑实现, setEventThread函数的定义如下所示:
1 void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
2 {
3 mEventThread = eventThread;
4 mEvents = eventThread->createEventConnection();
5 mEventTube = mEvents->getDataChannel();
6 mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT, MessageQueue::cb_eventReceiver, this);
7 }
第4行(MessageQueue->setEventThread)会调用EventThread的createEventConnection函数, 关于createEventConnection函数的详细分析可以参考page13文件.
第5行(MessageQueue->setEventThread)会调用Connection的getDataChannel来得到一个BitTube对象并初始化, getDataChannel函数的定义如下所示:
sp<BitTube> EventThread::Connection::getDataChannel() const {
return mChannel;
}
第6行(MessageQueue->setEventThread)会首先调用BitTube的getFd函数来得到一个文件操作符, 并加入到MessageQueue的Looper里.
我们先看一下BitTube的getFd函数的定义, 如下所示:
int BitTube::getFd() const
{
return mReceiveFd;
}
BitTube的getFd函数会返回用于接受的文件操作符, 这样当有数据写入该文件操作符的时候就会唤醒这个Looper处理该消息, 也就是说EventThread线程收到事件会交给SurfaceFlinger的Main线程取处理了, 这样就把EventThread线程和Main线程绑定到一起了.
EventThread发过来的消息的处理函数是调用的MessageQueue的cb_eventReceiver函数, 关于cb_eventReceiver函数的详细分析可以参考page14文件.
page13
在这里, 我们看一下EventThread的createEventConnection函数的具体实现, createEventConnection函数的定义如下:
sp<EventThread::Connection> EventThread::createEventConnection() const {
return new Connection(const_cast<EventThread*>(this));
}
createEventConnection函数只是返回了一个Connection对象.
Connection类的构造函数的定义如下:
EventThread::Connection::Connection(
const sp<EventThread>& eventThread)
: count(-1), mEventThread(eventThread), mChannel(new BitTube())
{
}
可以看到, Connection的mChannel会用一个BitTube来初始化, BitTube的类的声明如下:
class BitTube : public RefBase
BitTube类的构造函数的定义如下:
1 BitTube::BitTube()
2 : mSendFd(-1), mReceiveFd(-1)
3 {
4 int sockets[2];
5 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
6 int size = SOCKET_BUFFER_SIZE;
7 setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
8 setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
9 setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
10 setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
11 fcntl(sockets[0], F_SETFL, O_NONBLOCK);
12 fcntl(sockets[1], F_SETFL, O_NONBLOCK);
13 mReceiveFd = sockets[0];
14 mSendFd = sockets[1];
15 } else {
16 mReceiveFd = -errno;
17 ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
18 }
19 }
可以看出, BitTube构造函数只是创建了两个文件操作符, 一个用户读, 一个用于写.
page14
在这篇文章里, 我们分析一下MessageQueue的cb_eventReceiver函数的实现:
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
return queue->eventReceiver(fd, events);
}
cb_eventReceiver函数又会调用eventReceiver函数, MessageQueue的eventReceiver函数的定义如下:
1 int MessageQueue::eventReceiver(int fd, int events) {
2 ssize_t n;
3 DisplayEventReceiver::Event buffer[8];
4 while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer,) > 0) {
5 for (int i=0 ; i<n ; i++) {
6 if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
7 #if INVALIDATE_ON_VSYNC
8 mHandler->dispatchInvalidate();
9 #else
10 mHandler->dispatchRefresh();
11 #endif
12 break;
13 }
14 }
15 }
16 return 1;
17 }
第4行(MessageQueue->eventReceiver)会在mEventTube上调用DisplayEventReceiver的getEvents函数, 关于DisplayEventReceiver的getEvents函数的详细分析可以参考page15文件.
page15
在这篇文章里, 我们分析一下DisplayEventReceiver的getEvents函数的实现:
1ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events, size_t count) {
2 return DisplayEventReceiver::getEvents(mDataChannel, events, count);
3}
两个参数的getEvents又会调用三个参数的重载版本, 该函数的定义如下:
1ssize_t DisplayEventReceiver::getEvents(const sp<BitTube>& dataChannel, Event* events, size_t count)
2{
3 return BitTube::recvObjects(dataChannel, events, count);
4}
getEvents函数最终会调用BitTube的recvObjects函数, 而传入的文件操作符正是成员变量mEventTube.
BitTube的recvObjects函数的定义如下:
1 ssize_t BitTube::recvObjects(const sp<BitTube>& tube, void* events, size_t count, size_t objSize)
2 {
3 ssize_t numObjects = 0;
4 for (size_t i=0 ; i<count ; i++) {
5 char* vaddr = reinterpret_cast<char*>(events) + objSize * i;
6 ssize_t size = tube->read(vaddr, objSize);
7 if (size < 0) {
8 // error occurred
9 return size;
10 } else if (size == 0) {
11 // no more messages
12 break;
13 }
14 numObjects++;
15 }
16 return numObjects;
17 }
第6行(BitTube->recvObjects)会在该BitTube上调用read函数来接受数据, BitTube的read函数的定义如下所示:
1 ssize_t BitTube::read(void* vaddr, size_t size)
2 {
3 ssize_t err, len;
4 do {
5 len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT);
6 err = len < 0 ? errno : 0;
7 } while (err == EINTR);
8 if (err == EAGAIN || err == EWOULDBLOCK) {
9 // EAGAIN means that we have non-blocking I/O but there was
10 // no data to be read. Nothing the client should care about.
11 return 0;
12 }
13 return err == 0 ? len : -err;
14 }
第5行(BitTube->read)会在mReceiveFd文件操作符上读取size大小的数据, 并保存到地址vaddr里去.
我们来看一下SurfaceFlinger的onFirstRef函数的定义:
1void EventThread::onFirstRef() {
2 run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
3}
我靠, 又调用run函数, 这会导致又启动了一个线程.
同样的, 这也会导致readyToRun和threadLoop函数的.
EventThread的readyToRun函数是从Thread类继承而来的, 是个空函数.
而EventThread的threadLoop函数的定义如下:
1 bool EventThread::threadLoop() {
2 DisplayEventReceiver::Event event;
3 Vector< sp<EventThread::Connection> > signalConnections;
4 signalConnections = waitForEvent(&event);
5
6 // dispatch events to listeners...
7 const size_t count = signalConnections.size();
8 for (size_t i=0 ; i<count ; i++) {
9 const sp<Connection>& conn(signalConnections[i]);
10 // now see if we still need to report this event
11 status_t err = conn->postEvent(event);
12 if (err == -EAGAIN || err == -EWOULDBLOCK) {
13 // The destination doesn't accept events anymore, it's probably
14 // full. For now, we just drop the events on the floor.
15 // FIXME: Note that some events cannot be dropped and would have
16 // to be re-sent later.
17 // Right-now we don't have the ability to do this.
18 ALOGW("EventThread: dropping event (%08x) for connection %p",
19 event.header.type, conn.get());
20 } else if (err < 0) {
21 // handle any other error on the pipe as fatal. the only
22 // reasonable thing to do is to clean-up this connection.
23 // The most common error we'll get here is -EPIPE.
24 removeDisplayEventConnection(signalConnections[i]);
25 }
26 }
27 return true;
28 }
EventThread的threadLoop函数的主要逻辑就是不停地等待事件, 然后交给Connection去处理.
page12
我们来分析一下MessageQueue的setEventThread函数的逻辑实现, setEventThread函数的定义如下所示:
1 void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
2 {
3 mEventThread = eventThread;
4 mEvents = eventThread->createEventConnection();
5 mEventTube = mEvents->getDataChannel();
6 mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT, MessageQueue::cb_eventReceiver, this);
7 }
第4行(MessageQueue->setEventThread)会调用EventThread的createEventConnection函数, 关于createEventConnection函数的详细分析可以参考page13文件.
第5行(MessageQueue->setEventThread)会调用Connection的getDataChannel来得到一个BitTube对象并初始化, getDataChannel函数的定义如下所示:
sp<BitTube> EventThread::Connection::getDataChannel() const {
return mChannel;
}
第6行(MessageQueue->setEventThread)会首先调用BitTube的getFd函数来得到一个文件操作符, 并加入到MessageQueue的Looper里.
我们先看一下BitTube的getFd函数的定义, 如下所示:
int BitTube::getFd() const
{
return mReceiveFd;
}
BitTube的getFd函数会返回用于接受的文件操作符, 这样当有数据写入该文件操作符的时候就会唤醒这个Looper处理该消息, 也就是说EventThread线程收到事件会交给SurfaceFlinger的Main线程取处理了, 这样就把EventThread线程和Main线程绑定到一起了.
EventThread发过来的消息的处理函数是调用的MessageQueue的cb_eventReceiver函数, 关于cb_eventReceiver函数的详细分析可以参考page14文件.
page13
在这里, 我们看一下EventThread的createEventConnection函数的具体实现, createEventConnection函数的定义如下:
sp<EventThread::Connection> EventThread::createEventConnection() const {
return new Connection(const_cast<EventThread*>(this));
}
createEventConnection函数只是返回了一个Connection对象.
Connection类的构造函数的定义如下:
EventThread::Connection::Connection(
const sp<EventThread>& eventThread)
: count(-1), mEventThread(eventThread), mChannel(new BitTube())
{
}
可以看到, Connection的mChannel会用一个BitTube来初始化, BitTube的类的声明如下:
class BitTube : public RefBase
BitTube类的构造函数的定义如下:
1 BitTube::BitTube()
2 : mSendFd(-1), mReceiveFd(-1)
3 {
4 int sockets[2];
5 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
6 int size = SOCKET_BUFFER_SIZE;
7 setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
8 setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
9 setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
10 setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
11 fcntl(sockets[0], F_SETFL, O_NONBLOCK);
12 fcntl(sockets[1], F_SETFL, O_NONBLOCK);
13 mReceiveFd = sockets[0];
14 mSendFd = sockets[1];
15 } else {
16 mReceiveFd = -errno;
17 ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
18 }
19 }
可以看出, BitTube构造函数只是创建了两个文件操作符, 一个用户读, 一个用于写.
page14
在这篇文章里, 我们分析一下MessageQueue的cb_eventReceiver函数的实现:
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
return queue->eventReceiver(fd, events);
}
cb_eventReceiver函数又会调用eventReceiver函数, MessageQueue的eventReceiver函数的定义如下:
1 int MessageQueue::eventReceiver(int fd, int events) {
2 ssize_t n;
3 DisplayEventReceiver::Event buffer[8];
4 while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer,) > 0) {
5 for (int i=0 ; i<n ; i++) {
6 if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
7 #if INVALIDATE_ON_VSYNC
8 mHandler->dispatchInvalidate();
9 #else
10 mHandler->dispatchRefresh();
11 #endif
12 break;
13 }
14 }
15 }
16 return 1;
17 }
第4行(MessageQueue->eventReceiver)会在mEventTube上调用DisplayEventReceiver的getEvents函数, 关于DisplayEventReceiver的getEvents函数的详细分析可以参考page15文件.
page15
在这篇文章里, 我们分析一下DisplayEventReceiver的getEvents函数的实现:
1ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events, size_t count) {
2 return DisplayEventReceiver::getEvents(mDataChannel, events, count);
3}
两个参数的getEvents又会调用三个参数的重载版本, 该函数的定义如下:
1ssize_t DisplayEventReceiver::getEvents(const sp<BitTube>& dataChannel, Event* events, size_t count)
2{
3 return BitTube::recvObjects(dataChannel, events, count);
4}
getEvents函数最终会调用BitTube的recvObjects函数, 而传入的文件操作符正是成员变量mEventTube.
BitTube的recvObjects函数的定义如下:
1 ssize_t BitTube::recvObjects(const sp<BitTube>& tube, void* events, size_t count, size_t objSize)
2 {
3 ssize_t numObjects = 0;
4 for (size_t i=0 ; i<count ; i++) {
5 char* vaddr = reinterpret_cast<char*>(events) + objSize * i;
6 ssize_t size = tube->read(vaddr, objSize);
7 if (size < 0) {
8 // error occurred
9 return size;
10 } else if (size == 0) {
11 // no more messages
12 break;
13 }
14 numObjects++;
15 }
16 return numObjects;
17 }
第6行(BitTube->recvObjects)会在该BitTube上调用read函数来接受数据, BitTube的read函数的定义如下所示:
1 ssize_t BitTube::read(void* vaddr, size_t size)
2 {
3 ssize_t err, len;
4 do {
5 len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT);
6 err = len < 0 ? errno : 0;
7 } while (err == EINTR);
8 if (err == EAGAIN || err == EWOULDBLOCK) {
9 // EAGAIN means that we have non-blocking I/O but there was
10 // no data to be read. Nothing the client should care about.
11 return 0;
12 }
13 return err == 0 ? len : -err;
14 }
第5行(BitTube->read)会在mReceiveFd文件操作符上读取size大小的数据, 并保存到地址vaddr里去.
发表评论
-
Activity与WindowManagerService连接的过程(三)
2018-04-16 16:27 622page11 WindowManagerService ... -
Activity与WindowManagerService连接的过程(二)
2018-04-16 16:36 770page6 WindowManagerGlobal的getW ... -
Activity与WindowManagerService连接的过程(一)
2018-04-16 16:21 987page1 Activity组件在 ... -
Activity的ViewRoot的创建过程(三)
2017-11-06 14:25 742page7 在这篇文章里, 我们分析一下W类的构造过程. W ... -
Activity的ViewRoot的创建过程(二)
2017-11-06 14:29 941page4 我们看一下ViewRootImpl对象的创 ... -
Activity的ViewRoot的创建过程(一)
2017-11-06 14:27 1079page1 当一个Activity第一次激活的时候会为该Ac ... -
Activity的Window和WindowManager的创建过程(三)
2017-07-05 11:49 1334page9 在这里我们分析一下DisplayManager的 ... -
Activity的Window和WindowManager的创建过程(二)
2017-07-05 11:31 548page5 在这篇文章中, 我们分析一下ContextImp ... -
Activity的Window和WindowManager的创建过程(一)
2017-07-05 11:27 607page1 我们开始分析一下Activity的Window和 ... -
Acitivy创建Context的过程(二)
2017-06-21 14:11 514page4 在这里我们分析一下ContextImpl的ini ... -
Acitivy创建Context的过程(一)
2017-06-21 14:15 638page1 从本篇文章开始,我们分析一下Activity创建 ... -
应用程序进程与SurfaceFlinger的连接过程
2017-06-21 11:49 1062我们从SurfaceComposerClient对象的创建开始 ... -
Android源码之SurfaceFlinger的启动(二)
2017-04-18 15:15 882page6 我们看一下Thread的run函数的实现: ... -
Android源码之SurfaceFlinger的启动(一)
2017-04-17 10:07 1000page1 在Android系统中, 显示系统在底层是通过S ... -
Android源码之Zygote
2015-12-15 11:45 519当ActivityManagerService启动一个应用程序 ... -
Android源码之Binder(五)
2015-12-04 09:19 1515Service组件在启动时,需要将自己注册到Service M ... -
Android源码之Binder(四)
2015-12-04 09:18 1951case BINDER_SET_MAX_THREADS: ... -
Android源码之Binder(三)
2015-12-04 09:17 910{ int ret; struct binder_pr ... -
Android源码之Binder(二)
2015-12-04 09:15 550分析完Binder驱动程序的打开和内存分配的过程之后,我们看一 ... -
Android源码之Binder(一)
2015-12-04 09:12 996在Android系统中,进程间通信使用的是Binder机制。B ...
相关推荐
《安卓系统源码详解——基于Android 14的探索与学习》 Android系统源码是开发者深入了解操作系统工作原理、定制个性化系统以及优化应用性能的重要工具。Android 14的源码,作为Android发展历程中的一个重要版本,为...
在Android源码开发实战9.05的资料中,我们可以深入探索Android操作系统的内部机制,了解如何基于Android 9.0 (Pie)进行定制和优化。Android源码开发是理解系统工作原理、改进性能和实现自定义功能的关键。以下是根据...
在Android源码中,系统的启动从bootloader开始,经过kernel加载,然后进入init进程。这个过程中涉及的源码包括bootable/recovery、system/core/init等目录下的文件。init进程负责初始化系统服务、启动Zygote进程,...
三、Android源码解析 1. 启动流程:Android系统的启动从Zygote进程开始,Zygote fork出SystemServer和各种应用程序进程,MyFeiGe项目也是在这个过程中被加载和初始化的。 2. 进程管理:Android系统通过Activity...
总的来说,《Android源码第二季(Mars)》是一场深入Android内核的探索之旅,通过学习这个项目,开发者不仅能提高代码质量,还能增强对系统优化的理解,为开发更出色的Android应用打下坚实基础。配合网上的教学视频...
这部分源码涉及到Android的系统服务交互,如SurfaceFlinger服务,用于获取屏幕的像素数据。 3. **编码与解码**: VNC协议支持多种编码方式,如RAW、COPYRECT、TIGHT等,用于高效地传输屏幕变化。源码中会有对应的...
"安卓Android源码——胜利大逃亡.zip"可能是一个关于探索和理解Android操作系统核心机制的资料包,其中包含了第15章的内容。这个章节可能涉及到Android系统的某个特定主题,如系统启动流程、进程管理、内存管理或者...
6. **Service管理**:Service是Android中后台运行的服务,源码可以帮助开发者了解Service的启动、绑定过程,以及如何合理地设计和使用Service来实现后台任务。 7. **ContentProvider**:ContentProvider是数据共享...
Android源码解析与常用布局介绍 Android作为全球最流行的开源移动操作系统,其源码的深入理解和分析对于开发者来说至关重要。这份资料集包含了Android源码的介绍以及关于Android常用布局的源码和PPT,旨在帮助...
《Android源码开发实战6.12》是针对Android系统深度开发的一份宝贵资源,它涵盖了从基础到高级的各种主题,旨在帮助开发者更好地理解和利用Android的底层机制。在这个压缩包中,主要包含的是第六章第十二节的内容。...
在本资源中,我们关注的是一个C++编写的Android实时投屏软件系统源码,名为QtScrcpy-dev。这个软件允许用户将安卓手机的屏幕实时传输到其他设备上,而无需对手机进行root操作。这是一项非常实用的技术,尤其对于...
在Android源码开发实战8.11这个主题中,我们主要探讨的是如何深入理解并实践Android系统的源代码,以提升应用程序开发的效率和质量。在这个过程中,开发者将有机会接触到Android系统的底层机制,包括系统启动流程、...
深入理解和分析Android源码中的"core"目录,有助于开发者更深入地了解Android系统的运行机制。 1. **系统库**:在"core"文件夹中,你可以找到多个关键的系统库,如libcore、libc、libart等。libcore是Java层的基础...
在Android源码开发实战课程中,我们通常会深入探索Android操作系统的内部机制,理解系统级服务的实现原理,以及如何利用这些知识进行定制化开发。这个压缩包"android源码开发实战16.01.zip"可能包含了第16讲至第1...
综上所述,Android源码中的system部分是整个系统的核心,它通过C++接口实现了与硬件的交互、系统服务的管理、安全策略的执行等一系列关键功能,构成了Android系统的基础架构。理解和研究这部分代码对于深入理解...
此外,Android使用SurfaceFlinger进行图形渲染,源码分析能帮助开发者理解动画、视图层次和GPU渲染的细节。 4. **系统服务** Android系统服务如电源管理、网络连接、位置服务等在源码中都有体现。通过研究源码,...
Android Framework源码是Android操作系统核心组件之一,它构成了Android应用层与系统服务之间的桥梁。深入理解Android Framework源码对于开发者来说至关重要,因为它可以帮助我们更好地掌握Android系统的运行机制,...
Android源码的分析与研究对于开发人员来说至关重要,它揭示了Android系统的底层运行机制,包括系统启动流程、进程管理、内存管理、图形渲染、安全机制等各个方面。通过学习源码,我们可以: 1. **理解系统启动**:...
Android 系统服务如 LocationProvider、PowerManager 等在系统启动时自动启动,并为上层应用提供服务。eoecn1.1.0 可能新增或修改了某些服务。同时,Dalvik 或 ART 运行时环境负责应用程序的执行,也可能存在性能...