renderer_client_base.cc 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // Copyright (c) 2017 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "atom/renderer/renderer_client_base.h"
  5. #include <string>
  6. #include <vector>
  7. #include "atom/common/color_util.h"
  8. #include "atom/common/native_mate_converters/value_converter.h"
  9. #include "atom/common/options_switches.h"
  10. #include "atom/renderer/atom_autofill_agent.h"
  11. #include "atom/renderer/atom_render_frame_observer.h"
  12. #include "atom/renderer/atom_render_view_observer.h"
  13. #include "atom/renderer/content_settings_observer.h"
  14. #include "atom/renderer/guest_view_container.h"
  15. #include "atom/renderer/preferences_manager.h"
  16. #include "base/command_line.h"
  17. #include "base/strings/string_split.h"
  18. #include "chrome/renderer/media/chrome_key_systems.h"
  19. #include "chrome/renderer/pepper/pepper_helper.h"
  20. #include "chrome/renderer/printing/print_web_view_helper.h"
  21. #include "chrome/renderer/tts_dispatcher.h"
  22. #include "content/public/common/content_constants.h"
  23. #include "content/public/renderer/render_view.h"
  24. #include "native_mate/dictionary.h"
  25. #include "third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h"
  26. #include "third_party/WebKit/public/web/WebCustomElement.h" // NOLINT(build/include_alpha)
  27. #include "third_party/WebKit/public/web/WebFrameWidget.h"
  28. #include "third_party/WebKit/public/web/WebKit.h"
  29. #include "third_party/WebKit/public/web/WebPluginParams.h"
  30. #include "third_party/WebKit/public/web/WebScriptSource.h"
  31. #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
  32. #if defined(OS_MACOSX)
  33. #include "base/mac/mac_util.h"
  34. #include "base/strings/sys_string_conversions.h"
  35. #endif
  36. #if defined(OS_WIN)
  37. #include <shlobj.h>
  38. #endif
  39. #if defined(ENABLE_PDF_VIEWER)
  40. #include "atom/common/atom_constants.h"
  41. #endif // defined(ENABLE_PDF_VIEWER)
  42. namespace atom {
  43. namespace {
  44. v8::Local<v8::Value> GetRenderProcessPreferences(
  45. const PreferencesManager* preferences_manager,
  46. v8::Isolate* isolate) {
  47. if (preferences_manager->preferences())
  48. return mate::ConvertToV8(isolate, *preferences_manager->preferences());
  49. else
  50. return v8::Null(isolate);
  51. }
  52. std::vector<std::string> ParseSchemesCLISwitch(const char* switch_name) {
  53. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  54. std::string custom_schemes = command_line->GetSwitchValueASCII(switch_name);
  55. return base::SplitString(custom_schemes, ",", base::TRIM_WHITESPACE,
  56. base::SPLIT_WANT_NONEMPTY);
  57. }
  58. } // namespace
  59. RendererClientBase::RendererClientBase() {
  60. // Parse --standard-schemes=scheme1,scheme2
  61. std::vector<std::string> standard_schemes_list =
  62. ParseSchemesCLISwitch(switches::kStandardSchemes);
  63. for (const std::string& scheme : standard_schemes_list)
  64. url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
  65. isolated_world_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
  66. switches::kContextIsolation);
  67. }
  68. RendererClientBase::~RendererClientBase() {}
  69. void RendererClientBase::AddRenderBindings(
  70. v8::Isolate* isolate,
  71. v8::Local<v8::Object> binding_object) {
  72. mate::Dictionary dict(isolate, binding_object);
  73. dict.SetMethod(
  74. "getRenderProcessPreferences",
  75. base::Bind(GetRenderProcessPreferences, preferences_manager_.get()));
  76. }
  77. void RendererClientBase::RenderThreadStarted() {
  78. blink::WebCustomElement::AddEmbedderCustomElementName("webview");
  79. blink::WebCustomElement::AddEmbedderCustomElementName("browserplugin");
  80. WTF::String extension_scheme("chrome-extension");
  81. // Extension resources are HTTP-like and safe to expose to the fetch API. The
  82. // rules for the fetch API are consistent with XHR.
  83. blink::SchemeRegistry::RegisterURLSchemeAsSupportingFetchAPI(
  84. extension_scheme);
  85. // Extension resources, when loaded as the top-level document, should bypass
  86. // Blink's strict first-party origin checks.
  87. blink::SchemeRegistry::RegisterURLSchemeAsFirstPartyWhenTopLevel(
  88. extension_scheme);
  89. // In Chrome we should set extension's origins to match the pages they can
  90. // work on, but in Electron currently we just let extensions do anything.
  91. blink::SchemeRegistry::RegisterURLSchemeAsSecure(extension_scheme);
  92. blink::SchemeRegistry::RegisterURLSchemeAsCORSEnabled(extension_scheme);
  93. blink::SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy(
  94. extension_scheme);
  95. // Parse --secure-schemes=scheme1,scheme2
  96. std::vector<std::string> secure_schemes_list =
  97. ParseSchemesCLISwitch(switches::kSecureSchemes);
  98. for (const std::string& scheme : secure_schemes_list)
  99. blink::SchemeRegistry::RegisterURLSchemeAsSecure(
  100. WTF::String::FromUTF8(scheme.data(), scheme.length()));
  101. // Allow file scheme to handle service worker by default.
  102. // FIXME(zcbenz): Can this be moved elsewhere?
  103. blink::WebSecurityPolicy::RegisterURLSchemeAsAllowingServiceWorkers("file");
  104. blink::SchemeRegistry::RegisterURLSchemeAsSupportingFetchAPI("file");
  105. preferences_manager_.reset(new PreferencesManager);
  106. #if defined(OS_WIN)
  107. // Set ApplicationUserModelID in renderer process.
  108. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  109. base::string16 app_id =
  110. command_line->GetSwitchValueNative(switches::kAppUserModelId);
  111. if (!app_id.empty()) {
  112. SetCurrentProcessExplicitAppUserModelID(app_id.c_str());
  113. }
  114. #endif
  115. #if defined(OS_MACOSX)
  116. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  117. bool scroll_bounce = command_line->HasSwitch(switches::kScrollBounce);
  118. base::ScopedCFTypeRef<CFStringRef> rubber_banding_key(
  119. base::SysUTF8ToCFStringRef("NSScrollViewRubberbanding"));
  120. CFPreferencesSetAppValue(rubber_banding_key,
  121. scroll_bounce ? kCFBooleanTrue : kCFBooleanFalse,
  122. kCFPreferencesCurrentApplication);
  123. CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
  124. #endif
  125. }
  126. void RendererClientBase::RenderFrameCreated(
  127. content::RenderFrame* render_frame) {
  128. #if defined(TOOLKIT_VIEWS)
  129. new AutofillAgent(render_frame);
  130. #endif
  131. new PepperHelper(render_frame);
  132. new ContentSettingsObserver(render_frame);
  133. new printing::PrintWebViewHelper(render_frame);
  134. // This is required for widevine plugin detection provided during runtime.
  135. blink::ResetPluginCache();
  136. #if defined(ENABLE_PDF_VIEWER)
  137. // Allow access to file scheme from pdf viewer.
  138. blink::WebSecurityPolicy::AddOriginAccessWhitelistEntry(
  139. GURL(kPdfViewerUIOrigin), "file", "", true);
  140. #endif // defined(ENABLE_PDF_VIEWER)
  141. }
  142. void RendererClientBase::RenderViewCreated(content::RenderView* render_view) {
  143. new AtomRenderViewObserver(render_view);
  144. blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
  145. if (!web_frame_widget)
  146. return;
  147. base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
  148. if (cmd->HasSwitch(switches::kGuestInstanceID)) { // webview.
  149. web_frame_widget->SetBaseBackgroundColor(SK_ColorTRANSPARENT);
  150. } else { // normal window.
  151. std::string name = cmd->GetSwitchValueASCII(switches::kBackgroundColor);
  152. SkColor color = name.empty() ? SK_ColorTRANSPARENT : ParseHexColor(name);
  153. web_frame_widget->SetBaseBackgroundColor(color);
  154. }
  155. }
  156. void RendererClientBase::DidClearWindowObject(
  157. content::RenderFrame* render_frame) {
  158. // Make sure every page will get a script context created.
  159. render_frame->GetWebFrame()->ExecuteScript(blink::WebScriptSource("void 0"));
  160. }
  161. std::unique_ptr<blink::WebSpeechSynthesizer>
  162. RendererClientBase::OverrideSpeechSynthesizer(
  163. blink::WebSpeechSynthesizerClient* client) {
  164. return std::make_unique<TtsDispatcher>(client);
  165. }
  166. bool RendererClientBase::OverrideCreatePlugin(
  167. content::RenderFrame* render_frame,
  168. const blink::WebPluginParams& params,
  169. blink::WebPlugin** plugin) {
  170. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  171. if (params.mime_type.Utf8() == content::kBrowserPluginMimeType ||
  172. #if defined(ENABLE_PDF_VIEWER)
  173. params.mime_type.Utf8() == kPdfPluginMimeType ||
  174. #endif // defined(ENABLE_PDF_VIEWER)
  175. command_line->HasSwitch(switches::kEnablePlugins))
  176. return false;
  177. *plugin = nullptr;
  178. return true;
  179. }
  180. content::BrowserPluginDelegate* RendererClientBase::CreateBrowserPluginDelegate(
  181. content::RenderFrame* render_frame,
  182. const std::string& mime_type,
  183. const GURL& original_url) {
  184. if (mime_type == content::kBrowserPluginMimeType) {
  185. return new GuestViewContainer(render_frame);
  186. } else {
  187. return nullptr;
  188. }
  189. }
  190. void RendererClientBase::AddSupportedKeySystems(
  191. std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
  192. AddChromeKeySystems(key_systems);
  193. }
  194. v8::Local<v8::Context> RendererClientBase::GetContext(
  195. blink::WebLocalFrame* frame,
  196. v8::Isolate* isolate) const {
  197. if (isolated_world())
  198. return frame->WorldScriptContext(isolate, World::ISOLATED_WORLD);
  199. else
  200. return frame->MainWorldScriptContext();
  201. }
  202. } // namespace atom