chromium源码分析系列:入门程序:content_shell

        我们看代码的时候会先去找main函数,那么chromium的main函数在哪里呢?或者说,从哪里我们可以进入chromium的世界呢?


        条条大路通罗马。而我觉得捷径是content_shell。content_shell拥有chrome内核,但是没有外层chrome UI,只是封装了一个简单的UI。正好可以让我们从纷繁的UI工作中抽离出来,仔细研究chrome内核工作。


        有了content_shell,我们可以测试,可以debug,了解UI需要做的工作,了解content API即内核提供的接口,跟进内核。如果把浏览器比作操作系统,那么这个content_shell就是内核。


        总之,有了content_shell,我是腰不疼了,腿不酸了,工作起来来特别带劲儿!


        基于content API,chromium封装了content_shell。可见,content API是连接到内核的桥梁啊。而关于content API的科普,这篇文档介绍的很清楚。大力感谢,鼓掌!


        chromium提供了两个层次的API:WebKit API和content API。前者主要是为测试chromium的WebKit port是否成功而提供的接口,对应的测试程序分别是test_shell。而后者是基于chromium内核提供的接口,对应测试程序为content_shell。大家在这里可以考虑一下为什么不从test_shell着手研究chromium,为什么呢,到底是为什么呢?课后作业哦


        关于Content API和WebKit API的区别,我们还是要借鉴一下别人的图,如下。再次感谢,鼓掌!

 《chromium源码分析系列:入门程序:content_shell》


         为什么要引入content API呢?官网是这么说的:


          1. 把chrome的工作从content的内部工作中分离。就是说,一部分人作内核,一部分人作chrome工作,即外壳工作。


          2. 分离chrome和content。这样,其他开发组织可以基于content开发自己的外壳。



          content API提供了哪些功能?满足我们的研究需要吗?啊,泄题了。。。

相比WebKit API而言,Content API增加了HTML5支持、GPU硬件加速、沙箱模型,更重要的是,Content API带来了多进程模型,您再也不用去费力的研究WebKit2了。



          那么,如何编content_shell呢?

          

          很简单,make content_shell。



           content_shell是如何被编出来的?


           看看Makefile,我们发现其实来源于content/content_shell.target.mk。然后我们顺藤摸瓜,找到了入口content/shell/shell_main.cc


           在shell_main.cc中找到main函数之后,我们发现只是调用了ContentMainRunner的Create, Initialize, Run函数。

           ContentMainRunner的实现在content_main_runner.cc


           ContentMainRunner::Create就是创建了对象ContentMainRunnerImpl


           Initialize作初始化工作。以后再研究。


           Run开始创建不同的进程。主要就是BrowserMain,还会有个gpuprocess。不知道RenderProcess是什么时候创建的,但却不是在这里。


           如下是一个content_shell堆栈信息。很清楚的说明了browser进程中URL的load过程。

(gdb) bt
#0  content::RenderWidgetHostImpl::Send (this=0x7fffe35d7c08, msg=0x7fffd74f7740) at content/browser/renderer_host/render_widget_host_impl.cc:343
#1  0x00007ffff6acfedc in content::RenderViewHostImpl::Navigate (this=0x7fffe35d7c00, params=...) at content/browser/renderer_host/render_view_host_impl.cc:326
#2  0x00007ffff6b7ad47 in WebContentsImpl::NavigateToEntry (this=0x7fffe3620500, entry=..., reload_type=content::NavigationController::NO_RELOAD)
    at content/browser/web_contents/web_contents_impl.cc:1543
#3  0x00007ffff6b7a8d6 in WebContentsImpl::NavigateToPendingEntry (this=0x7fffe3620500, reload_type=content::NavigationController::NO_RELOAD)
    at content/browser/web_contents/web_contents_impl.cc:1479
#4  0x00007ffff6b69078 in NavigationControllerImpl::NavigateToPendingEntry (this=0x7fffe3620570, reload_type=content::NavigationController::NO_RELOAD)
    at content/browser/web_contents/navigation_controller_impl.cc:1426
#5  0x00007ffff6b6487c in NavigationControllerImpl::LoadEntry (this=0x7fffe3620570, entry=0x7fffdaa66a80) at content/browser/web_contents/navigation_controller_impl.cc:368
#6  0x00007ffff6b65b12 in NavigationControllerImpl::LoadURLWithParams (this=0x7fffe3620570, params=...) at content/browser/web_contents/navigation_controller_impl.cc:653
#7  0x00007ffff6b655fe in NavigationControllerImpl::LoadURL (this=0x7fffe3620570, url=..., referrer=..., transition=content::PAGE_TRANSITION_TYPED, extra_headers=...)
    at content/browser/web_contents/navigation_controller_impl.cc:576
#8  0x00000000004e083d in content::Shell::LoadURL (this=0x7fffdfdb2100, url=...) at content/shell/shell.cc:130
#9  0x00000000004e07ac in content::Shell::CreateNewWindow (browser_context=0x7fffdfdcd4d0, url=..., site_instance=0x0, routing_id=-2, base_web_contents=0x0)
    at content/shell/shell.cc:121
#10 0x00000000004e4395 in content::ShellBrowserMainParts::PreMainMessageLoopRun (this=0x7fffe35c5740) at content/shell/shell_browser_main_parts.cc:125
#11 0x00007ffff68a22e9 in content::BrowserMainLoop::CreateThreads (this=0x7fffe35c69c0) at content/browser/browser_main_loop.cc:444
#12 0x00007ffff68a491a in (anonymous namespace)::BrowserMainRunnerImpl::Initialize (this=0x7fffe35c26c0, parameters=...) at content/browser/browser_main_runner.cc:86
#13 0x00000000004d6115 in ShellBrowserMain (parameters=...) at content/shell/shell_browser_main.cc:48
#14 0x00000000004d5b04 in content::ShellMainDelegate::RunProcess (this=0x7fffffffdd70, process_type=..., main_function_params=...) at content/shell/shell_main_delegate.cc:110
#15 0x00007ffff687f47c in content::RunNamedProcessTypeMain (process_type=..., main_function_params=..., delegate=0x7fffffffdd70) at content/app/content_main_runner.cc:369
#16 0x00007ffff68802e4 in content::ContentMainRunnerImpl::Run (this=0x7fffe35c3a50) at content/app/content_main_runner.cc:650
#17 0x00007ffff687eaa7 in content::ContentMain (argc=2, argv=0x7fffffffdea8, delegate=0x7fffffffdd70) at content/app/content_main.cc:35
#18 0x00000000004d5805 in main (argc=2, argv=0x7fffffffdea8) at content/shell/shell_main.cc:36

            

           然后就是render进程的处理过程了。这就到了WebKit相关的代码中了,然后就是WebKit的相关处理。

(gdb) bt
#0  RenderViewImpl::OnNavigate (this=0x7fffd4b1c600, params=...) at content/renderer/render_view_impl.cc:985
#1  0x00007ffff6e6eccc in DispatchToMethod<RenderViewImpl, void (RenderViewImpl::*)(ViewMsg_Navigate_Params const&), ViewMsg_Navigate_Params> (obj=0x7fffd4b1c600, method=
    (void (RenderViewImpl::*)(RenderViewImpl * const, const ViewMsg_Navigate_Params &)) 0x7ffff6e50e7e <RenderViewImpl::OnNavigate(ViewMsg_Navigate_Params const&)>, arg=...)
    at ./base/tuple.h:546
#2  0x00007ffff6e6ab00 in ViewMsg_Navigate::Dispatch<RenderViewImpl, RenderViewImpl, void (RenderViewImpl::*)(ViewMsg_Navigate_Params const&)> (msg=0x7fffd7501988, 
    obj=0x7fffd4b1c600, sender=0x7fffd4b1c600, func=
    (void (RenderViewImpl::*)(RenderViewImpl * const, const ViewMsg_Navigate_Params &)) 0x7ffff6e50e7e <RenderViewImpl::OnNavigate(ViewMsg_Navigate_Params const&)>)
    at ./content/common/view_messages.h:945
#3  0x00007ffff6e4e1a1 in RenderViewImpl::OnMessageReceived (this=0x7fffd4b1c600, message=...) at content/renderer/render_view_impl.cc:863
#4  0x00007ffff6d3e2d6 in MessageRouter::RouteMessage (this=0x7fffda8badf0, msg=...) at content/common/message_router.cc:47
#5  0x00007ffff6d3e27c in MessageRouter::OnMessageReceived (this=0x7fffda8badf0, msg=...) at content/common/message_router.cc:39
#6  0x00007ffff6bbfe15 in ChildThread::OnMessageReceived (this=0x7fffda8badc8, msg=...) at content/common/child_thread.cc:275
#7  0x00007ffff7fc792f in IPC::ChannelProxy::Context::OnDispatchMessage (this=0x7fffd7507c40, message=...) at ipc/ipc_channel_proxy.cc:261
#8  0x00007ffff7fcad06 in base::internal::RunnableAdapter<void (IPC::ChannelProxy::Context::*)(IPC::Message const&)>::Run (this=0x7fffd6645090, object=0x7fffd7507c40, a1=...)
    at ./base/bind_internal.h:190
#9  0x00007ffff7fca7d6 in base::internal::InvokeHelper<false, void, base::internal::RunnableAdapter<void (IPC::ChannelProxy::Context::*)(IPC::Message const&)>, void (IPC::ChannelProxy::Context* const&, IPC::Message const&)>::MakeItSo(base::internal::RunnableAdapter<void (IPC::ChannelProxy::Context::*)(IPC::Message const&)>, IPC::ChannelProxy::Context* const&, IPC::Message const&) (runnable=..., a1=@0x7fffd7501980: 0x7fffd7507c40, a2=...) at ./base/bind_internal.h:898
#10 0x00007ffff7fca0b3 in base::internal::Invoker<2, base::internal::BindState<base::internal::RunnableAdapter<void (IPC::ChannelProxy::Context::*)(IPC::Message const&)>, void (IPC::ChannelProxy::Context*, IPC::Message const&), void (IPC::ChannelProxy::Context*, IPC::Message)>, void (IPC::ChannelProxy::Context*, IPC::Message const&)>::Run(base::internal::BindStateBase*) (base=0x7fffd7501960) at ./base/bind_internal.h:1256
#11 0x00007ffff5996cc5 in base::Callback<void ()>::Run() const (this=0x7fffd66453e8) at ./base/callback.h:389
#12 0x00007ffff59d4398 in MessageLoop::RunTask (this=0x7fffd6645a30, pending_task=...) at base/message_loop.cc:460
#13 0x00007ffff59d44b0 in MessageLoop::DeferOrRunPendingTask (this=0x7fffd6645a30, pending_task=...) at base/message_loop.cc:472
#14 0x00007ffff59d4ca7 in MessageLoop::DoWork (this=0x7fffd6645a30) at base/message_loop.cc:648
#15 0x00007ffff59dcc02 in base::MessagePumpDefault::Run (this=0x7fffdfdce180, delegate=0x7fffd6645a30) at base/message_pump_default.cc:28
#16 0x00007ffff59d406b in MessageLoop::RunInternal (this=0x7fffd6645a30) at base/message_loop.cc:419
#17 0x00007ffff59d3f22 in MessageLoop::RunHandler (this=0x7fffd6645a30) at base/message_loop.cc:392
#18 0x00007ffff5a06d70 in base::RunLoop::Run (this=0x7fffd6645830) at base/run_loop.cc:45
#19 0x00007ffff59d3856 in MessageLoop::Run (this=0x7fffd6645a30) at base/message_loop.cc:299
#20 0x00007ffff5a437ec in base::Thread::Run (this=0x7fffdaa58820, message_loop=0x7fffd6645a30) at base/threading/thread.cc:133
#21 0x00007ffff5a43977 in base::Thread::ThreadMain (this=0x7fffdaa58820) at base/threading/thread.cc:169
#22 0x00007ffff5a37c3b in base::(anonymous namespace)::ThreadFunc (params=0x7fffdaab9460) at base/threading/platform_thread_posix.cc:65
#23 0x00007fffed978e9a in start_thread (arg=0x7fffd6646700) at pthread_create.c:308
#24 0x00007fffed6a64bd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
warning: (Internal error: pc 0x0 in read in psymtab, but not in symtab.)

#25 0x0000000000000000 in ?? ()

         什么时候回到Browser进程呢?我们不回来了!!!


参考:

1. http://mogoweb.net/archives/376

    原文作者:Android源码分析
    原文地址: https://blog.csdn.net/awebkit/article/details/7886438
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞