[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 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/renderer_startup_helper.h" |
| 6 | |
Takashi Toyoshima | 6957907 | 2018-11-19 07:10:50 | [diff] [blame^] | 7 | #include <utility> |
| 8 | #include <vector> |
| 9 | |
| 10 | #include "base/bind_helpers.h" |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 11 | #include "base/debug/dump_without_crashing.h" |
Takashi Toyoshima | 6957907 | 2018-11-19 07:10:50 | [diff] [blame^] | 12 | #include "base/feature_list.h" |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 13 | #include "base/stl_util.h" |
| 14 | #include "base/strings/string_util.h" |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 15 | #include "base/values.h" |
[email protected] | b33f0b11 | 2014-03-13 17:05:30 | [diff] [blame] | 16 | #include "components/keyed_service/content/browser_context_dependency_manager.h" |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 17 | #include "content/public/browser/browser_context.h" |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 18 | #include "content/public/browser/notification_service.h" |
| 19 | #include "content/public/browser/notification_types.h" |
| 20 | #include "content/public/browser/render_process_host.h" |
[email protected] | 0b9de03 | 2014-03-15 05:47:01 | [diff] [blame] | 21 | #include "extensions/browser/extension_function_dispatcher.h" |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 22 | #include "extensions/browser/extension_registry.h" |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 23 | #include "extensions/browser/extension_util.h" |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 24 | #include "extensions/browser/extensions_browser_client.h" |
paulmeyer | ad727fc6 | 2015-09-09 15:29:59 | [diff] [blame] | 25 | #include "extensions/browser/guest_view/web_view/web_view_guest.h" |
Takashi Toyoshima | 6957907 | 2018-11-19 07:10:50 | [diff] [blame^] | 26 | #include "extensions/common/cors_util.h" |
[email protected] | fb820c0 | 2014-03-13 15:07:08 | [diff] [blame] | 27 | #include "extensions/common/extension_messages.h" |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 28 | #include "extensions/common/extension_set.h" |
| 29 | #include "extensions/common/extensions_client.h" |
rdevlin.cronin | ea63fff | 2016-07-18 15:49:35 | [diff] [blame] | 30 | #include "extensions/common/features/feature_channel.h" |
tbarzic | c34cf3c | 2016-09-09 20:15:09 | [diff] [blame] | 31 | #include "extensions/common/features/feature_session_type.h" |
nrpeter | e33d2a5b | 2017-04-25 00:12:31 | [diff] [blame] | 32 | #include "extensions/common/permissions/permissions_data.h" |
Takashi Toyoshima | 6957907 | 2018-11-19 07:10:50 | [diff] [blame^] | 33 | #include "services/network/public/cpp/features.h" |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 34 | #include "ui/base/webui/web_ui_util.h" |
Takashi Toyoshima | 6957907 | 2018-11-19 07:10:50 | [diff] [blame^] | 35 | #include "url/origin.h" |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 36 | |
| 37 | using content::BrowserContext; |
| 38 | |
| 39 | namespace extensions { |
| 40 | |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 41 | namespace { |
| 42 | |
| 43 | // Returns whether the |extension| should be loaded in the given |
| 44 | // |browser_context|. |
| 45 | bool IsExtensionVisibleToContext(const Extension& extension, |
| 46 | content::BrowserContext* browser_context) { |
| 47 | // Renderers don't need to know about themes. |
| 48 | if (extension.is_theme()) |
| 49 | return false; |
| 50 | |
| 51 | // Only extensions enabled in incognito mode should be loaded in an incognito |
| 52 | // renderer. However extensions which can't be enabled in the incognito mode |
| 53 | // (e.g. platform apps) should also be loaded in an incognito renderer to |
| 54 | // ensure connections from incognito tabs to such extensions work. |
| 55 | return !browser_context->IsOffTheRecord() || |
| 56 | !util::CanBeIncognitoEnabled(&extension) || |
| 57 | util::IsIncognitoEnabled(extension.id(), browser_context); |
| 58 | } |
| 59 | |
| 60 | } // namespace |
| 61 | |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 62 | RendererStartupHelper::RendererStartupHelper(BrowserContext* browser_context) |
| 63 | : browser_context_(browser_context) { |
| 64 | DCHECK(browser_context); |
| 65 | registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
| 66 | content::NotificationService::AllBrowserContextsAndSources()); |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 67 | registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 68 | content::NotificationService::AllBrowserContextsAndSources()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 69 | registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 70 | content::NotificationService::AllBrowserContextsAndSources()); |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 71 | } |
| 72 | |
| 73 | RendererStartupHelper::~RendererStartupHelper() {} |
| 74 | |
| 75 | void RendererStartupHelper::Observe( |
| 76 | int type, |
| 77 | const content::NotificationSource& source, |
| 78 | const content::NotificationDetails& details) { |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 79 | switch (type) { |
| 80 | case content::NOTIFICATION_RENDERER_PROCESS_CREATED: |
| 81 | InitializeProcess( |
| 82 | content::Source<content::RenderProcessHost>(source).ptr()); |
| 83 | break; |
| 84 | case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 85 | // Fall through. |
| 86 | case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: |
| 87 | // This is needed to take care of the case when a RenderProcessHost is |
| 88 | // reused for a different renderer process. |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 89 | UntrackProcess(content::Source<content::RenderProcessHost>(source).ptr()); |
| 90 | break; |
| 91 | default: |
| 92 | NOTREACHED() << "Unexpected notification: " << type; |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | void RendererStartupHelper::InitializeProcess( |
| 97 | content::RenderProcessHost* process) { |
rdevlin.cronin | 6fba7ec | 2016-06-24 16:15:05 | [diff] [blame] | 98 | ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); |
| 99 | if (!client->IsSameContext(browser_context_, process->GetBrowserContext())) |
kalman | 8bcbc759 | 2015-06-03 23:12:27 | [diff] [blame] | 100 | return; |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 101 | |
rdevlin.cronin | 6fba7ec | 2016-06-24 16:15:05 | [diff] [blame] | 102 | bool activity_logging_enabled = |
| 103 | client->IsActivityLoggingEnabled(process->GetBrowserContext()); |
| 104 | // We only send the ActivityLoggingEnabled message if it is enabled; otherwise |
| 105 | // the default (not enabled) is correct. |
| 106 | if (activity_logging_enabled) { |
| 107 | process->Send( |
| 108 | new ExtensionMsg_SetActivityLoggingEnabled(activity_logging_enabled)); |
| 109 | } |
| 110 | |
tbarzic | c34cf3c | 2016-09-09 20:15:09 | [diff] [blame] | 111 | // Extensions need to know the channel and the session type for API |
| 112 | // restrictions. The values are sent to all renderers, as the non-extension |
| 113 | // renderers may have content scripts. |
tbarzic | 8e89b0b1 | 2017-06-10 03:25:51 | [diff] [blame] | 114 | bool is_lock_screen_context = |
| 115 | client->IsLockScreenContext(process->GetBrowserContext()); |
| 116 | process->Send(new ExtensionMsg_SetSessionInfo(GetCurrentChannel(), |
| 117 | GetCurrentFeatureSessionType(), |
| 118 | is_lock_screen_context)); |
rdevlin.cronin | ea63fff | 2016-07-18 15:49:35 | [diff] [blame] | 119 | |
kalman | 8bcbc759 | 2015-06-03 23:12:27 | [diff] [blame] | 120 | // Platform apps need to know the system font. |
| 121 | // TODO(dbeam): this is not the system font in all cases. |
| 122 | process->Send(new ExtensionMsg_SetSystemFont(webui::GetFontFamily(), |
| 123 | webui::GetFontSize())); |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 124 | |
kalman | 8bcbc759 | 2015-06-03 23:12:27 | [diff] [blame] | 125 | // Scripting whitelist. This is modified by tests and must be communicated |
| 126 | // to renderers. |
| 127 | process->Send(new ExtensionMsg_SetScriptingWhitelist( |
| 128 | extensions::ExtensionsClient::Get()->GetScriptingWhitelist())); |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 129 | |
paulmeyer | ad727fc6 | 2015-09-09 15:29:59 | [diff] [blame] | 130 | // If the new render process is a WebView guest process, propagate the WebView |
| 131 | // partition ID to it. |
| 132 | std::string webview_partition_id = WebViewGuest::GetPartitionID(process); |
| 133 | if (!webview_partition_id.empty()) { |
| 134 | process->Send(new ExtensionMsg_SetWebViewPartitionID( |
| 135 | WebViewGuest::GetPartitionID(process))); |
| 136 | } |
| 137 | |
nrpeter | e33d2a5b | 2017-04-25 00:12:31 | [diff] [blame] | 138 | // Load default policy_blocked_hosts and policy_allowed_hosts settings, part |
| 139 | // of the ExtensionSettings policy. |
| 140 | ExtensionMsg_UpdateDefaultPolicyHostRestrictions_Params params; |
| 141 | params.default_policy_blocked_hosts = |
| 142 | PermissionsData::default_policy_blocked_hosts(); |
| 143 | params.default_policy_allowed_hosts = |
| 144 | PermissionsData::default_policy_allowed_hosts(); |
| 145 | process->Send(new ExtensionMsg_UpdateDefaultPolicyHostRestrictions(params)); |
| 146 | |
kalman | 8bcbc759 | 2015-06-03 23:12:27 | [diff] [blame] | 147 | // Loaded extensions. |
| 148 | std::vector<ExtensionMsg_Loaded_Params> loaded_extensions; |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 149 | BrowserContext* renderer_context = process->GetBrowserContext(); |
kalman | 8bcbc759 | 2015-06-03 23:12:27 | [diff] [blame] | 150 | const ExtensionSet& extensions = |
| 151 | ExtensionRegistry::Get(browser_context_)->enabled_extensions(); |
| 152 | for (const auto& ext : extensions) { |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 153 | // OnLoadedExtension should have already been called for the extension. |
| 154 | DCHECK(base::ContainsKey(extension_process_map_, ext->id())); |
| 155 | DCHECK(!base::ContainsKey(extension_process_map_[ext->id()], process)); |
| 156 | |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 157 | if (!IsExtensionVisibleToContext(*ext, renderer_context)) |
| 158 | continue; |
| 159 | |
| 160 | // TODO(kalman): Only include tab specific permissions for extension |
| 161 | // processes, no other process needs it, so it's mildly wasteful. |
| 162 | // I am not sure this is possible to know this here, at such a low |
| 163 | // level of the stack. Perhaps site isolation can help. |
| 164 | bool include_tab_permissions = true; |
| 165 | loaded_extensions.push_back( |
| 166 | ExtensionMsg_Loaded_Params(ext.get(), include_tab_permissions)); |
| 167 | extension_process_map_[ext->id()].insert(process); |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 168 | } |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 169 | |
| 170 | // Activate pending extensions. |
kalman | 8bcbc759 | 2015-06-03 23:12:27 | [diff] [blame] | 171 | process->Send(new ExtensionMsg_Loaded(loaded_extensions)); |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 172 | auto iter = pending_active_extensions_.find(process); |
| 173 | if (iter != pending_active_extensions_.end()) { |
| 174 | for (const ExtensionId& id : iter->second) { |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 175 | // The extension should be loaded in the process. |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 176 | DCHECK(extensions.Contains(id)); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 177 | DCHECK(base::ContainsKey(extension_process_map_, id)); |
| 178 | DCHECK(base::ContainsKey(extension_process_map_[id], process)); |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 179 | process->Send(new ExtensionMsg_ActivateExtension(id)); |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | initialized_processes_.insert(process); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 184 | pending_active_extensions_.erase(process); |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 185 | } |
| 186 | |
| 187 | void RendererStartupHelper::UntrackProcess( |
| 188 | content::RenderProcessHost* process) { |
| 189 | if (!ExtensionsBrowserClient::Get()->IsSameContext( |
| 190 | browser_context_, process->GetBrowserContext())) { |
| 191 | return; |
| 192 | } |
| 193 | |
| 194 | initialized_processes_.erase(process); |
| 195 | pending_active_extensions_.erase(process); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 196 | for (auto& extension_process_pair : extension_process_map_) |
| 197 | extension_process_pair.second.erase(process); |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 198 | } |
| 199 | |
| 200 | void RendererStartupHelper::ActivateExtensionInProcess( |
rdevlin.cronin | c40d39f | 2016-08-04 23:42:13 | [diff] [blame] | 201 | const Extension& extension, |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 202 | content::RenderProcessHost* process) { |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 203 | // The extension should have been loaded already. Dump without crashing to |
| 204 | // debug crbug.com/528026. |
| 205 | if (!base::ContainsKey(extension_process_map_, extension.id())) { |
| 206 | #if DCHECK_IS_ON() |
| 207 | NOTREACHED() << "Extension " << extension.id() |
| 208 | << "activated before loading"; |
| 209 | #else |
| 210 | base::debug::DumpWithoutCrashing(); |
| 211 | return; |
| 212 | #endif |
| 213 | } |
| 214 | |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 215 | if (!IsExtensionVisibleToContext(extension, process->GetBrowserContext())) |
rdevlin.cronin | c40d39f | 2016-08-04 23:42:13 | [diff] [blame] | 216 | return; |
| 217 | |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 218 | if (base::ContainsKey(initialized_processes_, process)) { |
| 219 | DCHECK(base::ContainsKey(extension_process_map_[extension.id()], process)); |
rdevlin.cronin | c40d39f | 2016-08-04 23:42:13 | [diff] [blame] | 220 | process->Send(new ExtensionMsg_ActivateExtension(extension.id())); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 221 | } else { |
rdevlin.cronin | c40d39f | 2016-08-04 23:42:13 | [diff] [blame] | 222 | pending_active_extensions_[process].insert(extension.id()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 223 | } |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 224 | } |
| 225 | |
| 226 | void RendererStartupHelper::OnExtensionLoaded(const Extension& extension) { |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 227 | // Extension was already loaded. |
| 228 | // TODO(crbug.com/708230): Ensure that clients don't call this for an |
| 229 | // already loaded extension and change this to a DCHECK. |
| 230 | if (base::ContainsKey(extension_process_map_, extension.id())) |
| 231 | return; |
| 232 | |
| 233 | // Mark the extension as loaded. |
| 234 | std::set<content::RenderProcessHost*>& loaded_process_set = |
| 235 | extension_process_map_[extension.id()]; |
| 236 | |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 237 | // IsExtensionVisibleToContext() would filter out themes, but we choose to |
| 238 | // return early for performance reasons. |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 239 | if (extension.is_theme()) |
| 240 | return; |
| 241 | |
Takashi Toyoshima | 6957907 | 2018-11-19 07:10:50 | [diff] [blame^] | 242 | // Registers the initial origin access lists to the BrowserContext |
| 243 | // asynchronously. |
| 244 | url::Origin extension_origin = url::Origin::Create(extension.url()); |
| 245 | std::vector<network::mojom::CorsOriginPatternPtr> allow_list = |
| 246 | CreateCorsOriginAccessAllowList(extension); |
| 247 | if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { |
| 248 | ExtensionsClient::Get()->AddOriginAccessPermissions(extension, true, |
| 249 | &allow_list); |
| 250 | } |
| 251 | |
| 252 | content::BrowserContext::SetCorsOriginAccessListsForOrigin( |
| 253 | browser_context_, extension_origin, std::move(allow_list), |
| 254 | CreateCorsOriginAccessBlockList(extension), base::DoNothing::Once()); |
| 255 | |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 256 | // We don't need to include tab permisisons here, since the extension |
| 257 | // was just loaded. |
| 258 | // Uninitialized renderers will be informed of the extension load during the |
| 259 | // first batch of messages. |
Istiaque Ahmed | abb887f | 2018-07-12 16:59:51 | [diff] [blame] | 260 | std::vector<ExtensionMsg_Loaded_Params> params; |
| 261 | params.emplace_back(&extension, false /* no tab permissions */); |
| 262 | |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 263 | for (content::RenderProcessHost* process : initialized_processes_) { |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 264 | if (!IsExtensionVisibleToContext(extension, process->GetBrowserContext())) |
| 265 | continue; |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 266 | process->Send(new ExtensionMsg_Loaded(params)); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 267 | loaded_process_set.insert(process); |
| 268 | } |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 269 | } |
| 270 | |
rdevlin.cronin | c40d39f | 2016-08-04 23:42:13 | [diff] [blame] | 271 | void RendererStartupHelper::OnExtensionUnloaded(const Extension& extension) { |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 272 | // Extension is not loaded. |
| 273 | // TODO(crbug.com/708230): Ensure that clients call this for a loaded |
| 274 | // extension only and change this to a DCHECK. |
| 275 | if (!base::ContainsKey(extension_process_map_, extension.id())) |
rdevlin.cronin | c40d39f | 2016-08-04 23:42:13 | [diff] [blame] | 276 | return; |
| 277 | |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 278 | const std::set<content::RenderProcessHost*>& loaded_process_set = |
| 279 | extension_process_map_[extension.id()]; |
| 280 | for (content::RenderProcessHost* process : loaded_process_set) { |
| 281 | DCHECK(base::ContainsKey(initialized_processes_, process)); |
rdevlin.cronin | c40d39f | 2016-08-04 23:42:13 | [diff] [blame] | 282 | process->Send(new ExtensionMsg_Unloaded(extension.id())); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 283 | } |
| 284 | |
Takashi Toyoshima | 6957907 | 2018-11-19 07:10:50 | [diff] [blame^] | 285 | // Resets registered origin access lists in the BrowserContext asynchronously. |
| 286 | url::Origin extension_origin = url::Origin::Create(extension.url()); |
| 287 | content::BrowserContext::SetCorsOriginAccessListsForOrigin( |
| 288 | browser_context_, extension_origin, |
| 289 | std::vector<network::mojom::CorsOriginPatternPtr>(), |
| 290 | std::vector<network::mojom::CorsOriginPatternPtr>(), |
| 291 | base::DoNothing::Once()); |
| 292 | |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 293 | for (auto& process_extensions_pair : pending_active_extensions_) |
rdevlin.cronin | c40d39f | 2016-08-04 23:42:13 | [diff] [blame] | 294 | process_extensions_pair.second.erase(extension.id()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 295 | |
| 296 | // Mark the extension as unloaded. |
| 297 | extension_process_map_.erase(extension.id()); |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 298 | } |
| 299 | |
| 300 | ////////////////////////////////////////////////////////////////////////////// |
| 301 | |
| 302 | // static |
| 303 | RendererStartupHelper* RendererStartupHelperFactory::GetForBrowserContext( |
| 304 | BrowserContext* context) { |
| 305 | return static_cast<RendererStartupHelper*>( |
| 306 | GetInstance()->GetServiceForBrowserContext(context, true)); |
| 307 | } |
| 308 | |
| 309 | // static |
| 310 | RendererStartupHelperFactory* RendererStartupHelperFactory::GetInstance() { |
olli.raula | 36aa8be | 2015-09-10 11:14:22 | [diff] [blame] | 311 | return base::Singleton<RendererStartupHelperFactory>::get(); |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 312 | } |
| 313 | |
| 314 | RendererStartupHelperFactory::RendererStartupHelperFactory() |
| 315 | : BrowserContextKeyedServiceFactory( |
| 316 | "RendererStartupHelper", |
| 317 | BrowserContextDependencyManager::GetInstance()) { |
| 318 | // No dependencies on other services. |
| 319 | } |
| 320 | |
| 321 | RendererStartupHelperFactory::~RendererStartupHelperFactory() {} |
| 322 | |
[email protected] | b33f0b11 | 2014-03-13 17:05:30 | [diff] [blame] | 323 | KeyedService* RendererStartupHelperFactory::BuildServiceInstanceFor( |
[email protected] | 44366da1 | 2014-01-28 01:38:41 | [diff] [blame] | 324 | content::BrowserContext* context) const { |
| 325 | return new RendererStartupHelper(context); |
| 326 | } |
| 327 | |
| 328 | BrowserContext* RendererStartupHelperFactory::GetBrowserContextToUse( |
| 329 | BrowserContext* context) const { |
| 330 | // Redirected in incognito. |
| 331 | return ExtensionsBrowserClient::Get()->GetOriginalContext(context); |
| 332 | } |
| 333 | |
| 334 | bool RendererStartupHelperFactory::ServiceIsCreatedWithBrowserContext() const { |
| 335 | return true; |
| 336 | } |
| 337 | |
| 338 | } // namespace extensions |