Don't rely on process_id to search for NativeWindow

This commit is contained in:
Cheng Zhao 2015-06-03 14:08:56 +08:00
parent 6dfa7b5383
commit d4be2da70e
7 changed files with 36 additions and 65 deletions

View file

@ -85,7 +85,7 @@ v8::Persistent<v8::ObjectTemplate> template_;
// Get the window that has the |guest| embedded. // Get the window that has the |guest| embedded.
NativeWindow* GetWindowFromGuest(const content::WebContents* guest) { NativeWindow* GetWindowFromGuest(const content::WebContents* guest) {
WebViewManager::WebViewInfo info; WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForProcess(guest->GetRenderProcessHost(), &info)) if (WebViewManager::GetInfoForWebContents(guest, &info))
return NativeWindow::FromWebContents(info.embedder); return NativeWindow::FromWebContents(info.embedder);
else else
return nullptr; return nullptr;

View file

@ -31,33 +31,38 @@ namespace atom {
namespace { namespace {
// The default routing id of WebContents, since in Electron a WebContents
// always owns its own RenderProcessHost, this ID is same for every WebContents.
int kDefaultRoutingID = 2;
// Next navigation should not restart renderer process. // Next navigation should not restart renderer process.
bool g_suppress_renderer_process_restart = false; bool g_suppress_renderer_process_restart = false;
// Returns the WebContents from process.
inline content::WebContents* GetWebContentsFromProcess(int process_id) {
return content::WebContents::FromRenderViewHost(
content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
}
// Find out the owner of the child process according to child_process_id. // Find out the owner of the child process according to child_process_id.
enum ChildProcessOwner { enum WebContentsOwner {
OWNER_NATIVE_WINDOW, OWNER_NATIVE_WINDOW,
OWNER_GUEST_WEB_CONTENTS, OWNER_GUEST_WEB_CONTENTS,
OWNER_NONE, // it might be devtools though. OWNER_NONE, // it might be devtools though.
}; };
ChildProcessOwner GetChildProcessOwner(int process_id, WebContentsOwner GetWebContentsOwner(content::WebContents* web_contents,
NativeWindow** window, NativeWindow** window,
WebViewManager::WebViewInfo* info) { WebViewManager::WebViewInfo* info) {
// First search for NativeWindow. // First search for NativeWindow.
for (auto native_window : *WindowList::GetInstance()) { for (auto native_window : *WindowList::GetInstance())
content::WebContents* web_contents = native_window->GetWebContents(); if (web_contents == native_window->GetWebContents()) {
if (web_contents &&
process_id == web_contents->GetRenderProcessHost()->GetID()) {
*window = native_window; *window = native_window;
return OWNER_NATIVE_WINDOW; return OWNER_NATIVE_WINDOW;
} }
}
// Then search for guest WebContents. // Then search for guest WebContents.
auto process = content::RenderProcessHost::FromID(process_id); if (WebViewManager::GetInfoForWebContents(web_contents, info))
if (WebViewManager::GetInfoForProcess(process, info)) {
return OWNER_GUEST_WEB_CONTENTS; return OWNER_GUEST_WEB_CONTENTS;
}
return OWNER_NONE; return OWNER_NONE;
} }
@ -69,8 +74,7 @@ void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
g_suppress_renderer_process_restart = true; g_suppress_renderer_process_restart = true;
} }
AtomBrowserClient::AtomBrowserClient() AtomBrowserClient::AtomBrowserClient() {
: dying_render_process_(nullptr) {
} }
AtomBrowserClient::~AtomBrowserClient() { AtomBrowserClient::~AtomBrowserClient() {
@ -148,9 +152,6 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
if (url.SchemeIs(url::kJavaScriptScheme)) if (url.SchemeIs(url::kJavaScriptScheme))
return; return;
if (current_instance->HasProcess())
dying_render_process_ = current_instance->GetProcess();
*new_instance = content::SiteInstance::CreateForURL(browser_context, url); *new_instance = content::SiteInstance::CreateForURL(browser_context, url);
} }
@ -161,20 +162,16 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
if (process_type != "renderer") if (process_type != "renderer")
return; return;
auto web_contents = GetWebContentsFromProcess(process_id);
if (!web_contents)
return;
NativeWindow* window; NativeWindow* window;
WebViewManager::WebViewInfo info; WebViewManager::WebViewInfo info;
ChildProcessOwner owner = GetChildProcessOwner(process_id, &window, &info); WebContentsOwner owner = GetWebContentsOwner(web_contents, &window, &info);
// 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
// owner from the swapped render process.
if (owner == OWNER_NONE) {
process_id = dying_render_process_->GetID();
owner = GetChildProcessOwner(process_id, &window, &info);
}
if (owner == OWNER_NATIVE_WINDOW) { if (owner == OWNER_NATIVE_WINDOW) {
window->AppendExtraCommandLineSwitches(command_line, process_id); window->AppendExtraCommandLineSwitches(command_line);
} else if (owner == OWNER_GUEST_WEB_CONTENTS) { } else if (owner == OWNER_GUEST_WEB_CONTENTS) {
command_line->AppendSwitchASCII( command_line->AppendSwitchASCII(
switches::kGuestInstanceID, base::IntToString(info.guest_instance_id)); switches::kGuestInstanceID, base::IntToString(info.guest_instance_id));
@ -186,8 +183,6 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
command_line->AppendSwitchPath( command_line->AppendSwitchPath(
switches::kPreloadScript, info.preload_script); switches::kPreloadScript, info.preload_script);
} }
dying_render_process_ = nullptr;
} }
void AtomBrowserClient::DidCreatePpapiPlugin( void AtomBrowserClient::DidCreatePpapiPlugin(

View file

@ -46,9 +46,6 @@ class AtomBrowserClient : public brightray::BrowserClient {
brightray::BrowserMainParts* OverrideCreateBrowserMainParts( brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) override; const content::MainFunctionParams&) override;
// The render process which would be swapped out soon.
content::RenderProcessHost* dying_render_process_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient); DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
}; };

View file

@ -422,7 +422,7 @@ content::WebContents* NativeWindow::GetDevToolsWebContents() const {
} }
void NativeWindow::AppendExtraCommandLineSwitches( void NativeWindow::AppendExtraCommandLineSwitches(
base::CommandLine* command_line, int child_process_id) { base::CommandLine* command_line) {
// Append --node-integration to renderer process. // Append --node-integration to renderer process.
command_line->AppendSwitchASCII(switches::kNodeIntegration, command_line->AppendSwitchASCII(switches::kNodeIntegration,
node_integration_ ? "true" : "false"); node_integration_ ? "true" : "false");

View file

@ -192,8 +192,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
content::WebContents* GetDevToolsWebContents() const; content::WebContents* GetDevToolsWebContents() const;
// Called when renderer process is going to be started. // Called when renderer process is going to be started.
void AppendExtraCommandLineSwitches(base::CommandLine* command_line, void AppendExtraCommandLineSwitches(base::CommandLine* command_line);
int child_process_id);
void OverrideWebkitPrefs(content::WebPreferences* prefs); void OverrideWebkitPrefs(content::WebPreferences* prefs);
// Set fullscreen mode triggered by html api. // Set fullscreen mode triggered by html api.

View file

@ -12,10 +12,9 @@ namespace atom {
namespace { namespace {
WebViewManager* GetManagerFromProcess(content::RenderProcessHost* process) { WebViewManager* GetManagerFromWebContents(
if (!process) const content::WebContents* web_contents) {
return nullptr; auto context = web_contents->GetBrowserContext();
auto context = process->GetBrowserContext();
if (!context) if (!context)
return nullptr; return nullptr;
return static_cast<WebViewManager*>(context->GetGuestManager()); return static_cast<WebViewManager*>(context->GetGuestManager());
@ -24,24 +23,9 @@ WebViewManager* GetManagerFromProcess(content::RenderProcessHost* process) {
} // namespace } // namespace
// static // static
bool WebViewManager::GetInfoForProcess(content::RenderProcessHost* process, bool WebViewManager::GetInfoForWebContents(
WebViewInfo* info) { const content::WebContents* web_contents, WebViewInfo* info) {
auto manager = GetManagerFromProcess(process); auto manager = GetManagerFromWebContents(web_contents);
if (!manager)
return false;
base::AutoLock auto_lock(manager->lock_);
for (auto iter : manager->webview_info_map_)
if (iter.first->GetRenderProcessHost() == process) {
*info = iter.second;
return true;
}
return false;
}
// static
bool WebViewManager::GetInfoForWebContents(content::WebContents* web_contents,
WebViewInfo* info) {
auto manager = GetManagerFromProcess(web_contents->GetRenderProcessHost());
if (!manager) if (!manager)
return false; return false;
base::AutoLock auto_lock(manager->lock_); base::AutoLock auto_lock(manager->lock_);

View file

@ -29,13 +29,9 @@ class WebViewManager : public content::BrowserPluginGuestManager {
base::FilePath preload_script; base::FilePath preload_script;
}; };
// Finds the WebViewManager attached with |process| and returns the // Finds the WebViewManager attached with |web_contents| and returns the
// WebViewInfo of it. // WebViewInfo of it.
static bool GetInfoForProcess(content::RenderProcessHost* process, static bool GetInfoForWebContents(const content::WebContents* web_contents,
WebViewInfo* info);
// Same with GetInfoForProcess but search for |web_contents| instead.
static bool GetInfoForWebContents(content::WebContents* web_contents,
WebViewInfo* info); WebViewInfo* info);
explicit WebViewManager(content::BrowserContext* context); explicit WebViewManager(content::BrowserContext* context);
@ -85,7 +81,7 @@ class WebViewManager : public content::BrowserPluginGuestManager {
// (embedder_process_id, element_instance_id) => guest_instance_id // (embedder_process_id, element_instance_id) => guest_instance_id
std::map<ElementInstanceKey, int> element_instance_id_to_guest_map_; std::map<ElementInstanceKey, int> element_instance_id_to_guest_map_;
typedef std::map<content::WebContents*, WebViewInfo> WebViewInfoMap; typedef std::map<const content::WebContents*, WebViewInfo> WebViewInfoMap;
// web_contents => (guest_instance_id, embedder, ...) // web_contents => (guest_instance_id, embedder, ...)
WebViewInfoMap webview_info_map_; WebViewInfoMap webview_info_map_;