OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
11 #include "base/time.h" | 11 #include "base/time.h" |
12 #include "chrome/browser/extensions/extension_event_router.h" | 12 #include "chrome/browser/extensions/extension_event_router.h" |
13 #include "chrome/browser/extensions/extension_process_manager.h" | 13 #include "chrome/browser/extensions/extension_process_manager.h" |
14 #include "chrome/browser/extensions/extension_host.h" | 14 #include "chrome/browser/extensions/extension_host.h" |
15 #include "chrome/browser/extensions/extension_info_map.h" | 15 #include "chrome/browser/extensions/extension_info_map.h" |
16 #include "chrome/browser/extensions/extension_service.h" | 16 #include "chrome/browser/extensions/extension_service.h" |
17 #include "chrome/browser/extensions/extension_system.h" | 17 #include "chrome/browser/extensions/extension_system.h" |
18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/ui/browser.h" | 19 #include "chrome/browser/ui/browser.h" |
20 #include "chrome/browser/ui/browser_finder.h" | 20 #include "chrome/browser/ui/browser_finder.h" |
21 #include "chrome/browser/ui/browser_window.h" | 21 #include "chrome/browser/ui/browser_window.h" |
| 22 #include "chrome/browser/view_type_utils.h" |
22 #include "chrome/common/chrome_notification_types.h" | 23 #include "chrome/common/chrome_notification_types.h" |
23 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
24 #include "chrome/common/chrome_view_type.h" | |
25 #include "chrome/common/extensions/extension.h" | 25 #include "chrome/common/extensions/extension.h" |
26 #include "chrome/common/extensions/extension_messages.h" | 26 #include "chrome/common/extensions/extension_messages.h" |
27 #include "chrome/common/url_constants.h" | 27 #include "chrome/common/url_constants.h" |
28 #include "content/public/browser/browser_thread.h" | 28 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
30 #include "content/public/browser/render_process_host.h" | 30 #include "content/public/browser/render_process_host.h" |
31 #include "content/public/browser/render_view_host.h" | 31 #include "content/public/browser/render_view_host.h" |
32 #include "content/public/browser/render_view_host_delegate.h" | 32 #include "content/public/browser/render_view_host_delegate.h" |
33 #include "content/public/browser/site_instance.h" | 33 #include "content/public/browser/site_instance.h" |
34 #include "content/public/browser/web_contents.h" | 34 #include "content/public/browser/web_contents.h" |
35 #include "content/public/common/renderer_preferences.h" | 35 #include "content/public/common/renderer_preferences.h" |
36 | 36 |
37 #if defined(OS_MACOSX) | 37 #if defined(OS_MACOSX) |
38 #include "chrome/browser/extensions/extension_host_mac.h" | 38 #include "chrome/browser/extensions/extension_host_mac.h" |
39 #endif | 39 #endif |
40 | 40 |
41 using content::BrowserThread; | 41 using content::BrowserThread; |
42 using content::OpenURLParams; | 42 using content::OpenURLParams; |
43 using content::Referrer; | 43 using content::Referrer; |
44 using content::RenderViewHost; | 44 using content::RenderViewHost; |
45 using content::SiteInstance; | 45 using content::SiteInstance; |
| 46 using content::WebContents; |
46 using extensions::Extension; | 47 using extensions::Extension; |
47 | 48 |
48 namespace { | 49 namespace { |
49 | 50 |
50 std::string GetExtensionID(RenderViewHost* render_view_host) { | 51 std::string GetExtensionID(RenderViewHost* render_view_host) { |
51 // This works for both apps and extensions because the site has been | 52 // This works for both apps and extensions because the site has been |
52 // normalized to the extension URL for apps. | 53 // normalized to the extension URL for apps. |
53 if (!render_view_host->GetSiteInstance()) | 54 if (!render_view_host->GetSiteInstance()) |
54 return ""; | 55 return ""; |
55 | 56 |
56 return render_view_host->GetSiteInstance()->GetSite().host(); | 57 return render_view_host->GetSiteInstance()->GetSite().host(); |
57 } | 58 } |
58 | 59 |
59 // Incognito profiles use this process manager. It is mostly a shim that decides | 60 // Incognito profiles use this process manager. It is mostly a shim that decides |
60 // whether to fall back on the original profile's ExtensionProcessManager based | 61 // whether to fall back on the original profile's ExtensionProcessManager based |
61 // on whether a given extension uses "split" or "spanning" incognito behavior. | 62 // on whether a given extension uses "split" or "spanning" incognito behavior. |
62 class IncognitoExtensionProcessManager : public ExtensionProcessManager { | 63 class IncognitoExtensionProcessManager : public ExtensionProcessManager { |
63 public: | 64 public: |
64 explicit IncognitoExtensionProcessManager(Profile* profile); | 65 explicit IncognitoExtensionProcessManager(Profile* profile); |
65 virtual ~IncognitoExtensionProcessManager() {} | 66 virtual ~IncognitoExtensionProcessManager() {} |
66 virtual ExtensionHost* CreateViewHost( | 67 virtual ExtensionHost* CreateViewHost( |
67 const Extension* extension, | 68 const Extension* extension, |
68 const GURL& url, | 69 const GURL& url, |
69 Browser* browser, | 70 Browser* browser, |
70 content::ViewType view_type) OVERRIDE; | 71 chrome::ViewType view_type) OVERRIDE; |
71 virtual void CreateBackgroundHost(const Extension* extension, | 72 virtual void CreateBackgroundHost(const Extension* extension, |
72 const GURL& url); | 73 const GURL& url); |
73 virtual SiteInstance* GetSiteInstanceForURL(const GURL& url); | 74 virtual SiteInstance* GetSiteInstanceForURL(const GURL& url); |
74 | 75 |
75 private: | 76 private: |
76 // content::NotificationObserver: | 77 // content::NotificationObserver: |
77 virtual void Observe(int type, | 78 virtual void Observe(int type, |
78 const content::NotificationSource& source, | 79 const content::NotificationSource& source, |
79 const content::NotificationDetails& details); | 80 const content::NotificationDetails& details); |
80 | 81 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 } | 172 } |
172 } | 173 } |
173 | 174 |
174 ExtensionProcessManager::~ExtensionProcessManager() { | 175 ExtensionProcessManager::~ExtensionProcessManager() { |
175 CloseBackgroundHosts(); | 176 CloseBackgroundHosts(); |
176 DCHECK(background_hosts_.empty()); | 177 DCHECK(background_hosts_.empty()); |
177 } | 178 } |
178 | 179 |
179 void ExtensionProcessManager::EnsureBrowserWhenRequired( | 180 void ExtensionProcessManager::EnsureBrowserWhenRequired( |
180 Browser* browser, | 181 Browser* browser, |
181 content::ViewType view_type) { | 182 chrome::ViewType view_type) { |
182 if (!browser) { | 183 if (!browser) { |
183 #if defined (OS_CHROMEOS) | 184 #if defined (OS_CHROMEOS) |
184 // On ChromeOS we'll only use ExtensionView, which | 185 // On ChromeOS we'll only use ExtensionView, which |
185 // does not use the browser parameter. | 186 // does not use the browser parameter. |
186 // TODO(rkc): Remove all this once we create a new host for | 187 // TODO(rkc): Remove all this once we create a new host for |
187 // screensaver extensions (crosbug.com/28211). | 188 // screensaver extensions (crosbug.com/28211). |
188 DCHECK(view_type == chrome::VIEW_TYPE_EXTENSION_POPUP || | 189 DCHECK(view_type == chrome::VIEW_TYPE_EXTENSION_POPUP || |
189 view_type == chrome::VIEW_TYPE_EXTENSION_DIALOG); | 190 view_type == chrome::VIEW_TYPE_EXTENSION_DIALOG); |
190 #else | 191 #else |
191 // A NULL browser may only be given for pop-up views. | 192 // A NULL browser may only be given for pop-up views. |
192 DCHECK(view_type == chrome::VIEW_TYPE_EXTENSION_POPUP); | 193 DCHECK(view_type == chrome::VIEW_TYPE_EXTENSION_POPUP); |
193 #endif | 194 #endif |
194 } | 195 } |
195 } | 196 } |
196 | 197 |
197 | 198 |
198 ExtensionHost* ExtensionProcessManager::CreateViewHost( | 199 ExtensionHost* ExtensionProcessManager::CreateViewHost( |
199 const Extension* extension, | 200 const Extension* extension, |
200 const GURL& url, | 201 const GURL& url, |
201 Browser* browser, | 202 Browser* browser, |
202 content::ViewType view_type) { | 203 chrome::ViewType view_type) { |
203 DCHECK(extension); | 204 DCHECK(extension); |
204 EnsureBrowserWhenRequired(browser, view_type); | 205 EnsureBrowserWhenRequired(browser, view_type); |
205 ExtensionHost* host = | 206 ExtensionHost* host = |
206 #if defined(OS_MACOSX) | 207 #if defined(OS_MACOSX) |
207 new ExtensionHostMac(extension, GetSiteInstanceForURL(url), url, | 208 new ExtensionHostMac(extension, GetSiteInstanceForURL(url), url, |
208 view_type); | 209 view_type); |
209 #else | 210 #else |
210 new ExtensionHost(extension, GetSiteInstanceForURL(url), url, view_type); | 211 new ExtensionHost(extension, GetSiteInstanceForURL(url), url, view_type); |
211 #endif | 212 #endif |
212 host->CreateView(browser); | 213 host->CreateView(browser); |
213 OnExtensionHostCreated(host, false); | 214 OnExtensionHostCreated(host, false); |
214 return host; | 215 return host; |
215 } | 216 } |
216 | 217 |
217 ExtensionHost* ExtensionProcessManager::CreateViewHost( | 218 ExtensionHost* ExtensionProcessManager::CreateViewHost( |
218 const GURL& url, Browser* browser, content::ViewType view_type) { | 219 const GURL& url, Browser* browser, chrome::ViewType view_type) { |
219 EnsureBrowserWhenRequired(browser, view_type); | 220 EnsureBrowserWhenRequired(browser, view_type); |
220 ExtensionService* service = GetProfile()->GetExtensionService(); | 221 ExtensionService* service = GetProfile()->GetExtensionService(); |
221 if (service) { | 222 if (service) { |
222 const Extension* extension = | 223 const Extension* extension = |
223 service->extensions()->GetByID(url.host()); | 224 service->extensions()->GetByID(url.host()); |
224 if (extension) | 225 if (extension) |
225 return CreateViewHost(extension, url, browser, view_type); | 226 return CreateViewHost(extension, url, browser, view_type); |
226 } | 227 } |
227 return NULL; | 228 return NULL; |
228 } | 229 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 return NULL; | 335 return NULL; |
335 | 336 |
336 ExtensionService* service = | 337 ExtensionService* service = |
337 ExtensionSystem::Get(GetProfile())->extension_service(); | 338 ExtensionSystem::Get(GetProfile())->extension_service(); |
338 return service->extensions()->GetByID(GetExtensionID(render_view_host)); | 339 return service->extensions()->GetByID(GetExtensionID(render_view_host)); |
339 } | 340 } |
340 | 341 |
341 void ExtensionProcessManager::RegisterRenderViewHost( | 342 void ExtensionProcessManager::RegisterRenderViewHost( |
342 RenderViewHost* render_view_host, | 343 RenderViewHost* render_view_host, |
343 const Extension* extension) { | 344 const Extension* extension) { |
344 all_extension_views_[render_view_host] = content::VIEW_TYPE_INVALID; | 345 all_extension_views_[render_view_host] = chrome::VIEW_TYPE_INVALID; |
345 } | 346 } |
346 | 347 |
347 void ExtensionProcessManager::UnregisterRenderViewHost( | 348 void ExtensionProcessManager::UnregisterRenderViewHost( |
348 RenderViewHost* render_view_host) { | 349 RenderViewHost* render_view_host) { |
349 ExtensionRenderViews::iterator view = | 350 ExtensionRenderViews::iterator view = |
350 all_extension_views_.find(render_view_host); | 351 all_extension_views_.find(render_view_host); |
351 if (view == all_extension_views_.end()) | 352 if (view == all_extension_views_.end()) |
352 return; | 353 return; |
353 | 354 |
354 content::NotificationService::current()->Notify( | 355 content::NotificationService::current()->Notify( |
355 chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED, | 356 chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED, |
356 content::Source<Profile>(GetProfile()), | 357 content::Source<Profile>(GetProfile()), |
357 content::Details<RenderViewHost>(render_view_host)); | 358 content::Details<RenderViewHost>(render_view_host)); |
358 | 359 |
359 content::ViewType view_type = view->second; | 360 chrome::ViewType view_type = view->second; |
360 all_extension_views_.erase(view); | 361 all_extension_views_.erase(view); |
361 | 362 |
362 // Keepalive count, balanced in UpdateRegisteredRenderView. | 363 // Keepalive count, balanced in UpdateRegisteredRenderView. |
363 if (view_type != content::VIEW_TYPE_INVALID && | 364 if (view_type != chrome::VIEW_TYPE_INVALID && |
364 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 365 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
365 const Extension* extension = GetExtensionForRenderViewHost( | 366 const Extension* extension = GetExtensionForRenderViewHost( |
366 render_view_host); | 367 render_view_host); |
367 if (extension) | 368 if (extension) |
368 DecrementLazyKeepaliveCount(extension); | 369 DecrementLazyKeepaliveCount(extension); |
369 } | 370 } |
370 } | 371 } |
371 | 372 |
372 void ExtensionProcessManager::UpdateRegisteredRenderView( | 373 void ExtensionProcessManager::UpdateRegisteredRenderView( |
373 RenderViewHost* render_view_host) { | 374 RenderViewHost* render_view_host) { |
374 ExtensionRenderViews::iterator view = | 375 ExtensionRenderViews::iterator view = |
375 all_extension_views_.find(render_view_host); | 376 all_extension_views_.find(render_view_host); |
376 if (view == all_extension_views_.end()) | 377 if (view == all_extension_views_.end()) |
377 return; | 378 return; |
378 | 379 |
379 content::NotificationService::current()->Notify( | 380 content::NotificationService::current()->Notify( |
380 chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED, | 381 chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED, |
381 content::Source<Profile>(GetProfile()), | 382 content::Source<Profile>(GetProfile()), |
382 content::Details<RenderViewHost>(render_view_host)); | 383 content::Details<RenderViewHost>(render_view_host)); |
383 | 384 |
384 view->second = render_view_host->GetDelegate()->GetRenderViewType(); | 385 WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host); |
| 386 view->second = chrome::GetViewType(web_contents); |
385 | 387 |
386 // Keep the lazy background page alive as long as any non-background-page | 388 // Keep the lazy background page alive as long as any non-background-page |
387 // extension views are visible. Keepalive count balanced in | 389 // extension views are visible. Keepalive count balanced in |
388 // UnregisterRenderViewHost. | 390 // UnregisterRenderViewHost. |
389 IncrementLazyKeepaliveCountForView(render_view_host); | 391 IncrementLazyKeepaliveCountForView(render_view_host); |
390 } | 392 } |
391 | 393 |
392 SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) { | 394 SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) { |
393 return site_instance_->GetRelatedSiteInstance(url); | 395 return site_instance_->GetRelatedSiteInstance(url); |
394 } | 396 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, | 433 base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, |
432 weak_ptr_factory_.GetWeakPtr(), extension->id(), | 434 weak_ptr_factory_.GetWeakPtr(), extension->id(), |
433 ++background_page_data_[extension->id()].close_sequence_id), | 435 ++background_page_data_[extension->id()].close_sequence_id), |
434 event_page_idle_time_); | 436 event_page_idle_time_); |
435 } | 437 } |
436 | 438 |
437 return count; | 439 return count; |
438 } | 440 } |
439 void ExtensionProcessManager::IncrementLazyKeepaliveCountForView( | 441 void ExtensionProcessManager::IncrementLazyKeepaliveCountForView( |
440 RenderViewHost* render_view_host) { | 442 RenderViewHost* render_view_host) { |
441 content::ViewType view_type = | 443 WebContents* web_contents = |
442 render_view_host->GetDelegate()->GetRenderViewType(); | 444 WebContents::FromRenderViewHost(render_view_host); |
443 if (view_type != content::VIEW_TYPE_INVALID && | 445 chrome::ViewType view_type = chrome::GetViewType(web_contents); |
| 446 if (view_type != chrome::VIEW_TYPE_INVALID && |
444 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 447 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
445 const Extension* extension = GetExtensionForRenderViewHost( | 448 const Extension* extension = GetExtensionForRenderViewHost( |
446 render_view_host); | 449 render_view_host); |
447 if (extension) | 450 if (extension) |
448 IncrementLazyKeepaliveCount(extension); | 451 IncrementLazyKeepaliveCount(extension); |
449 } | 452 } |
450 } | 453 } |
451 | 454 |
452 void ExtensionProcessManager::OnLazyBackgroundPageIdle( | 455 void ExtensionProcessManager::OnLazyBackgroundPageIdle( |
453 const std::string& extension_id, int sequence_id) { | 456 const std::string& extension_id, int sequence_id) { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 // Close background hosts when the last browser is closed so that they | 588 // Close background hosts when the last browser is closed so that they |
586 // have time to shutdown various objects on different threads. Our | 589 // have time to shutdown various objects on different threads. Our |
587 // destructor is called too late in the shutdown sequence. | 590 // destructor is called too late in the shutdown sequence. |
588 CloseBackgroundHosts(); | 591 CloseBackgroundHosts(); |
589 break; | 592 break; |
590 } | 593 } |
591 | 594 |
592 case content::NOTIFICATION_DEVTOOLS_WINDOW_OPENING: { | 595 case content::NOTIFICATION_DEVTOOLS_WINDOW_OPENING: { |
593 RenderViewHost* render_view_host = | 596 RenderViewHost* render_view_host = |
594 content::Details<RenderViewHost>(details).ptr(); | 597 content::Details<RenderViewHost>(details).ptr(); |
| 598 WebContents* web_contents = |
| 599 WebContents::FromRenderViewHost(render_view_host); |
595 // Keep the lazy background page alive while it's being inspected. | 600 // Keep the lazy background page alive while it's being inspected. |
596 // Balanced in response to the CLOSING notification. | 601 // Balanced in response to the CLOSING notification. |
597 if (render_view_host->GetDelegate()->GetRenderViewType() == | 602 if (chrome::GetViewType(web_contents) == |
598 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 603 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
599 const Extension* extension = GetExtensionForRenderViewHost( | 604 const Extension* extension = GetExtensionForRenderViewHost( |
600 render_view_host); | 605 render_view_host); |
601 if (extension) | 606 if (extension) |
602 IncrementLazyKeepaliveCount(extension); | 607 IncrementLazyKeepaliveCount(extension); |
603 } | 608 } |
604 break; | 609 break; |
605 } | 610 } |
606 | 611 |
607 case content::NOTIFICATION_DEVTOOLS_WINDOW_CLOSING: { | 612 case content::NOTIFICATION_DEVTOOLS_WINDOW_CLOSING: { |
608 RenderViewHost* render_view_host = | 613 RenderViewHost* render_view_host = |
609 content::Details<RenderViewHost>(details).ptr(); | 614 content::Details<RenderViewHost>(details).ptr(); |
| 615 WebContents* web_contents = |
| 616 WebContents::FromRenderViewHost(render_view_host); |
610 // Balanced in response to the OPENING notification. | 617 // Balanced in response to the OPENING notification. |
611 if (render_view_host->GetDelegate()->GetRenderViewType() == | 618 if (chrome::GetViewType(web_contents) == |
612 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 619 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
613 const Extension* extension = GetExtensionForRenderViewHost( | 620 const Extension* extension = GetExtensionForRenderViewHost( |
614 render_view_host); | 621 render_view_host); |
615 if (extension) | 622 if (extension) |
616 DecrementLazyKeepaliveCount(extension); | 623 DecrementLazyKeepaliveCount(extension); |
617 } | 624 } |
618 break; | 625 break; |
619 } | 626 } |
620 | 627 |
621 default: | 628 default: |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 iter != all_extension_views_.end(); ++iter) { | 703 iter != all_extension_views_.end(); ++iter) { |
697 result.insert(iter->first); | 704 result.insert(iter->first); |
698 } | 705 } |
699 return result; | 706 return result; |
700 } | 707 } |
701 | 708 |
702 ExtensionHost* IncognitoExtensionProcessManager::CreateViewHost( | 709 ExtensionHost* IncognitoExtensionProcessManager::CreateViewHost( |
703 const Extension* extension, | 710 const Extension* extension, |
704 const GURL& url, | 711 const GURL& url, |
705 Browser* browser, | 712 Browser* browser, |
706 content::ViewType view_type) { | 713 chrome::ViewType view_type) { |
707 if (extension->incognito_split_mode()) { | 714 if (extension->incognito_split_mode()) { |
708 if (IsIncognitoEnabled(extension)) { | 715 if (IsIncognitoEnabled(extension)) { |
709 return ExtensionProcessManager::CreateViewHost(extension, url, | 716 return ExtensionProcessManager::CreateViewHost(extension, url, |
710 browser, view_type); | 717 browser, view_type); |
711 } else { | 718 } else { |
712 NOTREACHED() << | 719 NOTREACHED() << |
713 "We shouldn't be trying to create an incognito extension view unless " | 720 "We shouldn't be trying to create an incognito extension view unless " |
714 "it has been enabled for incognito."; | 721 "it has been enabled for incognito."; |
715 return NULL; | 722 return NULL; |
716 } | 723 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 if (service && service->is_ready()) | 775 if (service && service->is_ready()) |
769 CreateBackgroundHostsForProfileStartup(this, service->extensions()); | 776 CreateBackgroundHostsForProfileStartup(this, service->extensions()); |
770 } | 777 } |
771 break; | 778 break; |
772 } | 779 } |
773 default: | 780 default: |
774 ExtensionProcessManager::Observe(type, source, details); | 781 ExtensionProcessManager::Observe(type, source, details); |
775 break; | 782 break; |
776 } | 783 } |
777 } | 784 } |
OLD | NEW |