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 |