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.
5 #include "extensions/shell/browser/shell_nacl_browser_delegate.h"
9 #include "base/base_paths.h"
10 #include "base/command_line.h"
11 #include "base/path_service.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h"
14 #include "content/public/browser/browser_context.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/render_frame_host.h"
17 #include "content/public/browser/site_instance.h"
18 #include "extensions/browser/extension_system.h"
19 #include "extensions/browser/info_map.h"
20 #include "extensions/browser/process_manager.h"
21 #include "extensions/common/constants.h"
22 #include "extensions/common/extension.h"
23 #include "extensions/common/url_pattern.h"
24 #include "extensions/shell/common/version.h" // Generated file.
27 using content::BrowserContext
;
28 using content::BrowserThread
;
29 using content::BrowserPpapiHost
;
31 namespace extensions
{
34 // Handles an extension's NaCl process transitioning in or out of idle state by
35 // relaying the state to the extension's process manager. See Chrome's
36 // NaClBrowserDelegateImpl for another example.
37 void OnKeepaliveOnUIThread(
38 const BrowserPpapiHost::OnKeepaliveInstanceData
& instance_data
,
39 const base::FilePath
& profile_data_directory
) {
40 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
42 // Only one instance will exist for NaCl embeds, even when more than one
43 // embed of the same plugin exists on the same page.
44 DCHECK(instance_data
.size() == 1);
45 if (instance_data
.size() < 1)
48 ProcessManager::OnKeepaliveFromPlugin(instance_data
[0].render_process_id
,
49 instance_data
[0].render_frame_id
,
50 instance_data
[0].document_url
.host());
53 // Calls OnKeepaliveOnUIThread on UI thread.
54 void OnKeepalive(const BrowserPpapiHost::OnKeepaliveInstanceData
& instance_data
,
55 const base::FilePath
& profile_data_directory
) {
56 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
57 BrowserThread::PostTask(
61 &OnKeepaliveOnUIThread
, instance_data
, profile_data_directory
));
66 ShellNaClBrowserDelegate::ShellNaClBrowserDelegate(BrowserContext
* context
)
67 : browser_context_(context
) {
68 DCHECK(browser_context_
);
71 ShellNaClBrowserDelegate::~ShellNaClBrowserDelegate() {
74 void ShellNaClBrowserDelegate::ShowMissingArchInfobar(int render_process_id
,
76 // app_shell does not have infobars.
77 LOG(ERROR
) << "Missing architecture for pid " << render_process_id
;
80 bool ShellNaClBrowserDelegate::DialogsAreSuppressed() {
84 bool ShellNaClBrowserDelegate::GetCacheDirectory(base::FilePath
* cache_dir
) {
85 // Just use the general cache directory, not a subdirectory like Chrome does.
87 return PathService::Get(base::DIR_CACHE
, cache_dir
);
89 // TODO(yoz): Find an appropriate persistent directory to use here.
90 return PathService::Get(base::DIR_TEMP
, cache_dir
);
94 bool ShellNaClBrowserDelegate::GetPluginDirectory(base::FilePath
* plugin_dir
) {
95 // On Posix, plugins are in the module directory.
96 return PathService::Get(base::DIR_MODULE
, plugin_dir
);
99 bool ShellNaClBrowserDelegate::GetPnaclDirectory(base::FilePath
* pnacl_dir
) {
100 // On Posix, the pnacl directory is inside the plugin directory.
101 base::FilePath plugin_dir
;
102 if (!GetPluginDirectory(&plugin_dir
))
104 *pnacl_dir
= plugin_dir
.Append(FILE_PATH_LITERAL("pnacl"));
108 bool ShellNaClBrowserDelegate::GetUserDirectory(base::FilePath
* user_dir
) {
109 base::FilePath path
= browser_context_
->GetPath();
117 std::string
ShellNaClBrowserDelegate::GetVersionString() const {
118 // A version change triggers an update of the NaCl validation caches.
119 // Example version: "39.0.2129.0 (290550)".
120 return PRODUCT_VERSION
" (" LAST_CHANGE
")";
123 ppapi::host::HostFactory
* ShellNaClBrowserDelegate::CreatePpapiHostFactory(
124 content::BrowserPpapiHost
* ppapi_host
) {
128 void ShellNaClBrowserDelegate::SetDebugPatterns(
129 const std::string
& debug_patterns
) {
130 // No debugger support. Developers should use Chrome for debugging.
133 bool ShellNaClBrowserDelegate::URLMatchesDebugPatterns(
134 const GURL
& manifest_url
) {
135 // No debugger support. Developers should use Chrome for debugging.
139 // This function is security sensitive. Be sure to check with a security
140 // person before you modify it.
141 // TODO(jamescook): Refactor this code into the extensions module so it can
142 // be shared with Chrome's NaClBrowserDelegateImpl. http://crbug.com/403017
143 bool ShellNaClBrowserDelegate::MapUrlToLocalFilePath(
144 const GURL
& file_url
,
145 bool use_blocking_api
,
146 const base::FilePath
& profile_directory
,
147 base::FilePath
* file_path
) {
148 scoped_refptr
<InfoMap
> info_map
=
149 ExtensionSystem::Get(browser_context_
)->info_map();
150 // Check that the URL is recognized by the extension system.
151 const Extension
* extension
=
152 info_map
->extensions().GetExtensionOrAppByURL(file_url
);
156 // This is a short-cut which avoids calling a blocking file operation
157 // (GetFilePath()), so that this can be called on the IO thread. It only
158 // handles a subset of the urls.
159 if (!use_blocking_api
) {
160 if (file_url
.SchemeIs(kExtensionScheme
)) {
161 std::string path
= file_url
.path();
162 base::TrimString(path
, "/", &path
); // Remove first slash
163 *file_path
= extension
->path().AppendASCII(path
);
169 // Check that the URL references a resource in the extension.
170 // NOTE: app_shell does not support shared modules.
171 ExtensionResource resource
= extension
->GetResource(file_url
.path());
172 if (resource
.empty())
175 // GetFilePath is a blocking function call.
176 const base::FilePath resource_file_path
= resource
.GetFilePath();
177 if (resource_file_path
.empty())
180 *file_path
= resource_file_path
;
184 content::BrowserPpapiHost::OnKeepaliveCallback
185 ShellNaClBrowserDelegate::GetOnKeepaliveCallback() {
186 return base::Bind(&OnKeepalive
);
189 bool ShellNaClBrowserDelegate::IsNonSfiModeAllowed(
190 const base::FilePath
& profile_directory
,
191 const GURL
& manifest_url
) {
195 } // namespace extensions