Don't rely on guest_process_id for searching guest

This commit is contained in:
Cheng Zhao 2015-06-03 13:45:06 +08:00
parent 3ee054e316
commit 6dfa7b5383
3 changed files with 80 additions and 112 deletions

View file

@ -34,22 +34,33 @@ namespace {
// Next navigation should not restart renderer process.
bool g_suppress_renderer_process_restart = false;
struct FindByProcessId {
explicit FindByProcessId(int child_process_id)
: child_process_id_(child_process_id) {
}
bool operator() (NativeWindow* const window) {
content::WebContents* web_contents = window->GetWebContents();
if (!web_contents)
return false;
int id = window->GetWebContents()->GetRenderProcessHost()->GetID();
return id == child_process_id_;
}
int child_process_id_;
// Find out the owner of the child process according to child_process_id.
enum ChildProcessOwner {
OWNER_NATIVE_WINDOW,
OWNER_GUEST_WEB_CONTENTS,
OWNER_NONE, // it might be devtools though.
};
ChildProcessOwner GetChildProcessOwner(int process_id,
NativeWindow** window,
WebViewManager::WebViewInfo* info) {
// First search for NativeWindow.
for (auto native_window : *WindowList::GetInstance()) {
content::WebContents* web_contents = native_window->GetWebContents();
if (web_contents &&
process_id == web_contents->GetRenderProcessHost()->GetID()) {
*window = native_window;
return OWNER_NATIVE_WINDOW;
}
}
// Then search for guest WebContents.
auto process = content::RenderProcessHost::FromID(process_id);
if (WebViewManager::GetInfoForProcess(process, info)) {
return OWNER_GUEST_WEB_CONTENTS;
}
return OWNER_NONE;
}
} // namespace
@ -82,8 +93,7 @@ content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
}
void AtomBrowserClient::OverrideWebkitPrefs(
content::RenderViewHost* render_view_host,
content::WebPreferences* prefs) {
content::RenderViewHost* host, content::WebPreferences* prefs) {
prefs->javascript_enabled = true;
prefs->web_security_enabled = true;
prefs->javascript_can_open_windows_automatically = true;
@ -102,17 +112,15 @@ void AtomBrowserClient::OverrideWebkitPrefs(
prefs->allow_running_insecure_content = false;
// Turn off web security for devtools.
auto web_contents = content::WebContents::FromRenderViewHost(
render_view_host);
auto web_contents = content::WebContents::FromRenderViewHost(host);
if (web_contents && web_contents->GetURL().SchemeIs("chrome-devtools")) {
prefs->web_security_enabled = false;
return;
}
// Custom preferences of guest page.
auto process = render_view_host->GetProcess();
WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForProcess(process, &info)) {
if (WebViewManager::GetInfoForWebContents(web_contents, &info)) {
prefs->web_security_enabled = !info.disable_web_security;
return;
}
@ -136,73 +144,47 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
return;
}
// Restart renderer process for all navigations except "javacript:" scheme.
if (url.SchemeIs(url::kJavaScriptScheme))
return;
if (current_instance->HasProcess())
dying_render_process_ = current_instance->GetProcess();
if (!url.SchemeIs(url::kJavaScriptScheme)) {
// Restart renderer process for all navigations except javacript: scheme.
*new_instance = content::SiteInstance::CreateForURL(browser_context, url);
}
*new_instance = content::SiteInstance::CreateForURL(browser_context, url);
}
void AtomBrowserClient::AppendExtraCommandLineSwitches(
base::CommandLine* command_line,
int child_process_id) {
int process_id) {
std::string process_type = command_line->GetSwitchValueASCII("type");
if (process_type != "renderer")
return;
WindowList* list = WindowList::GetInstance();
NativeWindow* window = nullptr;
NativeWindow* window;
WebViewManager::WebViewInfo info;
ChildProcessOwner owner = GetChildProcessOwner(process_id, &window, &info);
// Find the owner of this child process.
WindowList::const_iterator iter = std::find_if(
list->begin(), list->end(), FindByProcessId(child_process_id));
if (iter != list->end())
window = *iter;
// If the render process is a newly started one, which means the window still
// If the render process is a newly started one, which means the owner still
// uses the old going-to-be-swapped render process, then we try to find the
// window from the swapped render process.
if (!window && dying_render_process_) {
int dying_process_id = dying_render_process_->GetID();
WindowList::const_iterator iter = std::find_if(
list->begin(), list->end(), FindByProcessId(dying_process_id));
if (iter != list->end()) {
window = *iter;
child_process_id = dying_process_id;
} else {
// It appears that the dying process doesn't belong to a BrowserWindow,
// then it might be a guest process, if it is we should update its
// process ID in the WebViewManager.
auto child_process = content::RenderProcessHost::FromID(child_process_id);
// Update the process ID in webview guests.
WebViewManager::UpdateGuestProcessID(dying_render_process_,
child_process);
}
// owner from the swapped render process.
if (owner == OWNER_NONE) {
process_id = dying_render_process_->GetID();
owner = GetChildProcessOwner(process_id, &window, &info);
}
if (window) {
window->AppendExtraCommandLineSwitches(command_line, child_process_id);
} else {
// Append commnad line arguments for guest web view.
auto child_process = content::RenderProcessHost::FromID(child_process_id);
WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForProcess(child_process, &info)) {
command_line->AppendSwitchASCII(
switches::kGuestInstanceID,
base::IntToString(info.guest_instance_id));
command_line->AppendSwitchASCII(
switches::kNodeIntegration,
info.node_integration ? "true" : "false");
if (info.plugins)
command_line->AppendSwitch(switches::kEnablePlugins);
if (!info.preload_script.empty())
command_line->AppendSwitchPath(
switches::kPreloadScript,
info.preload_script);
}
if (owner == OWNER_NATIVE_WINDOW) {
window->AppendExtraCommandLineSwitches(command_line, process_id);
} else if (owner == OWNER_GUEST_WEB_CONTENTS) {
command_line->AppendSwitchASCII(
switches::kGuestInstanceID, base::IntToString(info.guest_instance_id));
command_line->AppendSwitchASCII(
switches::kNodeIntegration, info.node_integration ? "true" : "false");
if (info.plugins)
command_line->AppendSwitch(switches::kEnablePlugins);
if (!info.preload_script.empty())
command_line->AppendSwitchPath(
switches::kPreloadScript, info.preload_script);
}
dying_render_process_ = nullptr;