renderer_client_base.cc 9.4 KB

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