renderer_client_base.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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 <memory>
  6. #include <string>
  7. #include <vector>
  8. #include "atom/common/color_util.h"
  9. #include "atom/common/native_mate_converters/value_converter.h"
  10. #include "atom/common/options_switches.h"
  11. #include "atom/renderer/atom_autofill_agent.h"
  12. #include "atom/renderer/atom_render_frame_observer.h"
  13. #include "atom/renderer/atom_render_view_observer.h"
  14. #include "atom/renderer/content_settings_observer.h"
  15. #include "atom/renderer/preferences_manager.h"
  16. #include "base/command_line.h"
  17. #include "base/strings/string_split.h"
  18. #include "base/strings/stringprintf.h"
  19. #include "content/public/common/content_constants.h"
  20. #include "content/public/common/content_switches.h"
  21. #include "content/public/renderer/render_frame.h"
  22. #include "content/public/renderer/render_view.h"
  23. #include "electron/buildflags/buildflags.h"
  24. #include "native_mate/dictionary.h"
  25. #include "printing/buildflags/buildflags.h"
  26. #include "third_party/blink/public/web/blink.h"
  27. #include "third_party/blink/public/web/web_custom_element.h" // NOLINT(build/include_alpha)
  28. #include "third_party/blink/public/web/web_frame_widget.h"
  29. #include "third_party/blink/public/web/web_plugin_params.h"
  30. #include "third_party/blink/public/web/web_script_source.h"
  31. #include "third_party/blink/public/web/web_security_policy.h"
  32. #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
  33. #if defined(OS_MACOSX)
  34. #include "base/strings/sys_string_conversions.h"
  35. #endif
  36. #if defined(OS_WIN)
  37. #include <shlobj.h>
  38. #endif
  39. #if BUILDFLAG(ENABLE_PDF_VIEWER)
  40. #include "atom/common/atom_constants.h"
  41. #endif // BUILDFLAG(ENABLE_PDF_VIEWER)
  42. #if BUILDFLAG(ENABLE_PEPPER_FLASH)
  43. #include "chrome/renderer/pepper/pepper_helper.h"
  44. #endif // BUILDFLAG(ENABLE_PEPPER_FLASH)
  45. #if BUILDFLAG(ENABLE_PRINTING)
  46. #include "atom/renderer/printing/print_render_frame_helper_delegate.h"
  47. #include "components/printing/renderer/print_render_frame_helper.h"
  48. #endif // BUILDFLAG(ENABLE_PRINTING)
  49. #if BUILDFLAG(ENABLE_TTS)
  50. #include "chrome/renderer/tts_dispatcher.h"
  51. #endif // BUILDFLAG(ENABLE_TTS)
  52. namespace atom {
  53. namespace {
  54. v8::Local<v8::Value> GetRenderProcessPreferences(
  55. const PreferencesManager* preferences_manager,
  56. v8::Isolate* isolate) {
  57. if (preferences_manager->preferences())
  58. return mate::ConvertToV8(isolate, *preferences_manager->preferences());
  59. else
  60. return v8::Null(isolate);
  61. }
  62. std::vector<std::string> ParseSchemesCLISwitch(base::CommandLine* command_line,
  63. const char* switch_name) {
  64. std::string custom_schemes = command_line->GetSwitchValueASCII(switch_name);
  65. return base::SplitString(custom_schemes, ",", base::TRIM_WHITESPACE,
  66. base::SPLIT_WANT_NONEMPTY);
  67. }
  68. void SetHiddenValue(v8::Handle<v8::Context> context,
  69. const base::StringPiece& key,
  70. v8::Local<v8::Value> value) {
  71. v8::Isolate* isolate = context->GetIsolate();
  72. v8::Local<v8::Private> privateKey =
  73. v8::Private::ForApi(isolate, mate::StringToV8(isolate, key));
  74. context->Global()->SetPrivate(context, privateKey, value);
  75. }
  76. } // namespace
  77. RendererClientBase::RendererClientBase() {
  78. auto* command_line = base::CommandLine::ForCurrentProcess();
  79. // Parse --standard-schemes=scheme1,scheme2
  80. std::vector<std::string> standard_schemes_list =
  81. ParseSchemesCLISwitch(command_line, switches::kStandardSchemes);
  82. for (const std::string& scheme : standard_schemes_list)
  83. url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITH_HOST);
  84. isolated_world_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
  85. switches::kContextIsolation);
  86. // We rely on the unique process host id which is notified to the
  87. // renderer process via command line switch from the content layer,
  88. // if this switch is removed from the content layer for some reason,
  89. // we should define our own.
  90. DCHECK(command_line->HasSwitch(::switches::kRendererClientId));
  91. renderer_client_id_ =
  92. command_line->GetSwitchValueASCII(::switches::kRendererClientId);
  93. }
  94. RendererClientBase::~RendererClientBase() {}
  95. void RendererClientBase::DidCreateScriptContext(
  96. v8::Handle<v8::Context> context,
  97. content::RenderFrame* render_frame) {
  98. // global.setHidden("contextId", `${processHostId}-${++next_context_id_}`)
  99. auto context_id = base::StringPrintf(
  100. "%s-%" PRId64, renderer_client_id_.c_str(), ++next_context_id_);
  101. v8::Isolate* isolate = context->GetIsolate();
  102. SetHiddenValue(context, "contextId", mate::ConvertToV8(isolate, context_id));
  103. auto* command_line = base::CommandLine::ForCurrentProcess();
  104. bool enableRemoteModule =
  105. !command_line->HasSwitch(switches::kDisableRemoteModule);
  106. SetHiddenValue(context, "enableRemoteModule",
  107. mate::ConvertToV8(isolate, enableRemoteModule));
  108. }
  109. void RendererClientBase::AddRenderBindings(
  110. v8::Isolate* isolate,
  111. v8::Local<v8::Object> binding_object) {
  112. mate::Dictionary dict(isolate, binding_object);
  113. dict.SetMethod(
  114. "getRenderProcessPreferences",
  115. base::Bind(GetRenderProcessPreferences, preferences_manager_.get()));
  116. }
  117. void RendererClientBase::RenderThreadStarted() {
  118. auto* command_line = base::CommandLine::ForCurrentProcess();
  119. blink::WebCustomElement::AddEmbedderCustomElementName("webview");
  120. blink::WebCustomElement::AddEmbedderCustomElementName("browserplugin");
  121. WTF::String extension_scheme("chrome-extension");
  122. // Extension resources are HTTP-like and safe to expose to the fetch API. The
  123. // rules for the fetch API are consistent with XHR.
  124. blink::SchemeRegistry::RegisterURLSchemeAsSupportingFetchAPI(
  125. extension_scheme);
  126. // Extension resources, when loaded as the top-level document, should bypass
  127. // Blink's strict first-party origin checks.
  128. blink::SchemeRegistry::RegisterURLSchemeAsFirstPartyWhenTopLevel(
  129. extension_scheme);
  130. // In Chrome we should set extension's origins to match the pages they can
  131. // work on, but in Electron currently we just let extensions do anything.
  132. blink::SchemeRegistry::RegisterURLSchemeAsSecure(extension_scheme);
  133. blink::SchemeRegistry::RegisterURLSchemeAsCORSEnabled(extension_scheme);
  134. blink::SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy(
  135. extension_scheme);
  136. // Parse --secure-schemes=scheme1,scheme2
  137. std::vector<std::string> secure_schemes_list =
  138. ParseSchemesCLISwitch(command_line, switches::kSecureSchemes);
  139. for (const std::string& scheme : secure_schemes_list)
  140. blink::SchemeRegistry::RegisterURLSchemeAsSecure(
  141. WTF::String::FromUTF8(scheme.data(), scheme.length()));
  142. // Allow file scheme to handle service worker by default.
  143. // FIXME(zcbenz): Can this be moved elsewhere?
  144. blink::WebSecurityPolicy::RegisterURLSchemeAsAllowingServiceWorkers("file");
  145. blink::SchemeRegistry::RegisterURLSchemeAsSupportingFetchAPI("file");
  146. preferences_manager_.reset(new PreferencesManager);
  147. #if defined(OS_WIN)
  148. // Set ApplicationUserModelID in renderer process.
  149. base::string16 app_id =
  150. command_line->GetSwitchValueNative(switches::kAppUserModelId);
  151. if (!app_id.empty()) {
  152. SetCurrentProcessExplicitAppUserModelID(app_id.c_str());
  153. }
  154. #endif
  155. }
  156. void RendererClientBase::RenderFrameCreated(
  157. content::RenderFrame* render_frame) {
  158. #if defined(TOOLKIT_VIEWS)
  159. new AutofillAgent(render_frame);
  160. #endif
  161. #if BUILDFLAG(ENABLE_PEPPER_FLASH)
  162. new PepperHelper(render_frame);
  163. #endif
  164. new ContentSettingsObserver(render_frame);
  165. #if BUILDFLAG(ENABLE_PRINTING)
  166. new printing::PrintRenderFrameHelper(
  167. render_frame, std::make_unique<atom::PrintRenderFrameHelperDelegate>());
  168. #endif
  169. #if BUILDFLAG(ENABLE_PDF_VIEWER)
  170. // Allow access to file scheme from pdf viewer.
  171. blink::WebSecurityPolicy::AddOriginAccessWhitelistEntry(
  172. GURL(kPdfViewerUIOrigin), "file", "", true);
  173. #endif // BUILDFLAG(ENABLE_PDF_VIEWER)
  174. content::RenderView* render_view = render_frame->GetRenderView();
  175. if (render_frame->IsMainFrame() && render_view) {
  176. blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
  177. if (web_frame_widget) {
  178. base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
  179. if (cmd->HasSwitch(switches::kGuestInstanceID)) { // webview.
  180. web_frame_widget->SetBaseBackgroundColor(SK_ColorTRANSPARENT);
  181. } else { // normal window.
  182. std::string name = cmd->GetSwitchValueASCII(switches::kBackgroundColor);
  183. SkColor color =
  184. name.empty() ? SK_ColorTRANSPARENT : ParseHexColor(name);
  185. web_frame_widget->SetBaseBackgroundColor(color);
  186. }
  187. }
  188. }
  189. }
  190. void RendererClientBase::RenderViewCreated(content::RenderView* render_view) {
  191. new AtomRenderViewObserver(render_view);
  192. }
  193. void RendererClientBase::DidClearWindowObject(
  194. content::RenderFrame* render_frame) {
  195. // Make sure every page will get a script context created.
  196. render_frame->GetWebFrame()->ExecuteScript(blink::WebScriptSource("void 0"));
  197. }
  198. std::unique_ptr<blink::WebSpeechSynthesizer>
  199. RendererClientBase::OverrideSpeechSynthesizer(
  200. blink::WebSpeechSynthesizerClient* client) {
  201. #if BUILDFLAG(ENABLE_TTS)
  202. return std::make_unique<TtsDispatcher>(client);
  203. #else
  204. return nullptr;
  205. #endif
  206. }
  207. bool RendererClientBase::OverrideCreatePlugin(
  208. content::RenderFrame* render_frame,
  209. const blink::WebPluginParams& params,
  210. blink::WebPlugin** plugin) {
  211. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  212. if (params.mime_type.Utf8() == content::kBrowserPluginMimeType ||
  213. #if BUILDFLAG(ENABLE_PDF_VIEWER)
  214. params.mime_type.Utf8() == kPdfPluginMimeType ||
  215. #endif // BUILDFLAG(ENABLE_PDF_VIEWER)
  216. command_line->HasSwitch(switches::kEnablePlugins))
  217. return false;
  218. *plugin = nullptr;
  219. return true;
  220. }
  221. void RendererClientBase::AddSupportedKeySystems(
  222. std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
  223. #if defined(WIDEVINE_CDM_AVAILABLE)
  224. key_systems_provider_.AddSupportedKeySystems(key_systems);
  225. #endif
  226. }
  227. bool RendererClientBase::IsKeySystemsUpdateNeeded() {
  228. #if defined(WIDEVINE_CDM_AVAILABLE)
  229. return key_systems_provider_.IsKeySystemsUpdateNeeded();
  230. #else
  231. return false;
  232. #endif
  233. }
  234. v8::Local<v8::Context> RendererClientBase::GetContext(
  235. blink::WebLocalFrame* frame,
  236. v8::Isolate* isolate) const {
  237. if (isolated_world())
  238. return frame->WorldScriptContext(isolate, World::ISOLATED_WORLD);
  239. else
  240. return frame->MainWorldScriptContext();
  241. }
  242. } // namespace atom