// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/browser/devtools/renderer_overrides_handler.h" #include #include "base/base64.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/files/file_path.h" #include "base/strings/string16.h" #include "base/values.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/devtools/devtools_protocol_constants.h" #include "content/browser/devtools/devtools_tracing_handler.h" #include "content/browser/renderer_host/render_view_host_delegate.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/javascript_dialog_manager.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/common/page_transition_types.h" #include "content/public/common/referrer.h" #include "ui/snapshot/snapshot.h" #include "url/gurl.h" namespace content { RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent) : agent_(agent) { RegisterCommandHandler( devtools::DOM::setFileInputFiles::kName, base::Bind( &RendererOverridesHandler::GrantPermissionsForSetFileInputFiles, base::Unretained(this))); RegisterCommandHandler( devtools::Page::handleJavaScriptDialog::kName, base::Bind( &RendererOverridesHandler::PageHandleJavaScriptDialog, base::Unretained(this))); RegisterCommandHandler( devtools::Page::navigate::kName, base::Bind( &RendererOverridesHandler::PageNavigate, base::Unretained(this))); RegisterCommandHandler( devtools::Page::captureScreenshot::kName, base::Bind( &RendererOverridesHandler::PageCaptureScreenshot, base::Unretained(this))); } RendererOverridesHandler::~RendererOverridesHandler() {} scoped_ptr RendererOverridesHandler::GrantPermissionsForSetFileInputFiles( DevToolsProtocol::Command* command) { base::DictionaryValue* params = command->params(); base::ListValue* file_list = NULL; const char* param = devtools::DOM::setFileInputFiles::kParamFiles; if (!params || !params->GetList(param, &file_list)) return command->InvalidParamResponse(param); RenderViewHost* host = agent_->GetRenderViewHost(); if (!host) return scoped_ptr(); for (size_t i = 0; i < file_list->GetSize(); ++i) { base::FilePath::StringType file; if (!file_list->GetString(i, &file)) return command->InvalidParamResponse(param); ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( host->GetProcess()->GetID(), base::FilePath(file)); } return scoped_ptr(); } scoped_ptr RendererOverridesHandler::PageHandleJavaScriptDialog( DevToolsProtocol::Command* command) { base::DictionaryValue* params = command->params(); const char* paramAccept = devtools::Page::handleJavaScriptDialog::kParamAccept; bool accept; if (!params || !params->GetBoolean(paramAccept, &accept)) return command->InvalidParamResponse(paramAccept); string16 prompt_override; string16* prompt_override_ptr = &prompt_override; if (!params || !params->GetString( devtools::Page::handleJavaScriptDialog::kParamPromptText, prompt_override_ptr)) { prompt_override_ptr = NULL; } RenderViewHost* host = agent_->GetRenderViewHost(); if (host) { WebContents* web_contents = host->GetDelegate()->GetAsWebContents(); if (web_contents) { JavaScriptDialogManager* manager = web_contents->GetDelegate()->GetJavaScriptDialogManager(); if (manager && manager->HandleJavaScriptDialog( web_contents, accept, prompt_override_ptr)) { return scoped_ptr(); } } } return command->InternalErrorResponse("No JavaScript dialog to handle"); } scoped_ptr RendererOverridesHandler::PageNavigate( DevToolsProtocol::Command* command) { base::DictionaryValue* params = command->params(); std::string url; const char* param = devtools::Page::navigate::kParamUrl; if (!params || !params->GetString(param, &url)) return command->InvalidParamResponse(param); GURL gurl(url); if (!gurl.is_valid()) { return command->InternalErrorResponse("Cannot navigate to invalid URL"); } RenderViewHost* host = agent_->GetRenderViewHost(); if (host) { WebContents* web_contents = host->GetDelegate()->GetAsWebContents(); if (web_contents) { web_contents->GetController() .LoadURL(gurl, Referrer(), PAGE_TRANSITION_TYPED, std::string()); return command->SuccessResponse(new base::DictionaryValue()); } } return command->InternalErrorResponse("No WebContents to navigate"); } scoped_ptr RendererOverridesHandler::PageCaptureScreenshot( DevToolsProtocol::Command* command) { std::string base_64_data; if (!CaptureScreenshot(&base_64_data)) return command->InternalErrorResponse("Unable to capture a screenshot"); base::DictionaryValue* response = new base::DictionaryValue(); response->SetString( devtools::Page::captureScreenshot::kResponseData, base_64_data); return command->SuccessResponse(response); } bool RendererOverridesHandler::CaptureScreenshot(std::string* base_64_data) { RenderViewHost* host = agent_->GetRenderViewHost(); gfx::Rect view_bounds = host->GetView()->GetViewBounds(); gfx::Rect snapshot_bounds(view_bounds.size()); gfx::Size snapshot_size = snapshot_bounds.size(); std::vector png; if (!ui::GrabViewSnapshot(host->GetView()->GetNativeView(), &png, snapshot_bounds)) return false; return base::Base64Encode(base::StringPiece( reinterpret_cast(&*png.begin()), png.size()), base_64_data); } } // namespace content