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 3 // found in the LICENSE file. 4 5 #include "chrome/common/chrome_content_client.h" 6 7 #include "base/command_line.h" 8 #include "base/debug/crash_logging.h" 9 #include "base/files/file_util.h" 10 #include "base/path_service.h" 11 #include "base/strings/string16.h" 12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_split.h" 14 #include "base/strings/string_util.h" 15 #include "base/strings/stringprintf.h" 16 #include "base/strings/utf_string_conversions.h" 17 #include "build/build_config.h" 18 #include "chrome/common/child_process_logging.h" 19 #include "chrome/common/chrome_paths.h" 20 #include "chrome/common/chrome_switches.h" 21 #include "chrome/common/chrome_version_info.h" 22 #include "chrome/common/crash_keys.h" 23 #include "chrome/common/render_messages.h" 24 #include "chrome/common/url_constants.h" 25 #include "chrome/grit/common_resources.h" 26 #include "components/dom_distiller/core/url_constants.h" 27 #include "content/public/common/content_constants.h" 28 #include "content/public/common/content_switches.h" 29 #include "content/public/common/url_constants.h" 30 #include "content/public/common/user_agent.h" 31 #include "extensions/common/constants.h" 32 #include "gpu/config/gpu_info.h" 33 #include "net/http/http_util.h" 34 #include "ui/base/l10n/l10n_util.h" 35 #include "ui/base/layout.h" 36 #include "ui/base/resource/resource_bundle.h" 37 38 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. 39 40 #if defined(OS_WIN) 41 #include "base/win/registry.h" 42 #include "base/win/windows_version.h" 43 #elif defined(OS_MACOSX) 44 #include "components/nacl/common/nacl_sandbox_type_mac.h" 45 #endif 46 47 #if !defined(DISABLE_NACL) 48 #include "components/nacl/common/nacl_constants.h" 49 #include "components/nacl/common/nacl_process_type.h" 50 #include "ppapi/native_client/src/trusted/plugin/ppapi_entrypoints.h" 51 #endif 52 53 #if defined(ENABLE_PLUGINS) 54 #include "chrome/common/pepper_flash.h" 55 #include "content/public/common/pepper_plugin_info.h" 56 #include "flapper_version.h" // In SHARED_INTERMEDIATE_DIR. 57 #include "ppapi/shared_impl/ppapi_permissions.h" 58 #endif 59 60 #if defined(ENABLE_REMOTING) 61 #include "remoting/client/plugin/pepper_entrypoints.h" 62 #endif 63 64 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) && \ 65 !defined(WIDEVINE_CDM_IS_COMPONENT) 66 #include "chrome/common/widevine_cdm_constants.h" 67 #endif 68 69 namespace { 70 71 #if defined(ENABLE_PLUGINS) 72 const char kPDFPluginMimeType[] = "application/pdf"; 73 const char kPDFPluginExtension[] = "pdf"; 74 const char kPDFPluginDescription[] = "Portable Document Format"; 75 const char kPDFPluginPrintPreviewMimeType[] = 76 "application/x-google-chrome-print-preview-pdf"; 77 const char kPDFPluginOutOfProcessMimeType[] = 78 "application/x-google-chrome-pdf"; 79 const uint32 kPDFPluginPermissions = ppapi::PERMISSION_PRIVATE | 80 ppapi::PERMISSION_DEV; 81 82 const char kO1DPluginName[] = "Google Talk Plugin Video Renderer"; 83 const char kO1DPluginMimeType[] ="application/o1d"; 84 const char kO1DPluginExtension[] = ""; 85 const char kO1DPluginDescription[] = "Google Talk Plugin Video Renderer"; 86 const uint32 kO1DPluginPermissions = ppapi::PERMISSION_PRIVATE | 87 ppapi::PERMISSION_DEV; 88 89 const char kEffectsPluginName[] = "Google Talk Effects Plugin"; 90 const char kEffectsPluginMimeType[] ="application/x-ppapi-hangouts-effects"; 91 const char kEffectsPluginExtension[] = ""; 92 const char kEffectsPluginDescription[] = "Google Talk Effects Plugin"; 93 const uint32 kEffectsPluginPermissions = ppapi::PERMISSION_PRIVATE | 94 ppapi::PERMISSION_DEV; 95 96 const char kGTalkPluginName[] = "Google Talk Plugin"; 97 const char kGTalkPluginMimeType[] ="application/googletalk"; 98 const char kGTalkPluginExtension[] = ".googletalk"; 99 const char kGTalkPluginDescription[] = "Google Talk Plugin"; 100 const uint32 kGTalkPluginPermissions = ppapi::PERMISSION_PRIVATE | 101 ppapi::PERMISSION_DEV; 102 103 #if defined(ENABLE_REMOTING) 104 #if defined(GOOGLE_CHROME_BUILD) 105 const char kRemotingViewerPluginName[] = "Chrome Remote Desktop Viewer"; 106 #else 107 const char kRemotingViewerPluginName[] = "Chromoting Viewer"; 108 #endif // defined(GOOGLE_CHROME_BUILD) 109 const char kRemotingViewerPluginDescription[] = 110 "This plugin allows you to securely access other computers that have been " 111 "shared with you. To use this plugin you must first install the " 112 "<a href=\"https://chrome.google.com/remotedesktop\">" 113 "Chrome Remote Desktop</a> webapp."; 114 // Use a consistent MIME-type regardless of branding. 115 const char kRemotingViewerPluginMimeType[] = 116 "application/vnd.chromium.remoting-viewer"; 117 const char kRemotingViewerPluginMimeExtension[] = ""; 118 const char kRemotingViewerPluginMimeDescription[] = ""; 119 const uint32 kRemotingViewerPluginPermissions = ppapi::PERMISSION_PRIVATE | 120 ppapi::PERMISSION_DEV; 121 #endif // defined(ENABLE_REMOTING) 122 123 // Appends the known built-in plugins to the given vector. Some built-in 124 // plugins are "internal" which means they are compiled into the Chrome binary, 125 // and some are extra shared libraries distributed with the browser (these are 126 // not marked internal, aside from being automatically registered, they're just 127 // regular plugins). 128 void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) { 129 // PDF. 130 // 131 // Once we're sandboxed, we can't know if the PDF plugin is available or not; 132 // but (on Linux) this function is always called once before we're sandboxed. 133 // So the first time through test if the file is available and then skip the 134 // check on subsequent calls if yes. 135 static bool skip_pdf_file_check = false; 136 base::FilePath path; 137 if (PathService::Get(chrome::FILE_PDF_PLUGIN, &path)) { 138 if (skip_pdf_file_check || base::PathExists(path)) { 139 content::PepperPluginInfo pdf; 140 pdf.path = path; 141 pdf.name = ChromeContentClient::kPDFPluginName; 142 if (CommandLine::ForCurrentProcess()->HasSwitch( 143 switches::kOutOfProcessPdf)) { 144 pdf.is_out_of_process = true; 145 content::WebPluginMimeType pdf_mime_type(kPDFPluginOutOfProcessMimeType, 146 kPDFPluginExtension, 147 kPDFPluginDescription); 148 pdf.mime_types.push_back(pdf_mime_type); 149 // TODO(raymes): Make print preview work with out of process PDF. 150 } else { 151 content::WebPluginMimeType pdf_mime_type(kPDFPluginMimeType, 152 kPDFPluginExtension, 153 kPDFPluginDescription); 154 content::WebPluginMimeType print_preview_pdf_mime_type( 155 kPDFPluginPrintPreviewMimeType, 156 kPDFPluginExtension, 157 kPDFPluginDescription); 158 pdf.mime_types.push_back(pdf_mime_type); 159 pdf.mime_types.push_back(print_preview_pdf_mime_type); 160 } 161 pdf.permissions = kPDFPluginPermissions; 162 plugins->push_back(pdf); 163 164 skip_pdf_file_check = true; 165 } 166 } 167 168 #if !defined(DISABLE_NACL) 169 // Handle Native Client just like the PDF plugin. This means that it is 170 // enabled by default for the non-portable case. This allows apps installed 171 // from the Chrome Web Store to use NaCl even if the command line switch 172 // isn't set. For other uses of NaCl we check for the command line switch. 173 if (PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) { 174 content::PepperPluginInfo nacl; 175 // The nacl plugin is now built into the Chromium binary. 176 nacl.is_internal = true; 177 nacl.path = path; 178 nacl.name = nacl::kNaClPluginName; 179 content::WebPluginMimeType nacl_mime_type(nacl::kNaClPluginMimeType, 180 nacl::kNaClPluginExtension, 181 nacl::kNaClPluginDescription); 182 nacl.mime_types.push_back(nacl_mime_type); 183 content::WebPluginMimeType pnacl_mime_type(nacl::kPnaclPluginMimeType, 184 nacl::kPnaclPluginExtension, 185 nacl::kPnaclPluginDescription); 186 nacl.mime_types.push_back(pnacl_mime_type); 187 nacl.internal_entry_points.get_interface = nacl_plugin::PPP_GetInterface; 188 nacl.internal_entry_points.initialize_module = 189 nacl_plugin::PPP_InitializeModule; 190 nacl.internal_entry_points.shutdown_module = 191 nacl_plugin::PPP_ShutdownModule; 192 nacl.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV; 193 plugins->push_back(nacl); 194 } 195 #endif // !defined(DISABLE_NACL) 196 197 static bool skip_o1d_file_check = false; 198 if (PathService::Get(chrome::FILE_O1D_PLUGIN, &path)) { 199 if (skip_o1d_file_check || base::PathExists(path)) { 200 content::PepperPluginInfo o1d; 201 o1d.path = path; 202 o1d.name = kO1DPluginName; 203 o1d.is_out_of_process = true; 204 o1d.is_sandboxed = false; 205 o1d.permissions = kO1DPluginPermissions; 206 content::WebPluginMimeType o1d_mime_type(kO1DPluginMimeType, 207 kO1DPluginExtension, 208 kO1DPluginDescription); 209 o1d.mime_types.push_back(o1d_mime_type); 210 plugins->push_back(o1d); 211 212 skip_o1d_file_check = true; 213 } 214 } 215 216 // TODO(vrk): Remove this when NaCl effects plugin replaces the ppapi effects 217 // plugin. 218 static bool skip_effects_file_check = false; 219 if (PathService::Get(chrome::FILE_EFFECTS_PLUGIN, &path)) { 220 if (skip_effects_file_check || base::PathExists(path)) { 221 content::PepperPluginInfo effects; 222 effects.path = path; 223 effects.name = kEffectsPluginName; 224 effects.is_out_of_process = true; 225 effects.is_sandboxed = true; 226 effects.permissions = kEffectsPluginPermissions; 227 content::WebPluginMimeType effects_mime_type(kEffectsPluginMimeType, 228 kEffectsPluginExtension, 229 kEffectsPluginDescription); 230 effects.mime_types.push_back(effects_mime_type); 231 plugins->push_back(effects); 232 233 skip_effects_file_check = true; 234 } 235 } 236 237 static bool skip_gtalk_file_check = false; 238 if (PathService::Get(chrome::FILE_GTALK_PLUGIN, &path)) { 239 if (skip_gtalk_file_check || base::PathExists(path)) { 240 content::PepperPluginInfo gtalk; 241 gtalk.path = path; 242 gtalk.name = kGTalkPluginName; 243 gtalk.is_out_of_process = true; 244 gtalk.is_sandboxed = false; 245 gtalk.permissions = kGTalkPluginPermissions; 246 content::WebPluginMimeType gtalk_mime_type(kGTalkPluginMimeType, 247 kGTalkPluginExtension, 248 kGTalkPluginDescription); 249 gtalk.mime_types.push_back(gtalk_mime_type); 250 plugins->push_back(gtalk); 251 252 skip_gtalk_file_check = true; 253 } 254 } 255 256 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) && \ 257 !defined(WIDEVINE_CDM_IS_COMPONENT) 258 static bool skip_widevine_cdm_file_check = false; 259 if (PathService::Get(chrome::FILE_WIDEVINE_CDM_ADAPTER, &path)) { 260 if (skip_widevine_cdm_file_check || base::PathExists(path)) { 261 content::PepperPluginInfo widevine_cdm; 262 widevine_cdm.is_out_of_process = true; 263 widevine_cdm.path = path; 264 widevine_cdm.name = kWidevineCdmDisplayName; 265 widevine_cdm.description = kWidevineCdmDescription + 266 std::string(" (version: ") + 267 WIDEVINE_CDM_VERSION_STRING + ")"; 268 widevine_cdm.version = WIDEVINE_CDM_VERSION_STRING; 269 content::WebPluginMimeType widevine_cdm_mime_type( 270 kWidevineCdmPluginMimeType, 271 kWidevineCdmPluginExtension, 272 kWidevineCdmPluginMimeTypeDescription); 273 274 // Add the supported codecs as if they came from the component manifest. 275 std::vector<std::string> codecs; 276 codecs.push_back(kCdmSupportedCodecVorbis); 277 codecs.push_back(kCdmSupportedCodecVp8); 278 codecs.push_back(kCdmSupportedCodecVp9); 279 #if defined(USE_PROPRIETARY_CODECS) 280 // TODO(ddorwin): Rename these macros to reflect their real meaning: whether the 281 // CDM Chrome was built [and shipped] with support these types. 282 #if defined(WIDEVINE_CDM_AAC_SUPPORT_AVAILABLE) 283 codecs.push_back(kCdmSupportedCodecAac); 284 #endif 285 #if defined(WIDEVINE_CDM_AVC1_SUPPORT_AVAILABLE) 286 codecs.push_back(kCdmSupportedCodecAvc1); 287 #endif 288 #endif // defined(USE_PROPRIETARY_CODECS) 289 std::string codec_string = 290 JoinString(codecs, kCdmSupportedCodecsValueDelimiter); 291 widevine_cdm_mime_type.additional_param_names.push_back( 292 base::ASCIIToUTF16(kCdmSupportedCodecsParamName)); 293 widevine_cdm_mime_type.additional_param_values.push_back( 294 base::ASCIIToUTF16(codec_string)); 295 296 widevine_cdm.mime_types.push_back(widevine_cdm_mime_type); 297 widevine_cdm.permissions = kWidevineCdmPluginPermissions; 298 plugins->push_back(widevine_cdm); 299 300 skip_widevine_cdm_file_check = true; 301 } 302 } 303 #endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) && 304 // !defined(WIDEVINE_CDM_IS_COMPONENT) 305 306 // The Remoting Viewer plugin is built-in. 307 #if defined(ENABLE_REMOTING) 308 content::PepperPluginInfo info; 309 info.is_internal = true; 310 info.is_out_of_process = true; 311 info.name = kRemotingViewerPluginName; 312 info.description = kRemotingViewerPluginDescription; 313 info.path = base::FilePath::FromUTF8Unsafe( 314 ChromeContentClient::kRemotingViewerPluginPath); 315 content::WebPluginMimeType remoting_mime_type( 316 kRemotingViewerPluginMimeType, 317 kRemotingViewerPluginMimeExtension, 318 kRemotingViewerPluginMimeDescription); 319 info.mime_types.push_back(remoting_mime_type); 320 info.internal_entry_points.get_interface = remoting::PPP_GetInterface; 321 info.internal_entry_points.initialize_module = 322 remoting::PPP_InitializeModule; 323 info.internal_entry_points.shutdown_module = remoting::PPP_ShutdownModule; 324 info.permissions = kRemotingViewerPluginPermissions; 325 326 plugins->push_back(info); 327 #endif 328 } 329 330 content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path, 331 const std::string& version) { 332 content::PepperPluginInfo plugin; 333 334 plugin.is_out_of_process = true; 335 plugin.name = content::kFlashPluginName; 336 plugin.path = path; 337 plugin.permissions = kPepperFlashPermissions; 338 339 std::vector<std::string> flash_version_numbers; 340 base::SplitString(version, '.', &flash_version_numbers); 341 if (flash_version_numbers.size() < 1) 342 flash_version_numbers.push_back("11"); 343 // |SplitString()| puts in an empty string given an empty string. :( 344 else if (flash_version_numbers[0].empty()) 345 flash_version_numbers[0] = "11"; 346 if (flash_version_numbers.size() < 2) 347 flash_version_numbers.push_back("2"); 348 if (flash_version_numbers.size() < 3) 349 flash_version_numbers.push_back("999"); 350 if (flash_version_numbers.size() < 4) 351 flash_version_numbers.push_back("999"); 352 // E.g., "Shockwave Flash 10.2 r154": 353 plugin.description = plugin.name + " " + flash_version_numbers[0] + "." + 354 flash_version_numbers[1] + " r" + flash_version_numbers[2]; 355 plugin.version = JoinString(flash_version_numbers, '.'); 356 content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType, 357 content::kFlashPluginSwfExtension, 358 content::kFlashPluginSwfDescription); 359 plugin.mime_types.push_back(swf_mime_type); 360 content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType, 361 content::kFlashPluginSplExtension, 362 content::kFlashPluginSplDescription); 363 plugin.mime_types.push_back(spl_mime_type); 364 365 return plugin; 366 } 367 368 void AddPepperFlashFromCommandLine( 369 std::vector<content::PepperPluginInfo>* plugins) { 370 const CommandLine::StringType flash_path = 371 CommandLine::ForCurrentProcess()->GetSwitchValueNative( 372 switches::kPpapiFlashPath); 373 if (flash_path.empty()) 374 return; 375 376 // Also get the version from the command-line. Should be something like 11.2 377 // or 11.2.123.45. 378 std::string flash_version = 379 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 380 switches::kPpapiFlashVersion); 381 382 plugins->push_back( 383 CreatePepperFlashInfo(base::FilePath(flash_path), flash_version)); 384 } 385 386 bool GetBundledPepperFlash(content::PepperPluginInfo* plugin) { 387 #if defined(FLAPPER_AVAILABLE) 388 CommandLine* command_line = CommandLine::ForCurrentProcess(); 389 390 // Ignore bundled Pepper Flash if there is Pepper Flash specified from the 391 // command-line. 392 if (command_line->HasSwitch(switches::kPpapiFlashPath)) 393 return false; 394 395 bool force_disable = 396 command_line->HasSwitch(switches::kDisableBundledPpapiFlash); 397 if (force_disable) 398 return false; 399 400 base::FilePath flash_path; 401 if (!PathService::Get(chrome::FILE_PEPPER_FLASH_PLUGIN, &flash_path)) 402 return false; 403 404 *plugin = CreatePepperFlashInfo(flash_path, FLAPPER_VERSION_STRING); 405 return true; 406 #else 407 return false; 408 #endif // FLAPPER_AVAILABLE 409 } 410 #endif // defined(ENABLE_PLUGINS) 411 412 std::string GetProduct() { 413 chrome::VersionInfo version_info; 414 return version_info.is_valid() ? 415 version_info.ProductNameAndVersionForUserAgent() : std::string(); 416 } 417 418 } // namespace 419 420 std::string GetUserAgent() { 421 CommandLine* command_line = CommandLine::ForCurrentProcess(); 422 if (command_line->HasSwitch(switches::kUserAgent)) { 423 std::string ua = command_line->GetSwitchValueASCII(switches::kUserAgent); 424 if (net::HttpUtil::IsValidHeaderValue(ua)) 425 return ua; 426 LOG(WARNING) << "Ignored invalid value for flag --" << switches::kUserAgent; 427 } 428 429 std::string product = GetProduct(); 430 #if defined(OS_ANDROID) 431 if (command_line->HasSwitch(switches::kUseMobileUserAgent)) 432 product += " Mobile"; 433 #endif 434 return content::BuildUserAgentFromProduct(product); 435 } 436 437 void ChromeContentClient::SetActiveURL(const GURL& url) { 438 base::debug::SetCrashKeyValue(crash_keys::kActiveURL, 439 url.possibly_invalid_spec()); 440 } 441 442 void ChromeContentClient::SetGpuInfo(const gpu::GPUInfo& gpu_info) { 443 #if !defined(OS_ANDROID) 444 base::debug::SetCrashKeyValue(crash_keys::kGPUVendorID, 445 base::StringPrintf("0x%04x", gpu_info.gpu.vendor_id)); 446 base::debug::SetCrashKeyValue(crash_keys::kGPUDeviceID, 447 base::StringPrintf("0x%04x", gpu_info.gpu.device_id)); 448 #endif 449 base::debug::SetCrashKeyValue(crash_keys::kGPUDriverVersion, 450 gpu_info.driver_version); 451 base::debug::SetCrashKeyValue(crash_keys::kGPUPixelShaderVersion, 452 gpu_info.pixel_shader_version); 453 base::debug::SetCrashKeyValue(crash_keys::kGPUVertexShaderVersion, 454 gpu_info.vertex_shader_version); 455 #if defined(OS_MACOSX) 456 base::debug::SetCrashKeyValue(crash_keys::kGPUGLVersion, gpu_info.gl_version); 457 #elif defined(OS_POSIX) 458 base::debug::SetCrashKeyValue(crash_keys::kGPUVendor, gpu_info.gl_vendor); 459 base::debug::SetCrashKeyValue(crash_keys::kGPURenderer, gpu_info.gl_renderer); 460 #endif 461 } 462 463 void ChromeContentClient::AddPepperPlugins( 464 std::vector<content::PepperPluginInfo>* plugins) { 465 #if defined(ENABLE_PLUGINS) 466 ComputeBuiltInPlugins(plugins); 467 AddPepperFlashFromCommandLine(plugins); 468 469 content::PepperPluginInfo plugin; 470 if (GetBundledPepperFlash(&plugin)) 471 plugins->push_back(plugin); 472 #endif 473 } 474 475 void ChromeContentClient::AddAdditionalSchemes( 476 std::vector<std::string>* standard_schemes, 477 std::vector<std::string>* savable_schemes) { 478 standard_schemes->push_back(extensions::kExtensionScheme); 479 savable_schemes->push_back(extensions::kExtensionScheme); 480 standard_schemes->push_back(chrome::kChromeNativeScheme); 481 standard_schemes->push_back(extensions::kExtensionResourceScheme); 482 savable_schemes->push_back(extensions::kExtensionResourceScheme); 483 standard_schemes->push_back(chrome::kChromeSearchScheme); 484 savable_schemes->push_back(chrome::kChromeSearchScheme); 485 standard_schemes->push_back(dom_distiller::kDomDistillerScheme); 486 savable_schemes->push_back(dom_distiller::kDomDistillerScheme); 487 #if defined(OS_CHROMEOS) 488 standard_schemes->push_back(chrome::kCrosScheme); 489 #endif 490 } 491 492 std::string ChromeContentClient::GetProduct() const { 493 return ::GetProduct(); 494 } 495 496 std::string ChromeContentClient::GetUserAgent() const { 497 return ::GetUserAgent(); 498 } 499 500 base::string16 ChromeContentClient::GetLocalizedString(int message_id) const { 501 return l10n_util::GetStringUTF16(message_id); 502 } 503 504 base::StringPiece ChromeContentClient::GetDataResource( 505 int resource_id, 506 ui::ScaleFactor scale_factor) const { 507 return ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( 508 resource_id, scale_factor); 509 } 510 511 base::RefCountedStaticMemory* ChromeContentClient::GetDataResourceBytes( 512 int resource_id) const { 513 return ResourceBundle::GetSharedInstance().LoadDataResourceBytes(resource_id); 514 } 515 516 gfx::Image& ChromeContentClient::GetNativeImageNamed(int resource_id) const { 517 return ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id); 518 } 519 520 std::string ChromeContentClient::GetProcessTypeNameInEnglish(int type) { 521 #if !defined(DISABLE_NACL) 522 switch (type) { 523 case PROCESS_TYPE_NACL_LOADER: 524 return "Native Client module"; 525 case PROCESS_TYPE_NACL_BROKER: 526 return "Native Client broker"; 527 } 528 #endif 529 530 NOTREACHED() << "Unknown child process type!"; 531 return "Unknown"; 532 } 533 534 #if defined(OS_MACOSX) && !defined(OS_IOS) 535 bool ChromeContentClient::GetSandboxProfileForSandboxType( 536 int sandbox_type, 537 int* sandbox_profile_resource_id) const { 538 DCHECK(sandbox_profile_resource_id); 539 if (sandbox_type == NACL_SANDBOX_TYPE_NACL_LOADER) { 540 *sandbox_profile_resource_id = IDR_NACL_SANDBOX_PROFILE; 541 return true; 542 } 543 return false; 544 } 545 #endif 546