zl程序教程

您现在的位置是:首页 >  工具

当前栏目

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

2023-09-14 09:16:25 时间
 

上一次说到消息转发,并分析了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脚本网页下载的呢?