OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "extensions/browser/api/runtime/runtime_event_router.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/values.h" | |
10 #include "base/version.h" | |
11 #include "content/public/browser/browser_context.h" | |
12 #include "extensions/browser/event_router.h" | |
13 #include "extensions/browser/extension_registry.h" | |
14 #include "extensions/browser/extension_system.h" | |
15 #include "extensions/browser/extensions_browser_client.h" | |
16 #include "extensions/browser/lazy_background_task_queue.h" | |
17 #include "extensions/common/manifest_handlers/background_info.h" | |
18 | |
19 using content::BrowserContext; | |
20 | |
21 namespace extensions { | |
22 | |
23 namespace runtime = api::runtime; | |
24 | |
25 namespace { | |
26 | |
27 const char kInstallReason[] = "reason"; | |
28 const char kInstallReasonChromeUpdate[] = "chrome_update"; | |
29 const char kInstallReasonUpdate[] = "update"; | |
30 const char kInstallReasonInstall[] = "install"; | |
31 const char kInstallPreviousVersion[] = "previousVersion"; | |
32 | |
33 // Dispatches the onStartup event. May do so by posting a task if the extension | |
34 // background page has not yet loaded. | |
35 void DispatchOnStartupEventImpl(BrowserContext* browser_context, | |
36 const std::string& extension_id, | |
37 bool first_call, | |
38 ExtensionHost* host) { | |
39 // A NULL host from the LazyBackgroundTaskQueue means the page failed to | |
40 // load. Give up. | |
41 if (!host && !first_call) | |
42 return; | |
43 | |
44 // Don't send onStartup events to incognito browser contexts. | |
45 if (browser_context->IsOffTheRecord()) | |
46 return; | |
47 | |
48 if (ExtensionsBrowserClient::Get()->IsShuttingDown() || | |
49 !ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) | |
50 return; | |
51 ExtensionSystem* system = ExtensionSystem::Get(browser_context); | |
52 if (!system) | |
53 return; | |
54 | |
55 // If this is a persistent background page, we want to wait for it to load | |
56 // (it might not be ready, since this is startup). But only enqueue once. | |
57 // If it fails to load the first time, don't bother trying again. | |
58 const Extension* extension = | |
59 ExtensionRegistry::Get(browser_context) | |
60 ->GetExtensionById(extension_id, ExtensionRegistry::ENABLED); | |
61 LazyBackgroundTaskQueue* queue = system->lazy_background_task_queue(); | |
62 if (extension && BackgroundInfo::HasPersistentBackgroundPage(extension) && | |
63 first_call && queue->ShouldEnqueueTask(browser_context, extension)) { | |
64 queue->AddPendingTask( | |
65 browser_context, | |
66 extension_id, | |
67 base::Bind( | |
68 &DispatchOnStartupEventImpl, browser_context, extension_id, false)); | |
69 return; | |
70 } | |
71 | |
72 scoped_ptr<base::ListValue> event_args(new base::ListValue()); | |
73 scoped_ptr<Event> event( | |
74 new Event(runtime::OnStartup::kEventName, event_args.Pass())); | |
75 system->event_router()->DispatchEventToExtension(extension_id, event.Pass()); | |
76 } | |
77 | |
78 } // namespace | |
79 | |
80 // static | |
81 void RuntimeEventRouter::DispatchOnStartupEvent( | |
82 BrowserContext* context, | |
83 const std::string& extension_id) { | |
84 DispatchOnStartupEventImpl(context, extension_id, true, NULL); | |
85 } | |
86 | |
87 // static | |
88 void RuntimeEventRouter::DispatchOnInstalledEvent( | |
89 BrowserContext* context, | |
90 const std::string& extension_id, | |
91 const base::Version& old_version, | |
92 bool chrome_updated) { | |
93 if (!ExtensionsBrowserClient::Get()->IsValidContext(context)) | |
94 return; | |
95 ExtensionSystem* system = ExtensionSystem::Get(context); | |
96 if (!system) | |
97 return; | |
98 | |
99 scoped_ptr<base::ListValue> event_args(new base::ListValue()); | |
100 base::DictionaryValue* info = new base::DictionaryValue(); | |
101 event_args->Append(info); | |
102 if (old_version.IsValid()) { | |
103 info->SetString(kInstallReason, kInstallReasonUpdate); | |
104 info->SetString(kInstallPreviousVersion, old_version.GetString()); | |
105 } else if (chrome_updated) { | |
106 info->SetString(kInstallReason, kInstallReasonChromeUpdate); | |
107 } else { | |
108 info->SetString(kInstallReason, kInstallReasonInstall); | |
109 } | |
110 DCHECK(system->event_router()); | |
111 scoped_ptr<Event> event( | |
112 new Event(runtime::OnInstalled::kEventName, event_args.Pass())); | |
113 system->event_router()->DispatchEventWithLazyListener(extension_id, | |
114 event.Pass()); | |
115 } | |
116 | |
117 // static | |
118 void RuntimeEventRouter::DispatchOnUpdateAvailableEvent( | |
119 BrowserContext* context, | |
120 const std::string& extension_id, | |
121 const base::DictionaryValue* manifest) { | |
122 ExtensionSystem* system = ExtensionSystem::Get(context); | |
123 if (!system) | |
124 return; | |
125 | |
126 scoped_ptr<base::ListValue> args(new base::ListValue); | |
127 args->Append(manifest->DeepCopy()); | |
128 DCHECK(system->event_router()); | |
129 scoped_ptr<Event> event( | |
130 new Event(runtime::OnUpdateAvailable::kEventName, args.Pass())); | |
131 system->event_router()->DispatchEventToExtension(extension_id, event.Pass()); | |
132 } | |
133 | |
134 // static | |
135 void RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent( | |
136 BrowserContext* context) { | |
137 ExtensionSystem* system = ExtensionSystem::Get(context); | |
138 if (!system) | |
139 return; | |
140 | |
141 scoped_ptr<base::ListValue> args(new base::ListValue); | |
142 DCHECK(system->event_router()); | |
143 scoped_ptr<Event> event( | |
144 new Event(runtime::OnBrowserUpdateAvailable::kEventName, args.Pass())); | |
145 system->event_router()->BroadcastEvent(event.Pass()); | |
146 } | |
147 | |
148 // static | |
149 void RuntimeEventRouter::DispatchOnRestartRequiredEvent( | |
150 BrowserContext* context, | |
151 const std::string& app_id, | |
152 api::runtime::OnRestartRequired::Reason reason) { | |
153 ExtensionSystem* system = ExtensionSystem::Get(context); | |
154 if (!system) | |
155 return; | |
156 | |
157 scoped_ptr<Event> event( | |
158 new Event(runtime::OnRestartRequired::kEventName, | |
159 api::runtime::OnRestartRequired::Create(reason))); | |
160 | |
161 DCHECK(system->event_router()); | |
162 system->event_router()->DispatchEventToExtension(app_id, event.Pass()); | |
163 } | |
164 | |
165 } // namespace extensions | |
OLD | NEW |