Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: content/browser/service_worker/service_worker_client_navigation_utils.cc

Issue 1535983002: ServiceWorker: Factor out functions to collect client information from ServiceWorkerVersion (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/service_worker/service_worker_client_navigation_utils. h"
6
7 #include "base/macros.h"
8 #include "content/browser/frame_host/frame_tree_node.h"
9 #include "content/browser/frame_host/render_frame_host_impl.h"
10 #include "content/browser/service_worker/service_worker_context_core.h"
11 #include "content/browser/service_worker/service_worker_context_wrapper.h"
12 #include "content/browser/storage_partition_impl.h"
13 #include "content/common/service_worker/service_worker_client_info.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/content_browser_client.h"
16 #include "content/public/browser/page_navigator.h"
17 #include "content/public/browser/web_contents.h"
18 #include "content/public/browser/web_contents_observer.h"
19 #include "content/public/common/child_process_host.h"
20 #include "url/gurl.h"
21
22 namespace content {
23 namespace service_worker_client_navigation_utils {
24
25 namespace {
26
27 using OpenURLCallback = base::Callback<void(int, int)>;
28
29 // The OpenURLObserver class is a WebContentsObserver that will wait for a
30 // WebContents to be initialized, run the |callback| passed to its constructor
31 // then self destroy.
32 // The callback will receive the process and frame ids. If something went wrong
33 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE).
34 // The callback will be called in the IO thread.
35 class OpenURLObserver : public WebContentsObserver {
36 public:
37 OpenURLObserver(WebContents* web_contents,
38 int frame_tree_node_id,
39 const OpenURLCallback& callback)
40 : WebContentsObserver(web_contents),
41 frame_tree_node_id_(frame_tree_node_id),
42 callback_(callback) {}
43
44 void DidCommitProvisionalLoadForFrame(
45 RenderFrameHost* render_frame_host,
46 const GURL& validated_url,
47 ui::PageTransition transition_type) override {
48 DCHECK(web_contents());
49
50 RenderFrameHostImpl* rfhi =
51 static_cast<RenderFrameHostImpl*>(render_frame_host);
52 if (rfhi->frame_tree_node()->frame_tree_node_id() != frame_tree_node_id_)
53 return;
54
55 RunCallback(render_frame_host->GetProcess()->GetID(),
56 render_frame_host->GetRoutingID());
57 }
58
59 void RenderProcessGone(base::TerminationStatus status) override {
60 RunCallback(ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
61 }
62
63 void WebContentsDestroyed() override {
64 RunCallback(ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
65 }
66
67 private:
68 void RunCallback(int render_process_id, int render_frame_id) {
69 // After running the callback, |this| will stop observing, thus
70 // web_contents() should return nullptr and |RunCallback| should no longer
71 // be called. Then, |this| will self destroy.
72 DCHECK(web_contents());
73
74 BrowserThread::PostTask(
75 BrowserThread::IO, FROM_HERE,
76 base::Bind(callback_, render_process_id, render_frame_id));
77 Observe(nullptr);
78 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
79 }
80
81 int frame_tree_node_id_;
82 const OpenURLCallback callback_;
83
84 DISALLOW_COPY_AND_ASSIGN(OpenURLObserver);
85 };
86
87 // This is only called for main frame navigations in OpenWindowOnUI().
88 void DidOpenURL(const OpenURLCallback& callback, WebContents* web_contents) {
89 DCHECK(web_contents);
90
91 RenderFrameHostImpl* rfhi =
92 static_cast<RenderFrameHostImpl*>(web_contents->GetMainFrame());
93 new OpenURLObserver(web_contents,
94 rfhi->frame_tree_node()->frame_tree_node_id(), callback);
95 }
96
97 void OpenWindowOnUI(
98 const GURL& url,
99 const GURL& script_url,
100 int worker_process_id,
101 const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper,
102 const OpenURLCallback& callback) {
103 DCHECK_CURRENTLY_ON(BrowserThread::UI);
104
105 BrowserContext* browser_context =
106 context_wrapper->storage_partition()
107 ? context_wrapper->storage_partition()->browser_context()
108 : nullptr;
109 // We are shutting down.
110 if (!browser_context)
111 return;
112
113 RenderProcessHost* render_process_host =
114 RenderProcessHost::FromID(worker_process_id);
115 if (render_process_host->IsForGuestsOnly()) {
116 BrowserThread::PostTask(
117 BrowserThread::IO, FROM_HERE,
118 base::Bind(callback, ChildProcessHost::kInvalidUniqueID,
119 MSG_ROUTING_NONE));
120 return;
121 }
122
123 OpenURLParams params(
124 url, Referrer::SanitizeForRequest(
125 url, Referrer(script_url, blink::WebReferrerPolicyDefault)),
126 NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
127 true /* is_renderer_initiated */);
128
129 GetContentClient()->browser()->OpenURL(browser_context, params,
130 base::Bind(&DidOpenURL, callback));
131 }
132
133 void NavigateClientOnUI(const GURL& url,
134 const GURL& script_url,
135 int process_id,
136 int frame_id,
137 const OpenURLCallback& callback) {
138 DCHECK_CURRENTLY_ON(BrowserThread::UI);
139
140 RenderFrameHostImpl* rfhi = RenderFrameHostImpl::FromID(process_id, frame_id);
141 WebContents* web_contents = WebContents::FromRenderFrameHost(rfhi);
142
143 if (!rfhi || !web_contents) {
144 BrowserThread::PostTask(
145 BrowserThread::IO, FROM_HERE,
146 base::Bind(callback, ChildProcessHost::kInvalidUniqueID,
147 MSG_ROUTING_NONE));
148 return;
149 }
150
151 ui::PageTransition transition = rfhi->GetParent()
152 ? ui::PAGE_TRANSITION_AUTO_SUBFRAME
153 : ui::PAGE_TRANSITION_AUTO_TOPLEVEL;
154 int frame_tree_node_id = rfhi->frame_tree_node()->frame_tree_node_id();
155
156 OpenURLParams params(
157 url, Referrer::SanitizeForRequest(
158 url, Referrer(script_url, blink::WebReferrerPolicyDefault)),
159 frame_tree_node_id, CURRENT_TAB, transition,
160 true /* is_renderer_initiated */);
161 web_contents->OpenURL(params);
162 new OpenURLObserver(web_contents, frame_tree_node_id, callback);
163 }
164
165 void DidNavigate(const base::WeakPtr<ServiceWorkerContextCore>& context,
166 const GURL& origin,
167 const NavigationCallback& callback,
168 int render_process_id,
169 int render_frame_id) {
170 DCHECK_CURRENTLY_ON(BrowserThread::IO);
171
172 if (!context) {
173 callback.Run(SERVICE_WORKER_ERROR_ABORT, std::string(),
174 ServiceWorkerClientInfo());
175 return;
176 }
177
178 if (render_process_id == ChildProcessHost::kInvalidUniqueID &&
179 render_frame_id == MSG_ROUTING_NONE) {
180 callback.Run(SERVICE_WORKER_ERROR_FAILED, std::string(),
181 ServiceWorkerClientInfo());
182 return;
183 }
184
185 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
186 context->GetClientProviderHostIterator(origin);
187 !it->IsAtEnd(); it->Advance()) {
188 ServiceWorkerProviderHost* provider_host = it->GetProviderHost();
189 if (provider_host->process_id() != render_process_id ||
190 provider_host->frame_id() != render_frame_id) {
191 continue;
192 }
193 provider_host->GetWindowClientInfo(
194 base::Bind(callback, SERVICE_WORKER_OK, provider_host->client_uuid()));
195 return;
196 }
197
198 // If here, it means that no provider_host was found, in which case, the
199 // renderer should still be informed that the window was opened.
200 callback.Run(SERVICE_WORKER_OK, std::string(), ServiceWorkerClientInfo());
201 }
202
203 } // namespace
204
205 void OpenWindow(const GURL& url,
206 const GURL& script_url,
207 int worker_process_id,
208 const base::WeakPtr<ServiceWorkerContextCore>& context,
209 const NavigationCallback& callback) {
210 DCHECK_CURRENTLY_ON(BrowserThread::IO);
211 BrowserThread::PostTask(
212 BrowserThread::UI, FROM_HERE,
213 base::Bind(
214 &OpenWindowOnUI, url, script_url, worker_process_id,
215 make_scoped_refptr(context->wrapper()),
216 base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback)));
217 }
218
219 void NavigateClient(const GURL& url,
220 const GURL& script_url,
221 int process_id,
222 int frame_id,
223 const base::WeakPtr<ServiceWorkerContextCore>& context,
224 const NavigationCallback& callback) {
225 DCHECK_CURRENTLY_ON(BrowserThread::IO);
226 BrowserThread::PostTask(
227 BrowserThread::UI, FROM_HERE,
228 base::Bind(
229 &NavigateClientOnUI, url, script_url, process_id, frame_id,
230 base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback)));
231 }
232
233 } // namespace service_worker_client_navigation_utils
234 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698