日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

谷歌chrome浏览器的源码分析(五)

發布時間:2025/3/21 HTML 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 谷歌chrome浏览器的源码分析(五) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


上一次說到類RenderThread和類RenderView把消息處理,那么這兩個類是怎么樣處理消息的呢?又是怎么樣處理瀏覽的消息呢?現在就帶著這兩個問題去分析它的源碼,理解它處理消息的方法。類RenderThread處理消息的代碼如下:

#001??void RenderThread::OnMessageReceived(const IPC::Message& msg) {

#002????// NOTE: We could subclass router_ to intercept OnControlMessageReceived, but

#003????// it seems simpler to just process any control messages that we care about

#004????// up-front and then send the rest of the messages onto router_.

#005?

?

下面判斷是控制消息,如果是控制消息就在本類里處理,否則就分發到別的地方處理,主要是轉到類RenderView處理。

#006????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#007??????IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)

#008????????IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)

#009????????IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)

#010????????IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)

#011????????IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)

#012????????IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,

#013???????????????????????????OnGetCacheResourceStats)

#014????????// send the rest to the router

#015????????IPC_MESSAGE_UNHANDLED(router_.OnMessageReceived(msg))

#016??????IPC_END_MESSAGE_MAP()

#017????} else {

?

這里是分發消息到別的地方處理。

#018??????router_.OnMessageReceived(msg);

#019????}

#020??}

?

在瀏覽器里,消息分為兩大類:控制消息和路由消息。像使用IPC_MESSAGE_CONTROL宏定義的消息,就是控制消息;使用IPC_MESSAGE_ROUTED宏定義的消息,就是路由消息。

路由消息分發是由類MessageRouter來負責的,主要處理的代碼如下:

#001?

#002??void MessageRouter::OnMessageReceived(const IPC::Message& msg) {

#003????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#004??????OnControlMessageReceived(msg);

#005????} else {

#006??????RouteMessage(msg);

#007????}

#008??}

在這里又分為MSG_ROUTING_CONTROL消息和其它路由消息,再一次通過函數RouteMessage分發之后,如下:

#001??bool MessageRouter::RouteMessage(const IPC::Message& msg) {

#002????IPC::Channel::Listener* listener = routes_.Lookup(msg.routing_id());

#003????if (!listener)

#004??????return false;

#005?

#006????listener->OnMessageReceived(msg);

#007????return true;

#008??}

上面這個函數里又把消息通過發送到listener里去,其實listener是根據消息的目標routing_id來選擇的,那么就是說它是選擇發送到不同的窗口里去,因為每個TAB一個窗口。消息經過這樣的處理之后,就到達了終點地---?RenderView::OnMessageReceived函數。下一次再來分析RenderView::OnMessageReceived函數的代碼和后繼處理。





上一次說到類RenderThread和類RenderView把消息處理,那么這兩個類是怎么樣處理消息的呢?又是怎么樣處理瀏覽的消息呢?現在就帶著這兩個問題去分析它的源碼,理解它處理消息的方法。類RenderThread處理消息的代碼如下:

#001??void RenderThread::OnMessageReceived(const IPC::Message& msg) {

#002????// NOTE: We could subclass router_ to intercept OnControlMessageReceived, but

#003????// it seems simpler to just process any control messages that we care about

#004????// up-front and then send the rest of the messages onto router_.

#005?

?

下面判斷是控制消息,如果是控制消息就在本類里處理,否則就分發到別的地方處理,主要是轉到類RenderView處理。

#006????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#007??????IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)

#008????????IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)

#009????????IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)

#010????????IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)

#011????????IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)

#012????????IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,

#013???????????????????????????OnGetCacheResourceStats)

#014????????// send the rest to the router

#015????????IPC_MESSAGE_UNHANDLED(router_.OnMessageReceived(msg))

#016??????IPC_END_MESSAGE_MAP()

#017????} else {

?

這里是分發消息到別的地方處理。

#018??????router_.OnMessageReceived(msg);

#019????}

#020??}

?

在瀏覽器里,消息分為兩大類:控制消息和路由消息。像使用IPC_MESSAGE_CONTROL宏定義的消息,就是控制消息;使用IPC_MESSAGE_ROUTED宏定義的消息,就是路由消息。

路由消息分發是由類MessageRouter來負責的,主要處理的代碼如下:

#001?

#002??void MessageRouter::OnMessageReceived(const IPC::Message& msg) {

#003????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#004??????OnControlMessageReceived(msg);

#005????} else {

#006??????RouteMessage(msg);

#007????}

#008??}

在這里又分為MSG_ROUTING_CONTROL消息和其它路由消息,再一次通過函數RouteMessage分發之后,如下:

#001??bool MessageRouter::RouteMessage(const IPC::Message& msg) {

#002????IPC::Channel::Listener* listener = routes_.Lookup(msg.routing_id());

#003????if (!listener)

#004??????return false;

#005?

#006????listener->OnMessageReceived(msg);

#007????return true;

#008??}

上面這個函數里又把消息通過發送到listener里去,其實listener是根據消息的目標routing_id來選擇的,那么就是說它是選擇發送到不同的窗口里去,因為每個TAB一個窗口。消息經過這樣的處理之后,就到達了終點地---?RenderView::OnMessageReceived函數。下一次再來分析RenderView::OnMessageReceived函數的代碼和后繼處理。




上一次說到消息轉發,并分析了RenderThread類里處理消息的函數,其實大部份的消息都是在RenderView類里的OnMessageReceived函數處理,比如瀏覽的消息也是在這里處理。它的代碼如下:

#001??void RenderView::OnMessageReceived(const IPC::Message& message) {

#002????// Let the resource dispatcher intercept resource messages first.

?

如果是資源消息,就直接分發去處理,以便提高效率。

#003????if (resource_dispatcher_->OnMessageReceived(message))

#004??????return;

?

下面開始處理RenderView類里所有的消息。

#005????IPC_BEGIN_MESSAGE_MAP(RenderView, message)

#006??????IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)

#007??????IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)

#008??????IPC_MESSAGE_HANDLER(ViewMsg_GetPrintedPagesCount, OnGetPrintedPagesCount)

#009??????IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)

#010??????IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)

#011??????IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)

#012??????IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)

#013??????IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)

#014??????IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)

#015??????IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)

#016??????IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)

#017??????IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)

#018??????IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)

#019??????IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)

#020??????IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)

#021??????IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)

#022??????IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)

#023??????IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)

#024??????IPC_MESSAGE_HANDLER(ViewMsg_AlterTextSize, OnAlterTextSize)

#025??????IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)

#026??????IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement)

#027??????IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole)

#028??????IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)

#029??????IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)

#030??????IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)

#031??????IPC_MESSAGE_HANDLER(ViewMsg_DebugAttach, OnDebugAttach)

#032??????IPC_MESSAGE_HANDLER(ViewMsg_DebugDetach, OnDebugDetach)

#033??????IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)

#034??????IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)

#035??????IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)

#036??????IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)

#037??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)

#038??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)

#039??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)

#040??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)

#041??????IPC_MESSAGE_HANDLER(ViewMsg_AllowDomAutomationBindings,

#042?????????????????????????OnAllowDomAutomationBindings)

#043??????IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)

#044??????IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)

#045??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved, OnDragSourceEndedOrMoved)

#046??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,

#047?????????????????????????OnDragSourceSystemDragEnded)

#048??????IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)

#049??????IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)

#050??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)

#051??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)

#052??????IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)

#053??????IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)

#054??????IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)

#055??????IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)

#056??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,

#057?????????????????????????OnUpdateBackForwardListCount)

#058?????IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,

#059?????????????????????????OnGetAllSavableResourceLinksForCurrentPage)

#060?????IPC_MESSAGE_HANDLER(ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,

#061?????????????????????????OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)

#062??????IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)

#063??????IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)

#064??????IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)

#065??????IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)

#066??#ifdef CHROME_PERSONALIZATION

#067??????IPC_MESSAGE_HANDLER(ViewMsg_PersonalizationEvent, OnPersonalizationEvent)

#068??#endif

#069??????IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,

#070??????????????????????????OnMessageFromExternalHost)

?

這里對于沒有處理的消息進行提示。

#071??????// Have the super handle all other messages.

#072??????IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))

#073????IPC_END_MESSAGE_MAP()

#074??}

?

從上面這個函數可以看到,它的消息處理是非常多的,下面來分析一個瀏覽網絡連接的消息,它就是ViewMsg_Navigate,可以看到這個消息后面響應函數是OnNavigate,也就是說,當你輸入網絡地址之后按回車,就會通過上說過的IPC機制把消息發送到這里,接著來看這個函數OnNavigate的代碼,如下:

#001??void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {

?

判斷窗口是否關閉,如果關閉就不用去打開連接地址了。

#002????if (!webview())

#003??????return;

#004?

?

處理一些about的連接處理,比如about:crash。

#005????AboutHandler::MaybeHandle(params.url);

#006?

?

保存是否重新加載網頁。

#007????bool is_reload = params.reload;

#008?

?

獲取WEB的顯示框架。

#009????WebFrame* main_frame = webview()->GetMainFrame();

?

判斷當是重新加載時,而當前又不是歷史網頁的情況。

#010????if (is_reload && !main_frame->HasCurrentState()) {

#011??????// We cannot reload if we do not have any history state.??This happens, for

#012??????// example, when recovering from a crash.??Our workaround here is a bit of

#013??????// a hack since it means that reload after a crashed tab does not cause an

#014??????// end-to-end cache validation.

#015??????is_reload = false;

#016????}

#017?

?

下面設置緩沖策略。

#018????WebRequestCachePolicy cache_policy;

#019????if (is_reload) {

#020??????cache_policy = WebRequestReloadIgnoringCacheData;

#021????} else if (params.page_id != -1 || main_frame->GetInViewSourceMode()) {

#022??????cache_policy = WebRequestReturnCacheDataElseLoad;

#023????} else {

#024??????cache_policy = WebRequestUseProtocolCachePolicy;

#025????}

#026?

?

下面創建一個下載請求,并把相關參數設置到請求里面。

#027????scoped_ptr<WebRequest> request(WebRequest::Create(params.url));

#028????request->SetCachePolicy(cache_policy);

#029????request->SetExtraData(new RenderViewExtraRequestData(

#030????????params.page_id, params.transition, params.url));

#031?

?

設置WEBKIT的請求狀態。

#032????// If we are reloading, then WebKit will use the state of the current page.

#033????// Otherwise, we give it the state to navigate to.

#034????if (!is_reload)

#035??????request->SetHistoryState(params.state);

#036?

?

讓主WEB顯示框架去下載請求顯示。

#037????main_frame->LoadRequest(request.get());

#038??}

?

分析這個函數,就可以知道處理瀏覽消息的過程,下一次來分析WebFrame里的接口函數LoadRequest處理過程,到底它是怎么樣處理JavaScript腳本網頁下載的呢?









上一次說到類RenderThread和類RenderView把消息處理,那么這兩個類是怎么樣處理消息的呢?又是怎么樣處理瀏覽的消息呢?現在就帶著這兩個問題去分析它的源碼,理解它處理消息的方法。類RenderThread處理消息的代碼如下:

#001??void RenderThread::OnMessageReceived(const IPC::Message& msg) {

#002????// NOTE: We could subclass router_ to intercept OnControlMessageReceived, but

#003????// it seems simpler to just process any control messages that we care about

#004????// up-front and then send the rest of the messages onto router_.

#005?

?

下面判斷是控制消息,如果是控制消息就在本類里處理,否則就分發到別的地方處理,主要是轉到類RenderView處理。

#006????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#007??????IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)

#008????????IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)

#009????????IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)

#010????????IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)

#011????????IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)

#012????????IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,

#013???????????????????????????OnGetCacheResourceStats)

#014????????// send the rest to the router

#015????????IPC_MESSAGE_UNHANDLED(router_.OnMessageReceived(msg))

#016??????IPC_END_MESSAGE_MAP()

#017????} else {

?

這里是分發消息到別的地方處理。

#018??????router_.OnMessageReceived(msg);

#019????}

#020??}

?

在瀏覽器里,消息分為兩大類:控制消息和路由消息。像使用IPC_MESSAGE_CONTROL宏定義的消息,就是控制消息;使用IPC_MESSAGE_ROUTED宏定義的消息,就是路由消息。

路由消息分發是由類MessageRouter來負責的,主要處理的代碼如下:

#001?

#002??void MessageRouter::OnMessageReceived(const IPC::Message& msg) {

#003????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#004??????OnControlMessageReceived(msg);

#005????} else {

#006??????RouteMessage(msg);

#007????}

#008??}

在這里又分為MSG_ROUTING_CONTROL消息和其它路由消息,再一次通過函數RouteMessage分發之后,如下:

#001??bool MessageRouter::RouteMessage(const IPC::Message& msg) {

#002????IPC::Channel::Listener* listener = routes_.Lookup(msg.routing_id());

#003????if (!listener)

#004??????return false;

#005?

#006????listener->OnMessageReceived(msg);

#007????return true;

#008??}

上面這個函數里又把消息通過發送到listener里去,其實listener是根據消息的目標routing_id來選擇的,那么就是說它是選擇發送到不同的窗口里去,因為每個TAB一個窗口。消息經過這樣的處理之后,就到達了終點地---?RenderView::OnMessageReceived函數。下一次再來分析RenderView::OnMessageReceived函數的代碼和后繼處理。


上一次說到消息轉發,并分析了RenderThread類里處理消息的函數,其實大部份的消息都是在RenderView類里的OnMessageReceived函數處理,比如瀏覽的消息也是在這里處理。它的代碼如下:

#001??void RenderView::OnMessageReceived(const IPC::Message& message) {

#002????// Let the resource dispatcher intercept resource messages first.

?

如果是資源消息,就直接分發去處理,以便提高效率。

#003????if (resource_dispatcher_->OnMessageReceived(message))

#004??????return;

?

下面開始處理RenderView類里所有的消息。

#005????IPC_BEGIN_MESSAGE_MAP(RenderView, message)

#006??????IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)

#007??????IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)

#008??????IPC_MESSAGE_HANDLER(ViewMsg_GetPrintedPagesCount, OnGetPrintedPagesCount)

#009??????IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)

#010??????IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)

#011??????IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)

#012??????IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)

#013??????IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)

#014??????IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)

#015??????IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)

#016??????IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)

#017??????IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)

#018??????IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)

#019??????IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)

#020??????IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)

#021??????IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)

#022??????IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)

#023??????IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)

#024??????IPC_MESSAGE_HANDLER(ViewMsg_AlterTextSize, OnAlterTextSize)

#025??????IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)

#026??????IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement)

#027??????IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole)

#028??????IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)

#029??????IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)

#030??????IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)

#031??????IPC_MESSAGE_HANDLER(ViewMsg_DebugAttach, OnDebugAttach)

#032??????IPC_MESSAGE_HANDLER(ViewMsg_DebugDetach, OnDebugDetach)

#033??????IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)

#034??????IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)

#035??????IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)

#036??????IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)

#037??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)

#038??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)

#039??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)

#040??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)

#041??????IPC_MESSAGE_HANDLER(ViewMsg_AllowDomAutomationBindings,

#042?????????????????????????OnAllowDomAutomationBindings)

#043??????IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)

#044??????IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)

#045??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved, OnDragSourceEndedOrMoved)

#046??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,

#047?????????????????????????OnDragSourceSystemDragEnded)

#048??????IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)

#049??????IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)

#050??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)

#051??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)

#052??????IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)

#053??????IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)

#054??????IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)

#055??????IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)

#056??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,

#057?????????????????????????OnUpdateBackForwardListCount)

#058?????IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,

#059?????????????????????????OnGetAllSavableResourceLinksForCurrentPage)

#060?????IPC_MESSAGE_HANDLER(ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,

#061?????????????????????????OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)

#062??????IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)

#063??????IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)

#064??????IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)

#065??????IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)

#066??#ifdef CHROME_PERSONALIZATION

#067??????IPC_MESSAGE_HANDLER(ViewMsg_PersonalizationEvent, OnPersonalizationEvent)

#068??#endif

#069??????IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,

#070??????????????????????????OnMessageFromExternalHost)

?

這里對于沒有處理的消息進行提示。

#071??????// Have the super handle all other messages.

#072??????IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))

#073????IPC_END_MESSAGE_MAP()

#074??}

?

從上面這個函數可以看到,它的消息處理是非常多的,下面來分析一個瀏覽網絡連接的消息,它就是ViewMsg_Navigate,可以看到這個消息后面響應函數是OnNavigate,也就是說,當你輸入網絡地址之后按回車,就會通過上說過的IPC機制把消息發送到這里,接著來看這個函數OnNavigate的代碼,如下:

#001??void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {

?

判斷窗口是否關閉,如果關閉就不用去打開連接地址了。

#002????if (!webview())

#003??????return;

#004?

?

處理一些about的連接處理,比如about:crash。

#005????AboutHandler::MaybeHandle(params.url);

#006?

?

保存是否重新加載網頁。

#007????bool is_reload = params.reload;

#008?

?

獲取WEB的顯示框架。

#009????WebFrame* main_frame = webview()->GetMainFrame();

?

判斷當是重新加載時,而當前又不是歷史網頁的情況。

#010????if (is_reload && !main_frame->HasCurrentState()) {

#011??????// We cannot reload if we do not have any history state.??This happens, for

#012??????// example, when recovering from a crash.??Our workaround here is a bit of

#013??????// a hack since it means that reload after a crashed tab does not cause an

#014??????// end-to-end cache validation.

#015??????is_reload = false;

#016????}

#017?

?

下面設置緩沖策略。

#018????WebRequestCachePolicy cache_policy;

#019????if (is_reload) {

#020??????cache_policy = WebRequestReloadIgnoringCacheData;

#021????} else if (params.page_id != -1 || main_frame->GetInViewSourceMode()) {

#022??????cache_policy = WebRequestReturnCacheDataElseLoad;

#023????} else {

#024??????cache_policy = WebRequestUseProtocolCachePolicy;

#025????}

#026?

?

下面創建一個下載請求,并把相關參數設置到請求里面。

#027????scoped_ptr<WebRequest> request(WebRequest::Create(params.url));

#028????request->SetCachePolicy(cache_policy);

#029????request->SetExtraData(new RenderViewExtraRequestData(

#030????????params.page_id, params.transition, params.url));

#031?

?

設置WEBKIT的請求狀態。

#032????// If we are reloading, then WebKit will use the state of the current page.

#033????// Otherwise, we give it the state to navigate to.

#034????if (!is_reload)

#035??????request->SetHistoryState(params.state);

#036?

?

讓主WEB顯示框架去下載請求顯示。

#037????main_frame->LoadRequest(request.get());

#038??}

?

分析這個函數,就可以知道處理瀏覽消息的過程,下一次來分析WebFrame里的接口函數LoadRequest處理過程,到底它是怎么樣處理JavaScript腳本網頁下載的呢?


繼續上一次來分析LoadRequest的代碼,在分析這個函數代碼之前,先看看WebFrame類的繼承層次關系,如下:

class WebFrame : public base::RefCounted<WebFrame> {

WebFrame是一個接口類,但它先繼承引用計數類RefCounted,這樣對于這個對象多次訪問,就可以使用引用計數來判斷對象的生命周期了。對于base::RefCounted<WebFrame>的語法,其實它是一種模板實現的多態特性,這種方案是最高效的實現方式,比使用虛函數更少占內存,并且運行的速度也更快。它就是解決如下的問題:

??void Release() {

????if (subtle::RefCountedBase::Release()) {

??????delete static_cast<T*>(this);

????}

??}

上面的函數里static_cast<T*>(this),它就是一種多態的實現方法,由于base::RefCounted類并沒有聲明為虛析構函數,如下:

template <class T>

class RefCounted : public subtle::RefCountedBase {

?public:

??RefCounted() { }

??~RefCounted() { }

?

既然沒有把類RefCounted聲明為虛析構函數,又想在基類里調用派生類的析構函數,只好使用static_cast和類型轉換了,這是一種比較好的模板使用方法,在WTL里就大量使用這種技術。

接著可以看到:

class WebFrameImpl : public WebFrame {

?public:

??WebFrameImpl();

??~WebFrameImpl();

類WebFrameImpl是繼承接口類WebFrame,這里是使用接口與實現分析的設計模式,這樣更方便代碼靈活地復用。可見設計Chrome的設計師和寫代碼的程序員,都是頂尖的模板高手,大部的思想與WTL庫的設計是一脈相承。也難怪Chrome的瀏覽器使用WTL庫來設計界面。

?

#001??void WebFrameImpl::LoadRequest(WebRequest* request) {

#002????SubstituteData data;

#003????InternalLoadRequest(request, data, false);

#004??}

在WebFrame里調用函數LoadRequest,實際上是調用實現類WebFrameImpl函數LoadRequest,而在這個函數又是調用InternalLoadRequest來實現的,它的代碼如下:

#001??void WebFrameImpl::InternalLoadRequest(const WebRequest* request,

#002????????????????????????????????????????const SubstituteData& data,

#003????????????????????????????????????????bool replace) {

?

//轉換請求參數。

#004????const WebRequestImpl* request_impl =

#005????????static_cast<const WebRequestImpl*>(request);

#006?

?

獲取請求的資源。

#007????const ResourceRequest& resource_request =

#008????????request_impl->frame_load_request().resourceRequest();

#009?

#010????// Special-case?JavaScript?URLs.??Do not interrupt the existing load when

#011????// asked to load a javascript URL unless the script generates a result.

#012????// We can't just use FrameLoader::executeIfJavaScriptURL because it doesn't

#013????// handle redirects properly.

?

獲取需要下載網頁的地址。

#014????const KURL& kurl = resource_request.url();

?

處理加載javascript的連接情況。

#015????if (!data.isValid() && kurl.protocol() == "javascript") {

#016??????// Don't attempt to reload javascript URLs.

#017??????if (resource_request.cachePolicy() == ReloadIgnoringCacheData)

#018????????return;

#019?

#020??????// We can't load a javascript: URL if there is no Document!

#021??????if (!frame_->document())

#022????????return;

#023?

#024??????// TODO(darin): Is this the best API to use here???It works and seems good,

#025??????// but will it change out from under us?

#026??????DeprecatedString script =

#027?????????KURL::decode_string(kurl.deprecatedString().mid(sizeof("javascript:")-1));

#028??????bool succ = false;

?

加載執行腳本。

#029??????WebCore::String value =

#030??????????frame_->loader()->executeScript(script, &succ, true);

#031??????if (succ && !frame_->loader()->isScheduledLocationChangePending()) {

#032????????// TODO(darin): We need to figure out how to represent this in session

#033????????// history.??Hint: don't re-eval script when the user or script navigates

#034????????// back-n-forth (instead store the script result somewhere).

#035????????LoadDocumentData(kurl, value, String("text/html"), String());

#036??????}

#037??????return;

#038????}

#039?

?

停止上一次沒有完成的加載情況。

#040????StopLoading();??// make sure existing activity stops

#041?

#042????// Keep track of the request temporarily.??This is effectively a way of

#043????// passing the request to callbacks that may need it.??See

#044????// WebFrameLoaderClient::createDocumentLoader.

?

保存當前的請求連接。

#045????currently_loading_request_ = request;

#046?

#047????// If we have a current datasource, save the request info on it immediately.

#048????// This is because WebCore may not actually initiate a load on the toplevel

#049????// frame for some subframe navigations, so we want to update its request.

?

獲取當前數據源,如果已經存在就可以保存它。

#050????WebDataSourceImpl* datasource = GetDataSourceImpl();

#051????if (datasource)

#052??????CacheCurrentRequestInfo(datasource);

#053?

?

如果數據有效就可以直接替換就行了。

#054????if (data.isValid()) {

#055??????frame_->loader()->load(resource_request, data);

#056??????if (replace) {

#057????????// Do this to force WebKit to treat the load as replacing the currently

#058????????// loaded page.

#059????????frame_->loader()->setReplacing();

#060??????}

?

如果是歷史網頁選擇,就判斷是否出錯的加載處理。

#061????} else if (request_impl->history_item()) {

#062??????// Use the history item if we have one, otherwise fall back to standard

#063??????// load.

#064??????RefPtr<HistoryItem> current_item = frame_->loader()->currentHistoryItem();

#065?

#066??????// If there is no current_item, which happens when we are navigating in

#067??????// session history after a crash, we need to manufacture one otherwise

#068??????// WebKit hoarks. This is probably the wrong thing to do, but it seems to

#069??????// work.

#070??????if (!current_item) {

#071????????current_item = new HistoryItem(KURL("about:blank"), "");

#072????????frame_->loader()->setCurrentHistoryItem(current_item);

#073????????frame_->page()->backForwardList()->setCurrentItem(current_item.get());

#074?

#075????????// Mark the item as fake, so that we don't attempt to save its state and

#076????????// end up with about:blank in the navigation history.

#077????????frame_->page()->backForwardList()->setCurrentItemFake(true);

#078??????}

#079?

#080??????frame_->loader()->goToItem(request_impl->history_item().get(),

#081????????????????????????????????WebCore::FrameLoadTypeIndexedBackForward);

?

重新加載網頁。

#082????} else if (resource_request.cachePolicy() == ReloadIgnoringCacheData) {

#083??????frame_->loader()->reload();

?

?

下面開始調用load來加載新下載的網頁資源。

#084????} else {

#085??????frame_->loader()->load(resource_request);

#086????}

#087?

#088????currently_loading_request_ = NULL;

#089??}

?

上面通過幾種情況來分別實現了加載javascript網頁的處理,還有歷史選項處理,還有重新加載網頁和加載新網頁的處理。下一次再來分析加載新網頁的函數frame_->loader()->load的實現。







上一次說到類RenderThread和類RenderView把消息處理,那么這兩個類是怎么樣處理消息的呢?又是怎么樣處理瀏覽的消息呢?現在就帶著這兩個問題去分析它的源碼,理解它處理消息的方法。類RenderThread處理消息的代碼如下:

#001??void RenderThread::OnMessageReceived(const IPC::Message& msg) {

#002????// NOTE: We could subclass router_ to intercept OnControlMessageReceived, but

#003????// it seems simpler to just process any control messages that we care about

#004????// up-front and then send the rest of the messages onto router_.

#005?

?

下面判斷是控制消息,如果是控制消息就在本類里處理,否則就分發到別的地方處理,主要是轉到類RenderView處理。

#006????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#007??????IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)

#008????????IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)

#009????????IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)

#010????????IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)

#011????????IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)

#012????????IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,

#013???????????????????????????OnGetCacheResourceStats)

#014????????// send the rest to the router

#015????????IPC_MESSAGE_UNHANDLED(router_.OnMessageReceived(msg))

#016??????IPC_END_MESSAGE_MAP()

#017????} else {

?

這里是分發消息到別的地方處理。

#018??????router_.OnMessageReceived(msg);

#019????}

#020??}

?

在瀏覽器里,消息分為兩大類:控制消息和路由消息。像使用IPC_MESSAGE_CONTROL宏定義的消息,就是控制消息;使用IPC_MESSAGE_ROUTED宏定義的消息,就是路由消息。

路由消息分發是由類MessageRouter來負責的,主要處理的代碼如下:

#001?

#002??void MessageRouter::OnMessageReceived(const IPC::Message& msg) {

#003????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#004??????OnControlMessageReceived(msg);

#005????} else {

#006??????RouteMessage(msg);

#007????}

#008??}

在這里又分為MSG_ROUTING_CONTROL消息和其它路由消息,再一次通過函數RouteMessage分發之后,如下:

#001??bool MessageRouter::RouteMessage(const IPC::Message& msg) {

#002????IPC::Channel::Listener* listener = routes_.Lookup(msg.routing_id());

#003????if (!listener)

#004??????return false;

#005?

#006????listener->OnMessageReceived(msg);

#007????return true;

#008??}

上面這個函數里又把消息通過發送到listener里去,其實listener是根據消息的目標routing_id來選擇的,那么就是說它是選擇發送到不同的窗口里去,因為每個TAB一個窗口。消息經過這樣的處理之后,就到達了終點地---?RenderView::OnMessageReceived函數。下一次再來分析RenderView::OnMessageReceived函數的代碼和后繼處理。


上一次說到消息轉發,并分析了RenderThread類里處理消息的函數,其實大部份的消息都是在RenderView類里的OnMessageReceived函數處理,比如瀏覽的消息也是在這里處理。它的代碼如下:

#001??void RenderView::OnMessageReceived(const IPC::Message& message) {

#002????// Let the resource dispatcher intercept resource messages first.

?

如果是資源消息,就直接分發去處理,以便提高效率。

#003????if (resource_dispatcher_->OnMessageReceived(message))

#004??????return;

?

下面開始處理RenderView類里所有的消息。

#005????IPC_BEGIN_MESSAGE_MAP(RenderView, message)

#006??????IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)

#007??????IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)

#008??????IPC_MESSAGE_HANDLER(ViewMsg_GetPrintedPagesCount, OnGetPrintedPagesCount)

#009??????IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)

#010??????IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)

#011??????IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)

#012??????IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)

#013??????IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)

#014??????IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)

#015??????IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)

#016??????IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)

#017??????IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)

#018??????IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)

#019??????IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)

#020??????IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)

#021??????IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)

#022??????IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)

#023??????IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)

#024??????IPC_MESSAGE_HANDLER(ViewMsg_AlterTextSize, OnAlterTextSize)

#025??????IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)

#026??????IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement)

#027??????IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole)

#028??????IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)

#029??????IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)

#030??????IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)

#031??????IPC_MESSAGE_HANDLER(ViewMsg_DebugAttach, OnDebugAttach)

#032??????IPC_MESSAGE_HANDLER(ViewMsg_DebugDetach, OnDebugDetach)

#033??????IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)

#034??????IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)

#035??????IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)

#036??????IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)

#037??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)

#038??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)

#039??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)

#040??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)

#041??????IPC_MESSAGE_HANDLER(ViewMsg_AllowDomAutomationBindings,

#042?????????????????????????OnAllowDomAutomationBindings)

#043??????IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)

#044??????IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)

#045??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved, OnDragSourceEndedOrMoved)

#046??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,

#047?????????????????????????OnDragSourceSystemDragEnded)

#048??????IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)

#049??????IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)

#050??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)

#051??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)

#052??????IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)

#053??????IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)

#054??????IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)

#055??????IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)

#056??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,

#057?????????????????????????OnUpdateBackForwardListCount)

#058?????IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,

#059?????????????????????????OnGetAllSavableResourceLinksForCurrentPage)

#060?????IPC_MESSAGE_HANDLER(ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,

#061?????????????????????????OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)

#062??????IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)

#063??????IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)

#064??????IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)

#065??????IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)

#066??#ifdef CHROME_PERSONALIZATION

#067??????IPC_MESSAGE_HANDLER(ViewMsg_PersonalizationEvent, OnPersonalizationEvent)

#068??#endif

#069??????IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,

#070??????????????????????????OnMessageFromExternalHost)

?

這里對于沒有處理的消息進行提示。

#071??????// Have the super handle all other messages.

#072??????IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))

#073????IPC_END_MESSAGE_MAP()

#074??}

?

從上面這個函數可以看到,它的消息處理是非常多的,下面來分析一個瀏覽網絡連接的消息,它就是ViewMsg_Navigate,可以看到這個消息后面響應函數是OnNavigate,也就是說,當你輸入網絡地址之后按回車,就會通過上說過的IPC機制把消息發送到這里,接著來看這個函數OnNavigate的代碼,如下:

#001??void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {

?

判斷窗口是否關閉,如果關閉就不用去打開連接地址了。

#002????if (!webview())

#003??????return;

#004?

?

處理一些about的連接處理,比如about:crash。

#005????AboutHandler::MaybeHandle(params.url);

#006?

?

保存是否重新加載網頁。

#007????bool is_reload = params.reload;

#008?

?

獲取WEB的顯示框架。

#009????WebFrame* main_frame = webview()->GetMainFrame();

?

判斷當是重新加載時,而當前又不是歷史網頁的情況。

#010????if (is_reload && !main_frame->HasCurrentState()) {

#011??????// We cannot reload if we do not have any history state.??This happens, for

#012??????// example, when recovering from a crash.??Our workaround here is a bit of

#013??????// a hack since it means that reload after a crashed tab does not cause an

#014??????// end-to-end cache validation.

#015??????is_reload = false;

#016????}

#017?

?

下面設置緩沖策略。

#018????WebRequestCachePolicy cache_policy;

#019????if (is_reload) {

#020??????cache_policy = WebRequestReloadIgnoringCacheData;

#021????} else if (params.page_id != -1 || main_frame->GetInViewSourceMode()) {

#022??????cache_policy = WebRequestReturnCacheDataElseLoad;

#023????} else {

#024??????cache_policy = WebRequestUseProtocolCachePolicy;

#025????}

#026?

?

下面創建一個下載請求,并把相關參數設置到請求里面。

#027????scoped_ptr<WebRequest> request(WebRequest::Create(params.url));

#028????request->SetCachePolicy(cache_policy);

#029????request->SetExtraData(new RenderViewExtraRequestData(

#030????????params.page_id, params.transition, params.url));

#031?

?

設置WEBKIT的請求狀態。

#032????// If we are reloading, then WebKit will use the state of the current page.

#033????// Otherwise, we give it the state to navigate to.

#034????if (!is_reload)

#035??????request->SetHistoryState(params.state);

#036?

?

讓主WEB顯示框架去下載請求顯示。

#037????main_frame->LoadRequest(request.get());

#038??}

?

分析這個函數,就可以知道處理瀏覽消息的過程,下一次來分析WebFrame里的接口函數LoadRequest處理過程,到底它是怎么樣處理JavaScript腳本網頁下載的呢?


繼續上一次的分析,這里開始把連接址和其它相關的信息傳送frame_->loader()->load函數里面,那么在這個函數里面到底是怎么樣處理的呢,只有去分析它的代碼,我們才能找到它的答案,現在就來開始看吧,如下:

#001??void FrameLoader::load(const ResourceRequest& request)

#002??{

#003??????load(request, SubstituteData());

#004??}

在這個函數也只是一個中間者,它又調用函數load函數的重載函數來實現了。

#001??void FrameLoader::load(const ResourceRequest& request, const SubstituteData& substituteData)

#002??{

#003??????if (m_inStopAllLoaders)

#004??????????return;

#005?????????

#006??????// FIXME: is this the right place to reset loadType? Perhaps this should be done after loading is finished or aborted.

#007??????m_loadType = FrameLoadTypeStandard;

#008??????load(m_client->createDocumentLoader(request, substituteData).get());

#009??}

#010?

在這個函數里,第一個參數request是連接相關的信息,第二個參數substituteData是一些狀態數據。然后在第7行里設置加載的類型,第8行里調用WebFrameLoaderClient::createDocumentLoader函數來創建WebDocumentLoaderImpl對象,然后再通過get函數返回來,這樣就知道load函數又調用那個重載函數了,原來它是調用這個函數,如下:

#001??void FrameLoader::load(DocumentLoader* newDocumentLoader)

#002??{

#003??????ResourceRequest& r = newDocumentLoader->request();

#004??????addExtraFieldsToRequest(r, true, false);

#005??????FrameLoadType type;

#006?

#007??????if (shouldTreatURLAsSameAsCurrent(newDocumentLoader->originalRequest().url())) {

#008??????????r.setCachePolicy(ReloadIgnoringCacheData);

#009??????????type = FrameLoadTypeSame;

#010??????} else

#011??????????type = FrameLoadTypeStandard;

#012?

#013??????// Do not use original encoding override since it is not loaded by user

#014??????// selecting encoding.

#015??????if (m_documentLoader)

#016??????????newDocumentLoader->setOverrideEncoding(String());

#017?????

#018??????// When we loading alternate content for an unreachable URL that we're

#019??????// visiting in the b/f list, we treat it as a reload so the b/f list

#020??????// is appropriately maintained.

#021??????if (shouldReloadToHandleUnreachableURL(newDocumentLoader)) {

#022??????????ASSERT(type == FrameLoadTypeStandard);

#023??????????type = FrameLoadTypeReload;

#024??????}

#025?

#026??????load(newDocumentLoader, type, 0);

#027??}

上面只對newDocumentLoader做一些準備工作,并沒有真正地去加載任何東西,接著又調用函數:

void FrameLoader::load(DocumentLoader* loader, FrameLoadType type, PassRefPtr<FormState> formState)

在上面這個函數進行安全策略的處理,然后再經過N個函數處理之后,就調用下面的函數:

void FrameLoader::continueLoadAfterWillSubmitForm(PolicyAction)

在這個函數開始使用類DocumentLoader來設置下載請求,主要通過函數

bool DocumentLoader::startLoadingMainResource(unsigned long identifier)

來實現的,緊跟后面調用加載函數:

bool MainResourceLoader::load(const ResourceRequest& r, const SubstituteData&??substituteData)

在這個函數里又開始分為兩種情況處理,一種是延進加載數據,一種是立即加載數據,下面主要介紹立即加載數據函數:

bool MainResourceLoader::loadNow(ResourceRequest& r)

在類MainResourceLoader是主要資源下載的管理類,loadNow函數是把資源請求ResourceRequest變成一個IPC消息又發送給資源下載進程去處理。它的簡略代碼如下:

#001??bool MainResourceLoader::loadNow(ResourceRequest& r)

#002??{

......

#011??????willSendRequest(r, ResourceResponse());

#012?

......

?

#015??????if (!frameLoader())

#016??????????return false;

#017?????

......

#023?

#024??????if (m_substituteData.isValid())

#025??????????handleDataLoadSoon(r);

#026??????else if (shouldLoadEmpty || frameLoader()->representationExistsForURLScheme(url.protocol()))

#027??????????handleEmptyLoad(url, !shouldLoadEmpty);

#028??????else

#029??????????m_handle = ResourceHandle::create(r, this, m_frame.get(), false, true, true);

#030?

#031??????return false;

#032??}

在這個函數的第29行里,就會通過ResourceHandle::create函數創建一個資源消息,并把這個消息發送出去,到底它是怎么樣實現的呢?下一次再來分析它。





上一次說到類RenderThread和類RenderView把消息處理,那么這兩個類是怎么樣處理消息的呢?又是怎么樣處理瀏覽的消息呢?現在就帶著這兩個問題去分析它的源碼,理解它處理消息的方法。類RenderThread處理消息的代碼如下:

#001??void RenderThread::OnMessageReceived(const IPC::Message& msg) {

#002????// NOTE: We could subclass router_ to intercept OnControlMessageReceived, but

#003????// it seems simpler to just process any control messages that we care about

#004????// up-front and then send the rest of the messages onto router_.

#005?

?

下面判斷是控制消息,如果是控制消息就在本類里處理,否則就分發到別的地方處理,主要是轉到類RenderView處理。

#006????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#007??????IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)

#008????????IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)

#009????????IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)

#010????????IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)

#011????????IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)

#012????????IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,

#013???????????????????????????OnGetCacheResourceStats)

#014????????// send the rest to the router

#015????????IPC_MESSAGE_UNHANDLED(router_.OnMessageReceived(msg))

#016??????IPC_END_MESSAGE_MAP()

#017????} else {

?

這里是分發消息到別的地方處理。

#018??????router_.OnMessageReceived(msg);

#019????}

#020??}

?

在瀏覽器里,消息分為兩大類:控制消息和路由消息。像使用IPC_MESSAGE_CONTROL宏定義的消息,就是控制消息;使用IPC_MESSAGE_ROUTED宏定義的消息,就是路由消息。

路由消息分發是由類MessageRouter來負責的,主要處理的代碼如下:

#001?

#002??void MessageRouter::OnMessageReceived(const IPC::Message& msg) {

#003????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#004??????OnControlMessageReceived(msg);

#005????} else {

#006??????RouteMessage(msg);

#007????}

#008??}

在這里又分為MSG_ROUTING_CONTROL消息和其它路由消息,再一次通過函數RouteMessage分發之后,如下:

#001??bool MessageRouter::RouteMessage(const IPC::Message& msg) {

#002????IPC::Channel::Listener* listener = routes_.Lookup(msg.routing_id());

#003????if (!listener)

#004??????return false;

#005?

#006????listener->OnMessageReceived(msg);

#007????return true;

#008??}

上面這個函數里又把消息通過發送到listener里去,其實listener是根據消息的目標routing_id來選擇的,那么就是說它是選擇發送到不同的窗口里去,因為每個TAB一個窗口。消息經過這樣的處理之后,就到達了終點地---?RenderView::OnMessageReceived函數。下一次再來分析RenderView::OnMessageReceived函數的代碼和后繼處理。


上一次說到消息轉發,并分析了RenderThread類里處理消息的函數,其實大部份的消息都是在RenderView類里的OnMessageReceived函數處理,比如瀏覽的消息也是在這里處理。它的代碼如下:

#001??void RenderView::OnMessageReceived(const IPC::Message& message) {

#002????// Let the resource dispatcher intercept resource messages first.

?

如果是資源消息,就直接分發去處理,以便提高效率。

#003????if (resource_dispatcher_->OnMessageReceived(message))

#004??????return;

?

下面開始處理RenderView類里所有的消息。

#005????IPC_BEGIN_MESSAGE_MAP(RenderView, message)

#006??????IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)

#007??????IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)

#008??????IPC_MESSAGE_HANDLER(ViewMsg_GetPrintedPagesCount, OnGetPrintedPagesCount)

#009??????IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)

#010??????IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)

#011??????IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)

#012??????IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)

#013??????IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)

#014??????IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)

#015??????IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)

#016??????IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)

#017??????IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)

#018??????IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)

#019??????IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)

#020??????IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)

#021??????IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)

#022??????IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)

#023??????IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)

#024??????IPC_MESSAGE_HANDLER(ViewMsg_AlterTextSize, OnAlterTextSize)

#025??????IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)

#026??????IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement)

#027??????IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole)

#028??????IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)

#029??????IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)

#030??????IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)

#031??????IPC_MESSAGE_HANDLER(ViewMsg_DebugAttach, OnDebugAttach)

#032??????IPC_MESSAGE_HANDLER(ViewMsg_DebugDetach, OnDebugDetach)

#033??????IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)

#034??????IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)

#035??????IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)

#036??????IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)

#037??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)

#038??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)

#039??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)

#040??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)

#041??????IPC_MESSAGE_HANDLER(ViewMsg_AllowDomAutomationBindings,

#042?????????????????????????OnAllowDomAutomationBindings)

#043??????IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)

#044??????IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)

#045??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved, OnDragSourceEndedOrMoved)

#046??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,

#047?????????????????????????OnDragSourceSystemDragEnded)

#048??????IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)

#049??????IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)

#050??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)

#051??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)

#052??????IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)

#053??????IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)

#054??????IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)

#055??????IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)

#056??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,

#057?????????????????????????OnUpdateBackForwardListCount)

#058?????IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,

#059?????????????????????????OnGetAllSavableResourceLinksForCurrentPage)

#060?????IPC_MESSAGE_HANDLER(ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,

#061?????????????????????????OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)

#062??????IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)

#063??????IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)

#064??????IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)

#065??????IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)

#066??#ifdef CHROME_PERSONALIZATION

#067??????IPC_MESSAGE_HANDLER(ViewMsg_PersonalizationEvent, OnPersonalizationEvent)

#068??#endif

#069??????IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,

#070??????????????????????????OnMessageFromExternalHost)

?

這里對于沒有處理的消息進行提示。

#071??????// Have the super handle all other messages.

#072??????IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))

#073????IPC_END_MESSAGE_MAP()

#074??}

?

從上面這個函數可以看到,它的消息處理是非常多的,下面來分析一個瀏覽網絡連接的消息,它就是ViewMsg_Navigate,可以看到這個消息后面響應函數是OnNavigate,也就是說,當你輸入網絡地址之后按回車,就會通過上說過的IPC機制把消息發送到這里,接著來看這個函數OnNavigate的代碼,如下:

#001??void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {

?

判斷窗口是否關閉,如果關閉就不用去打開連接地址了。

#002????if (!webview())

#003??????return;

#004?

?

處理一些about的連接處理,比如about:crash。

#005????AboutHandler::MaybeHandle(params.url);

#006?

?

保存是否重新加載網頁。

#007????bool is_reload = params.reload;

#008?

?

獲取WEB的顯示框架。

#009????WebFrame* main_frame = webview()->GetMainFrame();

?

判斷當是重新加載時,而當前又不是歷史網頁的情況。

#010????if (is_reload && !main_frame->HasCurrentState()) {

#011??????// We cannot reload if we do not have any history state.??This happens, for

#012??????// example, when recovering from a crash.??Our workaround here is a bit of

#013??????// a hack since it means that reload after a crashed tab does not cause an

#014??????// end-to-end cache validation.

#015??????is_reload = false;

#016????}

#017?

?

下面設置緩沖策略。

#018????WebRequestCachePolicy cache_policy;

#019????if (is_reload) {

#020??????cache_policy = WebRequestReloadIgnoringCacheData;

#021????} else if (params.page_id != -1 || main_frame->GetInViewSourceMode()) {

#022??????cache_policy = WebRequestReturnCacheDataElseLoad;

#023????} else {

#024??????cache_policy = WebRequestUseProtocolCachePolicy;

#025????}

#026?

?

下面創建一個下載請求,并把相關參數設置到請求里面。

#027????scoped_ptr<WebRequest> request(WebRequest::Create(params.url));

#028????request->SetCachePolicy(cache_policy);

#029????request->SetExtraData(new RenderViewExtraRequestData(

#030????????params.page_id, params.transition, params.url));

#031?

?

設置WEBKIT的請求狀態。

#032????// If we are reloading, then WebKit will use the state of the current page.

#033????// Otherwise, we give it the state to navigate to.

#034????if (!is_reload)

#035??????request->SetHistoryState(params.state);

#036?

?

讓主WEB顯示框架去下載請求顯示。

#037????main_frame->LoadRequest(request.get());

#038??}

?

分析這個函數,就可以知道處理瀏覽消息的過程,下一次來分析WebFrame里的接口函數LoadRequest處理過程,到底它是怎么樣處理JavaScript腳本網頁下載的呢?


上一次說到需要把顯示的網絡連接地址變成一個資源的消息發送出去,它是通過函數ResourceHandle::create來實現的,但這個函數到底是怎么樣實現的呢?現在就分析它的實現代碼,了解它怎么樣把資源變換成消息,并且通過IPC機制把消息發送到資源下載進程去。數ResourceHandle::create的代碼如下:

#001??PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request,

#002???????????????????????????????????????????????????ResourceHandleClient* client,

#003???????????????????????????????????????????????????Frame* deprecated,

#004???????????????????????????????????????????????????bool defersLoading,

#005???????????????????????????????????????????????????bool shouldContentSniff,

#006???????????????????????????????????????????????????bool mightDownloadFromHandle) {

上面的參數request是把所有請求網絡連接地址信息傳進來了。

?

#007????RefPtr<ResourceHandle> newHandle(

#008????????new ResourceHandle(request, client, defersLoading, shouldContentSniff,

#009??????????????????????????mightDownloadFromHandle));

這里創建資源類ResourceHandle對象,通過它來生成一個消息發送出去。

?

#010?

#011????if (newHandle->start(NULL))

#012??????return newHandle.release();

上面的代碼里,調用函數start來處理資源請求下載。

?

#013?

#014????return NULL;

#015??}

?

在這個函數里調用newHandle->start函數來處理,其實它是調用下面的函數來工作的:

bool ResourceHandle::start(Frame* deprecated) {

??return d->Start(NULL);

}

那么這里的d實例是什么呢?可以通過ResourceHandle的構造函數來看到它的類,如下:

ResourceHandle::ResourceHandle(const ResourceRequest& request,

???????????????????????????????ResourceHandleClient* client,

???????????????????????????????bool defersLoading,

???????????????????????????????bool shouldContentSniff,

???????????????????????????????bool mightDownloadFromHandle)

#pragma warning(suppress: 4355)??// it's okay to pass |this| here!

??????:?d(new ResourceHandleInternal(this, request, client))?{

??// TODO(darin): figure out what to do with the two bool params

}???????????????

可以看到d是類ResourceHandleInternal的實例,這就是說調用d->Start函數,其實就是調用下面的函數:

#001??bool ResourceHandleInternal::Start(

#002??????ResourceLoaderBridge::SyncLoadResponse* sync_load_response) {

#003????DCHECK(!bridge_.get());

#004?

#005????// The WebFrame is the Frame's FrameWinClient

#006????WebFrameImpl* webframe =

#007????????request_.frame() ? WebFrameImpl::FromFrame(request_.frame()) : NULL;

......

#154?

#155????if (sync_load_response) {

#156??????bridge_->SyncLoad(sync_load_response);

#157??????return true;

#158????}

#159?

?

通過上面的處理,然后就調用橋連接成員bridge_來創建消息。

#160????bool rv = bridge_->Start(this);

#161????if (rv) {

#162??????pending_ = true;

#163??????job_->ref();??// to be released when we get a OnCompletedRequest.

#164????} else {

#165??????bridge_.reset();

#166????}

#167?

#168????return rv;

#169??}

在這里使用一個設計模式,叫橋連接模式。函數bridge_->Start的代碼如下:

// Writes a footer on the message and sends it

bool IPCResourceLoaderBridge::Start(Peer* peer) {

??if (request_id_ != -1) {

????NOTREACHED() << "Starting a request twice";

????return false;

??}

?

??RESOURCE_LOG("Starting request for " << url_);

?

?

保存當前接收的連接端點。

??peer_ = peer;

?

?

生成請求ID,以便返回數據時可以找到相應的顯示進程和窗口。

??// generate the request ID, and append it to the message

??request_id_ = dispatcher_->AddPendingRequest(peer_, request_.resource_type,

??????????????????????????????????????????????request_.mixed_content);

?

?

找到IPC的消息發送對象,然后創建ViewHostMsg_RequestResource消息并發送出去。

??IPC::Message::Sender* sender = dispatcher_->message_sender();

??bool ret = false;

??if (sender)

????ret = sender->Send(new ViewHostMsg_RequestResource(MSG_ROUTING_NONE,

??????????????????????????????????????????????????????request_id_,

??????????????????????????????????????????????????????request_));

??return ret;

}

?

通過上面漫長的分析,總算搞清楚了這個過程:

從界面開始輸入URL地址,然后界面把URL發送到渲染進程,渲染進程再進行處理,把這個URL連接請求再次發送到資源下載進程去處理。串起來是一個極其簡單的過程,但在這個瀏覽器里比較復雜的,因為它是多進程的瀏覽器,進程之間相互消息傳送,就比其它瀏覽器復雜,并且它還有很多安全策略的使用和優化處理,導致這個處理過程是比較復雜的。

OK,資源下載請求消息已經發送出去,那么這個消息又往何處而去呢?又怎么樣通過網絡連接下載回來呢?欲知后事如何,請繼續看下一篇!



from:?

上一次說到類RenderThread和類RenderView把消息處理,那么這兩個類是怎么樣處理消息的呢?又是怎么樣處理瀏覽的消息呢?現在就帶著這兩個問題去分析它的源碼,理解它處理消息的方法。類RenderThread處理消息的代碼如下:

#001??void RenderThread::OnMessageReceived(const IPC::Message& msg) {

#002????// NOTE: We could subclass router_ to intercept OnControlMessageReceived, but

#003????// it seems simpler to just process any control messages that we care about

#004????// up-front and then send the rest of the messages onto router_.

#005?

?

下面判斷是控制消息,如果是控制消息就在本類里處理,否則就分發到別的地方處理,主要是轉到類RenderView處理。

#006????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#007??????IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)

#008????????IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)

#009????????IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)

#010????????IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)

#011????????IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)

#012????????IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,

#013???????????????????????????OnGetCacheResourceStats)

#014????????// send the rest to the router

#015????????IPC_MESSAGE_UNHANDLED(router_.OnMessageReceived(msg))

#016??????IPC_END_MESSAGE_MAP()

#017????} else {

?

這里是分發消息到別的地方處理。

#018??????router_.OnMessageReceived(msg);

#019????}

#020??}

?

在瀏覽器里,消息分為兩大類:控制消息和路由消息。像使用IPC_MESSAGE_CONTROL宏定義的消息,就是控制消息;使用IPC_MESSAGE_ROUTED宏定義的消息,就是路由消息。

路由消息分發是由類MessageRouter來負責的,主要處理的代碼如下:

#001?

#002??void MessageRouter::OnMessageReceived(const IPC::Message& msg) {

#003????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#004??????OnControlMessageReceived(msg);

#005????} else {

#006??????RouteMessage(msg);

#007????}

#008??}

在這里又分為MSG_ROUTING_CONTROL消息和其它路由消息,再一次通過函數RouteMessage分發之后,如下:

#001??bool MessageRouter::RouteMessage(const IPC::Message& msg) {

#002????IPC::Channel::Listener* listener = routes_.Lookup(msg.routing_id());

#003????if (!listener)

#004??????return false;

#005?

#006????listener->OnMessageReceived(msg);

#007????return true;

#008??}

上面這個函數里又把消息通過發送到listener里去,其實listener是根據消息的目標routing_id來選擇的,那么就是說它是選擇發送到不同的窗口里去,因為每個TAB一個窗口。消息經過這樣的處理之后,就到達了終點地---?RenderView::OnMessageReceived函數。下一次再來分析RenderView::OnMessageReceived函數的代碼和后繼處理。


上一次說到消息轉發,并分析了RenderThread類里處理消息的函數,其實大部份的消息都是在RenderView類里的OnMessageReceived函數處理,比如瀏覽的消息也是在這里處理。它的代碼如下:

#001??void RenderView::OnMessageReceived(const IPC::Message& message) {

#002????// Let the resource dispatcher intercept resource messages first.

?

如果是資源消息,就直接分發去處理,以便提高效率。

#003????if (resource_dispatcher_->OnMessageReceived(message))

#004??????return;

?

下面開始處理RenderView類里所有的消息。

#005????IPC_BEGIN_MESSAGE_MAP(RenderView, message)

#006??????IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)

#007??????IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)

#008??????IPC_MESSAGE_HANDLER(ViewMsg_GetPrintedPagesCount, OnGetPrintedPagesCount)

#009??????IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)

#010??????IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)

#011??????IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)

#012??????IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)

#013??????IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)

#014??????IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)

#015??????IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)

#016??????IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)

#017??????IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)

#018??????IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)

#019??????IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)

#020??????IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)

#021??????IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)

#022??????IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)

#023??????IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)

#024??????IPC_MESSAGE_HANDLER(ViewMsg_AlterTextSize, OnAlterTextSize)

#025??????IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)

#026??????IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement)

#027??????IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole)

#028??????IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)

#029??????IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)

#030??????IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)

#031??????IPC_MESSAGE_HANDLER(ViewMsg_DebugAttach, OnDebugAttach)

#032??????IPC_MESSAGE_HANDLER(ViewMsg_DebugDetach, OnDebugDetach)

#033??????IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)

#034??????IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)

#035??????IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)

#036??????IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)

#037??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)

#038??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)

#039??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)

#040??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)

#041??????IPC_MESSAGE_HANDLER(ViewMsg_AllowDomAutomationBindings,

#042?????????????????????????OnAllowDomAutomationBindings)

#043??????IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)

#044??????IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)

#045??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved, OnDragSourceEndedOrMoved)

#046??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,

#047?????????????????????????OnDragSourceSystemDragEnded)

#048??????IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)

#049??????IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)

#050??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)

#051??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)

#052??????IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)

#053??????IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)

#054??????IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)

#055??????IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)

#056??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,

#057?????????????????????????OnUpdateBackForwardListCount)

#058?????IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,

#059?????????????????????????OnGetAllSavableResourceLinksForCurrentPage)

#060?????IPC_MESSAGE_HANDLER(ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,

#061?????????????????????????OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)

#062??????IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)

#063??????IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)

#064??????IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)

#065??????IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)

#066??#ifdef CHROME_PERSONALIZATION

#067??????IPC_MESSAGE_HANDLER(ViewMsg_PersonalizationEvent, OnPersonalizationEvent)

#068??#endif

#069??????IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,

#070??????????????????????????OnMessageFromExternalHost)

?

這里對于沒有處理的消息進行提示。

#071??????// Have the super handle all other messages.

#072??????IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))

#073????IPC_END_MESSAGE_MAP()

#074??}

?

從上面這個函數可以看到,它的消息處理是非常多的,下面來分析一個瀏覽網絡連接的消息,它就是ViewMsg_Navigate,可以看到這個消息后面響應函數是OnNavigate,也就是說,當你輸入網絡地址之后按回車,就會通過上說過的IPC機制把消息發送到這里,接著來看這個函數OnNavigate的代碼,如下:

#001??void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {

?

判斷窗口是否關閉,如果關閉就不用去打開連接地址了。

#002????if (!webview())

#003??????return;

#004?

?

處理一些about的連接處理,比如about:crash。

#005????AboutHandler::MaybeHandle(params.url);

#006?

?

保存是否重新加載網頁。

#007????bool is_reload = params.reload;

#008?

?

獲取WEB的顯示框架。

#009????WebFrame* main_frame = webview()->GetMainFrame();

?

判斷當是重新加載時,而當前又不是歷史網頁的情況。

#010????if (is_reload && !main_frame->HasCurrentState()) {

#011??????// We cannot reload if we do not have any history state.??This happens, for

#012??????// example, when recovering from a crash.??Our workaround here is a bit of

#013??????// a hack since it means that reload after a crashed tab does not cause an

#014??????// end-to-end cache validation.

#015??????is_reload = false;

#016????}

#017?

?

下面設置緩沖策略。

#018????WebRequestCachePolicy cache_policy;

#019????if (is_reload) {

#020??????cache_policy = WebRequestReloadIgnoringCacheData;

#021????} else if (params.page_id != -1 || main_frame->GetInViewSourceMode()) {

#022??????cache_policy = WebRequestReturnCacheDataElseLoad;

#023????} else {

#024??????cache_policy = WebRequestUseProtocolCachePolicy;

#025????}

#026?

?

下面創建一個下載請求,并把相關參數設置到請求里面。

#027????scoped_ptr<WebRequest> request(WebRequest::Create(params.url));

#028????request->SetCachePolicy(cache_policy);

#029????request->SetExtraData(new RenderViewExtraRequestData(

#030????????params.page_id, params.transition, params.url));

#031?

?

設置WEBKIT的請求狀態。

#032????// If we are reloading, then WebKit will use the state of the current page.

#033????// Otherwise, we give it the state to navigate to.

#034????if (!is_reload)

#035??????request->SetHistoryState(params.state);

#036?

?

讓主WEB顯示框架去下載請求顯示。

#037????main_frame->LoadRequest(request.get());

#038??}

?

分析這個函數,就可以知道處理瀏覽消息的過程,下一次來分析WebFrame里的接口函數LoadRequest處理過程,到底它是怎么樣處理JavaScript腳本網頁下載的呢?


http://blog.csdn.net/caimouse/article/details/3071368

上一次說到類RenderThread和類RenderView把消息處理,那么這兩個類是怎么樣處理消息的呢?又是怎么樣處理瀏覽的消息呢?現在就帶著這兩個問題去分析它的源碼,理解它處理消息的方法。類RenderThread處理消息的代碼如下:

#001??void RenderThread::OnMessageReceived(const IPC::Message& msg) {

#002????// NOTE: We could subclass router_ to intercept OnControlMessageReceived, but

#003????// it seems simpler to just process any control messages that we care about

#004????// up-front and then send the rest of the messages onto router_.

#005?

?

下面判斷是控制消息,如果是控制消息就在本類里處理,否則就分發到別的地方處理,主要是轉到類RenderView處理。

#006????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#007??????IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)

#008????????IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)

#009????????IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)

#010????????IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)

#011????????IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)

#012????????IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,

#013???????????????????????????OnGetCacheResourceStats)

#014????????// send the rest to the router

#015????????IPC_MESSAGE_UNHANDLED(router_.OnMessageReceived(msg))

#016??????IPC_END_MESSAGE_MAP()

#017????} else {

?

這里是分發消息到別的地方處理。

#018??????router_.OnMessageReceived(msg);

#019????}

#020??}

?

在瀏覽器里,消息分為兩大類:控制消息和路由消息。像使用IPC_MESSAGE_CONTROL宏定義的消息,就是控制消息;使用IPC_MESSAGE_ROUTED宏定義的消息,就是路由消息。

路由消息分發是由類MessageRouter來負責的,主要處理的代碼如下:

#001?

#002??void MessageRouter::OnMessageReceived(const IPC::Message& msg) {

#003????if (msg.routing_id() == MSG_ROUTING_CONTROL) {

#004??????OnControlMessageReceived(msg);

#005????} else {

#006??????RouteMessage(msg);

#007????}

#008??}

在這里又分為MSG_ROUTING_CONTROL消息和其它路由消息,再一次通過函數RouteMessage分發之后,如下:

#001??bool MessageRouter::RouteMessage(const IPC::Message& msg) {

#002????IPC::Channel::Listener* listener = routes_.Lookup(msg.routing_id());

#003????if (!listener)

#004??????return false;

#005?

#006????listener->OnMessageReceived(msg);

#007????return true;

#008??}

上面這個函數里又把消息通過發送到listener里去,其實listener是根據消息的目標routing_id來選擇的,那么就是說它是選擇發送到不同的窗口里去,因為每個TAB一個窗口。消息經過這樣的處理之后,就到達了終點地---?RenderView::OnMessageReceived函數。下一次再來分析RenderView::OnMessageReceived函數的代碼和后繼處理。

上一次說到消息轉發,并分析了RenderThread類里處理消息的函數,其實大部份的消息都是在RenderView類里的OnMessageReceived函數處理,比如瀏覽的消息也是在這里處理。它的代碼如下:

#001??void RenderView::OnMessageReceived(const IPC::Message& message) {

#002????// Let the resource dispatcher intercept resource messages first.

?

如果是資源消息,就直接分發去處理,以便提高效率。

#003????if (resource_dispatcher_->OnMessageReceived(message))

#004??????return;

?

下面開始處理RenderView類里所有的消息。

#005????IPC_BEGIN_MESSAGE_MAP(RenderView, message)

#006??????IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)

#007??????IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)

#008??????IPC_MESSAGE_HANDLER(ViewMsg_GetPrintedPagesCount, OnGetPrintedPagesCount)

#009??????IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)

#010??????IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)

#011??????IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)

#012??????IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)

#013??????IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)

#014??????IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)

#015??????IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)

#016??????IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)

#017??????IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)

#018??????IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)

#019??????IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)

#020??????IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)

#021??????IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)

#022??????IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)

#023??????IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)

#024??????IPC_MESSAGE_HANDLER(ViewMsg_AlterTextSize, OnAlterTextSize)

#025??????IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)

#026??????IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement)

#027??????IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole)

#028??????IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)

#029??????IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)

#030??????IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)

#031??????IPC_MESSAGE_HANDLER(ViewMsg_DebugAttach, OnDebugAttach)

#032??????IPC_MESSAGE_HANDLER(ViewMsg_DebugDetach, OnDebugDetach)

#033??????IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)

#034??????IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)

#035??????IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)

#036??????IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)

#037??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)

#038??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)

#039??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)

#040??????IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)

#041??????IPC_MESSAGE_HANDLER(ViewMsg_AllowDomAutomationBindings,

#042?????????????????????????OnAllowDomAutomationBindings)

#043??????IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)

#044??????IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)

#045??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved, OnDragSourceEndedOrMoved)

#046??????IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,

#047?????????????????????????OnDragSourceSystemDragEnded)

#048??????IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)

#049??????IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)

#050??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)

#051??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)

#052??????IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)

#053??????IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)

#054??????IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)

#055??????IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)

#056??????IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,

#057?????????????????????????OnUpdateBackForwardListCount)

#058?????IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,

#059?????????????????????????OnGetAllSavableResourceLinksForCurrentPage)

#060?????IPC_MESSAGE_HANDLER(ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,

#061?????????????????????????OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)

#062??????IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)

#063??????IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)

#064??????IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)

#065??????IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)

#066??#ifdef CHROME_PERSONALIZATION

#067??????IPC_MESSAGE_HANDLER(ViewMsg_PersonalizationEvent, OnPersonalizationEvent)

#068??#endif

#069??????IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,

#070??????????????????????????OnMessageFromExternalHost)

?

這里對于沒有處理的消息進行提示。

#071??????// Have the super handle all other messages.

#072??????IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))

#073????IPC_END_MESSAGE_MAP()

#074??}

?

從上面這個函數可以看到,它的消息處理是非常多的,下面來分析一個瀏覽網絡連接的消息,它就是ViewMsg_Navigate,可以看到這個消息后面響應函數是OnNavigate,也就是說,當你輸入網絡地址之后按回車,就會通過上說過的IPC機制把消息發送到這里,接著來看這個函數OnNavigate的代碼,如下:

#001??void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {

?

判斷窗口是否關閉,如果關閉就不用去打開連接地址了。

#002????if (!webview())

#003??????return;

#004?

?

處理一些about的連接處理,比如about:crash

#005????AboutHandler::MaybeHandle(params.url);

#006?

?

保存是否重新加載網頁。

#007????bool is_reload = params.reload;

#008?

?

獲取WEB的顯示框架。

#009????WebFrame* main_frame = webview()->GetMainFrame();

?

判斷當是重新加載時,而當前又不是歷史網頁的情況。

#010????if (is_reload && !main_frame->HasCurrentState()) {

#011??????// We cannot reload if we do not have any history state.??This happens, for

#012??????// example, when recovering from a crash.??Our workaround here is a bit of

#013??????// a hack since it means that reload after a crashed tab does not cause an

#014??????// end-to-end cache validation.

#015??????is_reload = false;

#016????}

#017?

?

下面設置緩沖策略。

#018????WebRequestCachePolicy cache_policy;

#019????if (is_reload) {

#020??????cache_policy = WebRequestReloadIgnoringCacheData;

#021????} else if (params.page_id != -1 || main_frame->GetInViewSourceMode()) {

#022??????cache_policy = WebRequestReturnCacheDataElseLoad;

#023????} else {

#024??????cache_policy = WebRequestUseProtocolCachePolicy;

#025????}

#026?

?

下面創建一個下載請求,并把相關參數設置到請求里面。

#027????scoped_ptr<WebRequest> request(WebRequest::Create(params.url));

#028????request->SetCachePolicy(cache_policy);

#029????request->SetExtraData(new RenderViewExtraRequestData(

#030????????params.page_id, params.transition, params.url));

#031?

?

設置WEBKIT的請求狀態。

#032????// If we are reloading, then WebKit will use the state of the current page.

#033????// Otherwise, we give it the state to navigate to.

#034????if (!is_reload)

#035??????request->SetHistoryState(params.state);

#036?

?

讓主WEB顯示框架去下載請求顯示。

#037????main_frame->LoadRequest(request.get());

#038??}

?

分析這個函數,就可以知道處理瀏覽消息的過程,下一次來分析WebFrame里的接口函數LoadRequest處理過程,到底它是怎么樣處理JavaScript腳本網頁下載的呢?

總結

以上是生活随笔為你收集整理的谷歌chrome浏览器的源码分析(五)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 夜夜嗨一区| 2018狠狠干 | 一起艹在线观看 | 国产成人精品123区免费视频 | 日韩av在线天堂 | 男人的天堂一级片 | 国产黄视频在线观看 | 青青艹在线观看 | 我爱av好色 | 国产亚洲成av人片在线观看桃 | 久久毛片视频 | www欧美| 91在线看 | 日韩欧美一区二区三区视频 | 一区二区在线精品 | 欧美国产91 | 精品一区二区毛片 | 日日爽| 亚洲 在线 | 亚洲人视频在线观看 | 欧美人与禽性xxxxx杂性 | www.99视频 | 国产乱子伦精品无码专区 | 小俊大肉大捧一进一出好爽 | 青青艹在线观看 | 精品免费一区二区 | 久草电影在线 | 91精品国产综合久久久久 | 一区二区三区亚洲 | 五月婷六月| 色呦呦日韩精品 | 杏导航aⅴ福利网站 | 久操视频在线播放 | 永久在线免费观看 | 动漫美女放屁 | 91免费在线观看网站 | 中文字幕综合 | 国产精品七区 | 天天看夜夜 | 久久黄色网络 | 无码av免费精品一区二区三区 | 私人影院毛片 | 国产精品久久久久999 | 久久免费偷拍视频 | 国产欧美日韩成人 | 91视频在线免费观看 | 一级久久久久久 | 欧日韩在线视频 | 男女视频免费看 | 久久综合久久88 | 亚洲精久久 | 男女激情视频网站 | 人人玩人人干 | 91精品国产乱码久久久久久久久 | xxxx视频在线观看 | 午夜在线| 国产精品免费一区 | 91播放在线 | 中文字幕国产专区 | 国产美女流白浆 | 狠狠干狠狠插 | 亚洲精品视频二区 | 亚洲手机视频 | 国内福利视频 | 日本人极品人妖高潮 | 中文精品一区 | 四虎在线看片 | 樱花影院最新免费观看攻略 | 国产一久久 | 在线免费黄色网址 | 97人妻人人揉人人躁人人 | 无码gogo大胆啪啪艺术 | 久久国产精品综合 | 午夜资源 | 美女插插| 欧美热热 | 欧美一区二区三区成人片在线 | 欧美色成人 | 亚洲一级二级三级 | 美女毛片网站 | 在线观看国产黄色 | 一二区精品 | 懂色av懂色av粉嫩av分享吧 | xxxxx日韩| av成人精品 | 色哟哟在线播放 | 日本免费爱爱视频 | 人人妻人人澡人人爽人人dvd | 91精品小视频 | 国产又黄又粗又硬 | 成年人网站免费视频 | 在线观看日韩一区二区 | 国产九九久久 | 亚洲狠狠爱 | 白白色2012年最新视频 | 久久午夜夜伦鲁鲁片 | 亚洲一区二区色 | 欧美三级视频在线观看 | 日本中文字幕在线观看视频 |