Bug 1110624 - How does an iframe start on B2G
10 Feb 2015On B2G, an app is just an embedded iframe like this: <iframe src=... remote mozbrowser mozapp=...>. It is mysterious to me how does that HTML tag become a process and load the content. Because of bug 1110624, I had a chance to look into the sequence, and figured out how is that happened. Some classes are involved to load the things according to the special attributes. I drew a simplified classes diagram:

I don’t know how to express the sequence simply, so this’s like a stack and the indent (1 space) indicates the stack level.
iframe.src = ...
HTMLIFrameElement::SetAttr()
nsElementFrameLoaderOwner::LoadSrc()
nsElementFrameLoaderOwner::EnsureFrameLoader()
mFrameLoader = nsFrameLoader::Create()
nsFrameLoader::LoadFrame()
nsFrameLoader::LoadURI()
nsDocument::InitializeFrameLoader()
nsDocument::MaybeInitializeFinalizeFrameLoaders()
nsFrameLoader::ReallyStartLoading()
nsFrameLoader::ReallyStartLoadingInternal()
if (mRemoteFrame) {
mRemoteBrowser = ContentParent::CreateBrowserOrApp()
if (isBrowser) {
ContentParent::GetNewOrUsedBrowserProcess()
} else {
ContentParent::GetNewOrPreallocatedAppProcess()
}
ContentParent::AllocateTabId()
new TabParent()
ContentParent::SendPBrowserConstructor()
--- IPC ---
ContentChild::AllocPBrowserChild()
nsIContentChild::AllocPBrowserChild()
TabChild::Create()
if (sPreallocatedTab) {
sPreallocatedTab->SetTabId()
sPreallocatedTab->SetTabContext()
} else {
new TabChild()
}
ContentChild::RecvPBrowserConstructor()
nsFrameLoader::ShowRemoteFrame()
TabParent::Show()
PBrowserParent::SendShow()
--- IPC ---
TabChild::RecvShow()
TabChild::InitTabChildGlobal()
TabChild::RecvLoadRemoteScript("BrowserElementChild.js")
NotifyObservers("remote-browser-shown")
nsBrowserElement::InitBrowserElementAPI()
mBrowserElementAPI = do_CreateInstance("BrowserElementParent.js")
mBrowserElementAPI->SetFrameLoader()
mRemoteBrowser->LoadURL()
TabParent::LoadURL()
PBrowserParent::SendLoadURL()
--- IPC ---
TabChild::RecvLoadURL()
nsIWebNavigation::LoadURI()
nsDocShell::LoadURI()
} else { // !mRemoteFrame
nsDocShell::LoadURI()
}