OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/browser/guest_view/web_view/web_view_guest.h" | 5 #include "extensions/browser/guest_view/web_view/web_view_guest.h" |
6 | 6 |
7 #include "base/bind.h" | |
7 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
8 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
9 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
10 #include "content/public/browser/browser_context.h" | 11 #include "content/public/browser/browser_context.h" |
11 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
12 #include "content/public/browser/child_process_security_policy.h" | 13 #include "content/public/browser/child_process_security_policy.h" |
13 #include "content/public/browser/native_web_keyboard_event.h" | 14 #include "content/public/browser/native_web_keyboard_event.h" |
14 #include "content/public/browser/navigation_entry.h" | 15 #include "content/public/browser/navigation_entry.h" |
15 #include "content/public/browser/notification_details.h" | 16 #include "content/public/browser/notification_details.h" |
16 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
52 | 53 |
53 using base::UserMetricsAction; | 54 using base::UserMetricsAction; |
54 using content::RenderFrameHost; | 55 using content::RenderFrameHost; |
55 using content::ResourceType; | 56 using content::ResourceType; |
56 using content::WebContents; | 57 using content::WebContents; |
57 | 58 |
58 namespace extensions { | 59 namespace extensions { |
59 | 60 |
60 namespace { | 61 namespace { |
61 | 62 |
63 using GetNextUniqueIDFunction = base::Callback<int(void)>; | |
64 | |
65 using WebViewKey = std::pair<int, int>; | |
66 using WebViewKeyToIDMap = std::map<WebViewKey, int>; | |
67 base::LazyInstance<WebViewKeyToIDMap> web_view_key_to_id_map = | |
68 LAZY_INSTANCE_INITIALIZER; | |
69 base::LazyInstance<WebViewKeyToIDMap> script_injection_instance_id_map = | |
70 LAZY_INSTANCE_INITIALIZER; | |
71 | |
72 int current_script_injection_instance_id = 0; | |
73 | |
62 std::string WindowOpenDispositionToString( | 74 std::string WindowOpenDispositionToString( |
63 WindowOpenDisposition window_open_disposition) { | 75 WindowOpenDisposition window_open_disposition) { |
64 switch (window_open_disposition) { | 76 switch (window_open_disposition) { |
65 case IGNORE_ACTION: | 77 case IGNORE_ACTION: |
66 return "ignore"; | 78 return "ignore"; |
67 case SAVE_TO_DISK: | 79 case SAVE_TO_DISK: |
68 return "save_to_disk"; | 80 return "save_to_disk"; |
69 case CURRENT_TAB: | 81 case CURRENT_TAB: |
70 return "current_tab"; | 82 return "current_tab"; |
71 case NEW_BACKGROUND_TAB: | 83 case NEW_BACKGROUND_TAB: |
(...skipping 21 matching lines...) Expand all Loading... | |
93 return "killed"; | 105 return "killed"; |
94 case base::TERMINATION_STATUS_PROCESS_CRASHED: | 106 case base::TERMINATION_STATUS_PROCESS_CRASHED: |
95 return "crashed"; | 107 return "crashed"; |
96 case base::TERMINATION_STATUS_MAX_ENUM: | 108 case base::TERMINATION_STATUS_MAX_ENUM: |
97 break; | 109 break; |
98 } | 110 } |
99 NOTREACHED() << "Unknown Termination Status."; | 111 NOTREACHED() << "Unknown Termination Status."; |
100 return "unknown"; | 112 return "unknown"; |
101 } | 113 } |
102 | 114 |
115 int GetNextScriptInjectionInstanceID() { | |
116 return ++current_script_injection_instance_id; | |
117 } | |
118 | |
119 int GetOrGenerateUniqueID(int embedder_process_id, | |
120 int guest_instance_id, | |
121 WebViewKeyToIDMap& id_map, | |
122 int default_id, | |
123 const GetNextUniqueIDFunction& function) { | |
Fady Samuel
2015/02/10 06:04:12
This is really weird. I don't know if I like this
Fady Samuel
2015/02/10 15:46:47
Nevermind, I didn't notice that you're passing in
Devlin
2015/02/10 20:59:53
I agree - it's a little over-verbose and hard to p
Xi Han
2015/02/10 23:35:14
I am happy to remove the bind statement as well. T
| |
124 if (!(embedder_process_id && guest_instance_id)) | |
125 return default_id; | |
126 | |
127 WebViewKey key = std::make_pair(embedder_process_id, guest_instance_id); | |
128 auto it = id_map.find(key); | |
129 if (it != id_map.end()) | |
130 return it->second; | |
131 | |
132 int instance_id = function.Run(); | |
133 id_map[key] = instance_id; | |
134 return instance_id; | |
135 } | |
136 | |
103 std::string GetStoragePartitionIdFromSiteURL(const GURL& site_url) { | 137 std::string GetStoragePartitionIdFromSiteURL(const GURL& site_url) { |
104 const std::string& partition_id = site_url.query(); | 138 const std::string& partition_id = site_url.query(); |
105 bool persist_storage = site_url.path().find("persist") != std::string::npos; | 139 bool persist_storage = site_url.path().find("persist") != std::string::npos; |
106 return (persist_storage ? webview::kPersistPrefix : "") + partition_id; | 140 return (persist_storage ? webview::kPersistPrefix : "") + partition_id; |
107 } | 141 } |
108 | 142 |
109 void ParsePartitionParam(const base::DictionaryValue& create_params, | 143 void ParsePartitionParam(const base::DictionaryValue& create_params, |
110 std::string* storage_partition_id, | 144 std::string* storage_partition_id, |
111 bool* persist_storage) { | 145 bool* persist_storage) { |
112 std::string partition_str; | 146 std::string partition_str; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
174 // The partition name is user supplied value, which we have encoded when the | 208 // The partition name is user supplied value, which we have encoded when the |
175 // URL was created, so it needs to be decoded. | 209 // URL was created, so it needs to be decoded. |
176 *partition_name = | 210 *partition_name = |
177 net::UnescapeURLComponent(site.query(), net::UnescapeRule::NORMAL); | 211 net::UnescapeURLComponent(site.query(), net::UnescapeRule::NORMAL); |
178 return true; | 212 return true; |
179 } | 213 } |
180 | 214 |
181 // static | 215 // static |
182 const char WebViewGuest::Type[] = "webview"; | 216 const char WebViewGuest::Type[] = "webview"; |
183 | 217 |
184 using WebViewKey = std::pair<int, int>; | |
185 using WebViewKeyToIDMap = std::map<WebViewKey, int>; | |
186 static base::LazyInstance<WebViewKeyToIDMap> web_view_key_to_id_map = | |
187 LAZY_INSTANCE_INITIALIZER; | |
188 | |
189 // static | 218 // static |
190 int WebViewGuest::GetOrGenerateRulesRegistryID( | 219 int WebViewGuest::GetOrGenerateRulesRegistryID( |
191 int embedder_process_id, | 220 int embedder_process_id, |
192 int webview_instance_id) { | 221 int webview_instance_id) { |
193 bool is_web_view = embedder_process_id && webview_instance_id; | 222 return GetOrGenerateUniqueID( |
194 if (!is_web_view) | 223 embedder_process_id, |
195 return RulesRegistryService::kDefaultRulesRegistryID; | 224 webview_instance_id, |
196 | 225 web_view_key_to_id_map.Get(), |
197 WebViewKey key = std::make_pair(embedder_process_id, webview_instance_id); | 226 RulesRegistryService::kDefaultRulesRegistryID, |
198 auto it = web_view_key_to_id_map.Get().find(key); | 227 base::Bind(&RulesRegistryService::GetNextRulesRegistryID, |
199 if (it != web_view_key_to_id_map.Get().end()) | 228 base::Unretained( |
200 return it->second; | 229 RulesRegistryService::Get( |
201 | 230 content::RenderProcessHost::FromID( |
202 auto rph = content::RenderProcessHost::FromID(embedder_process_id); | 231 embedder_process_id)->GetBrowserContext())))); |
203 int rules_registry_id = | |
204 RulesRegistryService::Get(rph->GetBrowserContext())-> | |
205 GetNextRulesRegistryID(); | |
206 web_view_key_to_id_map.Get()[key] = rules_registry_id; | |
207 return rules_registry_id; | |
208 } | 232 } |
209 | 233 |
210 // static | 234 // static |
235 int WebViewGuest::GetOrGenerateScriptInjectionInstanceID( | |
236 int embedder_process_id, | |
237 int guest_instance_id ) { | |
238 return GetOrGenerateUniqueID( | |
239 embedder_process_id, | |
240 guest_instance_id, | |
241 script_injection_instance_id_map.Get(), | |
242 HostID::kDefaultInstanceId, | |
243 base::Bind(&GetNextScriptInjectionInstanceID)); | |
244 } | |
245 | |
246 // static | |
211 int WebViewGuest::GetViewInstanceId(WebContents* contents) { | 247 int WebViewGuest::GetViewInstanceId(WebContents* contents) { |
212 auto guest = FromWebContents(contents); | 248 auto guest = FromWebContents(contents); |
213 if (!guest) | 249 if (!guest) |
214 return guestview::kInstanceIDNone; | 250 return guestview::kInstanceIDNone; |
215 | 251 |
216 return guest->view_instance_id(); | 252 return guest->view_instance_id(); |
217 } | 253 } |
218 | 254 |
219 bool WebViewGuest::CanRunInDetachedState() const { | 255 bool WebViewGuest::CanRunInDetachedState() const { |
220 return true; | 256 return true; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 content::Source<WebContents>(web_contents())); | 323 content::Source<WebContents>(web_contents())); |
288 | 324 |
289 if (web_view_guest_delegate_) | 325 if (web_view_guest_delegate_) |
290 web_view_guest_delegate_->OnDidInitialize(); | 326 web_view_guest_delegate_->OnDidInitialize(); |
291 AttachWebViewHelpers(web_contents()); | 327 AttachWebViewHelpers(web_contents()); |
292 | 328 |
293 rules_registry_id_ = GetOrGenerateRulesRegistryID( | 329 rules_registry_id_ = GetOrGenerateRulesRegistryID( |
294 owner_web_contents()->GetRenderProcessHost()->GetID(), | 330 owner_web_contents()->GetRenderProcessHost()->GetID(), |
295 view_instance_id()); | 331 view_instance_id()); |
296 | 332 |
333 GetOrGenerateScriptInjectionInstanceID( | |
334 owner_web_contents()->GetRenderProcessHost()->GetID(), | |
335 guest_instance_id()); | |
336 | |
297 // We must install the mapping from guests to WebViews prior to resuming | 337 // We must install the mapping from guests to WebViews prior to resuming |
298 // suspended resource loads so that the WebRequest API will catch resource | 338 // suspended resource loads so that the WebRequest API will catch resource |
299 // requests. | 339 // requests. |
300 PushWebViewStateToIOThread(); | 340 PushWebViewStateToIOThread(); |
301 | 341 |
302 ApplyAttributes(create_params); | 342 ApplyAttributes(create_params); |
303 } | 343 } |
304 | 344 |
305 void WebViewGuest::AttachWebViewHelpers(WebContents* contents) { | 345 void WebViewGuest::AttachWebViewHelpers(WebContents* contents) { |
306 if (web_view_guest_delegate_) | 346 if (web_view_guest_delegate_) |
307 web_view_guest_delegate_->OnAttachWebViewHelpers(contents); | 347 web_view_guest_delegate_->OnAttachWebViewHelpers(contents); |
308 web_view_permission_helper_.reset(new WebViewPermissionHelper(this)); | 348 web_view_permission_helper_.reset(new WebViewPermissionHelper(this)); |
309 } | 349 } |
310 | 350 |
311 void WebViewGuest::DidStopLoading() { | 351 void WebViewGuest::DidStopLoading() { |
312 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); | 352 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); |
313 DispatchEventToView( | 353 DispatchEventToView( |
314 new GuestViewBase::Event(webview::kEventLoadStop, args.Pass())); | 354 new GuestViewBase::Event(webview::kEventLoadStop, args.Pass())); |
315 } | 355 } |
316 | 356 |
317 void WebViewGuest::EmbedderWillBeDestroyed() { | 357 void WebViewGuest::EmbedderWillBeDestroyed() { |
318 // Clean up rules registries for the webview. | 358 // Clean up rules registries for the webview. |
319 RulesRegistryService::Get(browser_context()) | 359 RulesRegistryService::Get(browser_context()) |
320 ->RemoveRulesRegistriesByID(rules_registry_id_); | 360 ->RemoveRulesRegistriesByID(rules_registry_id_); |
321 WebViewKey key(owner_web_contents()->GetRenderProcessHost()->GetID(), | 361 WebViewKey key(owner_web_contents()->GetRenderProcessHost()->GetID(), |
322 view_instance_id()); | 362 view_instance_id()); |
323 web_view_key_to_id_map.Get().erase(key); | 363 web_view_key_to_id_map.Get().erase(key); |
364 script_injection_instance_id_map.Get().erase(key); | |
324 | 365 |
325 content::BrowserThread::PostTask( | 366 content::BrowserThread::PostTask( |
326 content::BrowserThread::IO, | 367 content::BrowserThread::IO, |
327 FROM_HERE, | 368 FROM_HERE, |
328 base::Bind( | 369 base::Bind( |
329 &RemoveWebViewEventListenersOnIOThread, | 370 &RemoveWebViewEventListenersOnIOThread, |
330 browser_context(), | 371 browser_context(), |
331 owner_extension_id(), | 372 owner_extension_id(), |
332 owner_web_contents()->GetRenderProcessHost()->GetID(), | 373 owner_web_contents()->GetRenderProcessHost()->GetID(), |
333 view_instance_id())); | 374 view_instance_id())); |
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1215 WebViewGuest::From(owner_web_contents()->GetRenderProcessHost()->GetID(), | 1256 WebViewGuest::From(owner_web_contents()->GetRenderProcessHost()->GetID(), |
1216 new_window_instance_id); | 1257 new_window_instance_id); |
1217 if (!guest) | 1258 if (!guest) |
1218 return; | 1259 return; |
1219 | 1260 |
1220 if (!allow) | 1261 if (!allow) |
1221 guest->Destroy(); | 1262 guest->Destroy(); |
1222 } | 1263 } |
1223 | 1264 |
1224 } // namespace extensions | 1265 } // namespace extensions |
OLD | NEW |