Merge remote-tracking branch 'atom/master'
This commit is contained in:
commit
1c97fc79ad
90 changed files with 3937 additions and 112 deletions
|
@ -31,7 +31,7 @@ npm install electron-prebuilt --save-dev
|
|||
|
||||
### Mirrors
|
||||
|
||||
- [China](https://npm.taobao.org/mirrors/atom-shell)
|
||||
- [China](https://npm.taobao.org/mirrors/electron)
|
||||
|
||||
## Documentation
|
||||
|
||||
|
|
5
atom.gyp
5
atom.gyp
|
@ -4,7 +4,7 @@
|
|||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '0.25.2',
|
||||
'version%': '0.26.0',
|
||||
|
||||
'atom_source_root': '<!(["python", "tools/atom_source_root.py"])',
|
||||
},
|
||||
|
@ -142,6 +142,9 @@
|
|||
'<(libchromiumcontent_dir)/snapshot_blob.bin',
|
||||
'external_binaries/d3dcompiler_47.dll',
|
||||
'external_binaries/xinput1_3.dll',
|
||||
'external_binaries/msvcp120.dll',
|
||||
'external_binaries/msvcr120.dll',
|
||||
'external_binaries/vccorlib120.dll',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -8,9 +8,42 @@
|
|||
#include <vector>
|
||||
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||
const std::string& version) {
|
||||
content::PepperPluginInfo plugin;
|
||||
|
||||
plugin.is_out_of_process = true;
|
||||
plugin.name = content::kFlashPluginName;
|
||||
plugin.path = path;
|
||||
plugin.permissions = ppapi::PERMISSION_ALL_BITS;
|
||||
plugin.version = version;
|
||||
|
||||
content::WebPluginMimeType swf_mime_type(
|
||||
content::kFlashPluginSwfMimeType,
|
||||
content::kFlashPluginSwfExtension,
|
||||
content::kFlashPluginSwfDescription);
|
||||
plugin.mime_types.push_back(swf_mime_type);
|
||||
content::WebPluginMimeType spl_mime_type(
|
||||
content::kFlashPluginSplMimeType,
|
||||
content::kFlashPluginSplExtension,
|
||||
content::kFlashPluginSplDescription);
|
||||
plugin.mime_types.push_back(spl_mime_type);
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomContentClient::AtomContentClient() {
|
||||
}
|
||||
|
||||
|
@ -27,4 +60,19 @@ void AtomContentClient::AddAdditionalSchemes(
|
|||
standard_schemes->push_back("chrome-extension");
|
||||
}
|
||||
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto flash_path = command_line->GetSwitchValueNative(
|
||||
switches::kPpapiFlashPath);
|
||||
if (flash_path.empty())
|
||||
return;
|
||||
|
||||
auto flash_version = command_line->GetSwitchValueASCII(
|
||||
switches::kPpapiFlashVersion);
|
||||
|
||||
plugins->push_back(
|
||||
CreatePepperFlashInfo(base::FilePath(flash_path), flash_version));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -23,6 +23,8 @@ class AtomContentClient : public brightray::ContentClient {
|
|||
void AddAdditionalSchemes(
|
||||
std::vector<std::string>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes) override;
|
||||
void AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/common/google_api_key.h"
|
||||
#include "atom/renderer/atom_renderer_client.h"
|
||||
#include "atom/utility/atom_content_utility_client.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/debug/stack_trace.h"
|
||||
#include "base/environment.h"
|
||||
|
@ -94,6 +95,11 @@ content::ContentRendererClient*
|
|||
return renderer_client_.get();
|
||||
}
|
||||
|
||||
content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() {
|
||||
utility_client_.reset(new AtomContentUtilityClient);
|
||||
return utility_client_.get();
|
||||
}
|
||||
|
||||
scoped_ptr<brightray::ContentClient> AtomMainDelegate::CreateContentClient() {
|
||||
return scoped_ptr<brightray::ContentClient>(new AtomContentClient).Pass();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
|||
void PreSandboxStartup() override;
|
||||
content::ContentBrowserClient* CreateContentBrowserClient() override;
|
||||
content::ContentRendererClient* CreateContentRendererClient() override;
|
||||
content::ContentUtilityClient* CreateContentUtilityClient() override;
|
||||
|
||||
// brightray::MainDelegate:
|
||||
scoped_ptr<brightray::ContentClient> CreateContentClient() override;
|
||||
|
@ -35,6 +36,7 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
|||
brightray::ContentClient content_client_;
|
||||
scoped_ptr<content::ContentBrowserClient> browser_client_;
|
||||
scoped_ptr<content::ContentRendererClient> renderer_client_;
|
||||
scoped_ptr<content::ContentUtilityClient> utility_client_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
|
||||
};
|
||||
|
|
|
@ -105,6 +105,15 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
|||
base::Bind(&AdapterRequestJob::CreateFileJobAndStart,
|
||||
GetWeakPtr(), path));
|
||||
return;
|
||||
} else if (name == "RequestErrorJob") {
|
||||
// Default value net::ERR_NOT_IMPLEMENTED
|
||||
int error = -11;
|
||||
dict.Get("error", &error);
|
||||
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&AdapterRequestJob::CreateErrorJobAndStart,
|
||||
GetWeakPtr(), error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <set>
|
||||
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_javascript_dialog_manager.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
|
@ -348,8 +349,9 @@ void WebContents::WebContentsDestroyed() {
|
|||
}
|
||||
|
||||
void WebContents::NavigationEntryCommitted(
|
||||
const content::LoadCommittedDetails& load_details) {
|
||||
Emit("navigation-entry-commited", load_details.entry->GetURL());
|
||||
const content::LoadCommittedDetails& details) {
|
||||
Emit("navigation-entry-commited", details.entry->GetURL(),
|
||||
details.is_in_page, details.did_replace_entry);
|
||||
}
|
||||
|
||||
void WebContents::DidAttach(int guest_proxy_routing_id) {
|
||||
|
@ -426,13 +428,6 @@ base::string16 WebContents::GetTitle() const {
|
|||
return web_contents()->GetTitle();
|
||||
}
|
||||
|
||||
gfx::Image WebContents::GetFavicon() const {
|
||||
auto entry = web_contents()->GetController().GetLastCommittedEntry();
|
||||
if (!entry)
|
||||
return gfx::Image();
|
||||
return entry->GetFavicon().image;
|
||||
}
|
||||
|
||||
bool WebContents::IsLoading() const {
|
||||
return web_contents()->IsLoading();
|
||||
}
|
||||
|
@ -449,6 +444,21 @@ void WebContents::ReloadIgnoringCache() {
|
|||
web_contents()->GetController().ReloadIgnoringCache(false);
|
||||
}
|
||||
|
||||
void WebContents::GoBack() {
|
||||
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
||||
web_contents()->GetController().GoBack();
|
||||
}
|
||||
|
||||
void WebContents::GoForward() {
|
||||
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
||||
web_contents()->GetController().GoForward();
|
||||
}
|
||||
|
||||
void WebContents::GoToOffset(int offset) {
|
||||
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
||||
web_contents()->GetController().GoToOffset(offset);
|
||||
}
|
||||
|
||||
int WebContents::GetRoutingID() const {
|
||||
return web_contents()->GetRoutingID();
|
||||
}
|
||||
|
@ -613,11 +623,13 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
|||
.SetMethod("isAlive", &WebContents::IsAlive)
|
||||
.SetMethod("_loadUrl", &WebContents::LoadURL)
|
||||
.SetMethod("getTitle", &WebContents::GetTitle)
|
||||
.SetMethod("getFavicon", &WebContents::GetFavicon)
|
||||
.SetMethod("isLoading", &WebContents::IsLoading)
|
||||
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
|
||||
.SetMethod("_stop", &WebContents::Stop)
|
||||
.SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache)
|
||||
.SetMethod("_goBack", &WebContents::GoBack)
|
||||
.SetMethod("_goForward", &WebContents::GoForward)
|
||||
.SetMethod("_goToOffset", &WebContents::GoToOffset)
|
||||
.SetMethod("getRoutingId", &WebContents::GetRoutingID)
|
||||
.SetMethod("getProcessId", &WebContents::GetProcessID)
|
||||
.SetMethod("isCrashed", &WebContents::IsCrashed)
|
||||
|
|
|
@ -49,11 +49,13 @@ class WebContents : public mate::EventEmitter,
|
|||
bool IsAlive() const;
|
||||
void LoadURL(const GURL& url, const mate::Dictionary& options);
|
||||
base::string16 GetTitle() const;
|
||||
gfx::Image GetFavicon() const;
|
||||
bool IsLoading() const;
|
||||
bool IsWaitingForResponse() const;
|
||||
void Stop();
|
||||
void ReloadIgnoringCache();
|
||||
void GoBack();
|
||||
void GoForward();
|
||||
void GoToOffset(int offset);
|
||||
int GetRoutingID() const;
|
||||
int GetProcessID() const;
|
||||
bool IsCrashed() const;
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
ipc = require 'ipc'
|
||||
|
||||
# The history operation in renderer is redirected to browser.
|
||||
ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
|
||||
event.sender[method] args...
|
||||
|
||||
# JavaScript implementation of Chromium's NavigationController.
|
||||
# Instead of relying on Chromium for history control, we compeletely do history
|
||||
# control on user land, and only rely on WebContents.loadUrl for navigation.
|
||||
|
@ -8,17 +14,28 @@ class NavigationController
|
|||
@history = []
|
||||
@currentIndex = -1
|
||||
@pendingIndex = -1
|
||||
@inPageIndex = -1
|
||||
|
||||
@webContents.on 'navigation-entry-commited', (event, url) =>
|
||||
if @pendingIndex is -1 # Normal navigation.
|
||||
@history = @history.slice 0, @currentIndex + 1 # Clear history.
|
||||
if @history[@currentIndex] isnt url
|
||||
@currentIndex++
|
||||
@history.push url
|
||||
else # Go to index.
|
||||
@webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) =>
|
||||
if @inPageIndex > -1 and not inPage
|
||||
# Navigated to a new page, clear in-page mark.
|
||||
@inPageIndex = -1
|
||||
else if @inPageIndex is -1 and inPage
|
||||
# Started in-page navigations.
|
||||
@inPageIndex = @currentIndex
|
||||
|
||||
if @pendingIndex >= 0 # Go to index.
|
||||
@currentIndex = @pendingIndex
|
||||
@pendingIndex = -1
|
||||
@history[@currentIndex] = url
|
||||
else if replaceEntry # Non-user initialized navigation.
|
||||
@history[@currentIndex] = url
|
||||
else # Normal navigation.
|
||||
@history = @history.slice 0, @currentIndex + 1 # Clear history.
|
||||
currentEntry = @history[@currentIndex]
|
||||
if currentEntry?.url isnt url
|
||||
@currentIndex++
|
||||
@history.push url
|
||||
|
||||
loadUrl: (url, options={}) ->
|
||||
@pendingIndex = -1
|
||||
|
@ -57,21 +74,32 @@ class NavigationController
|
|||
goBack: ->
|
||||
return unless @canGoBack()
|
||||
@pendingIndex = @getActiveIndex() - 1
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
|
||||
@webContents._goBack()
|
||||
else
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
|
||||
goForward: ->
|
||||
return unless @canGoForward()
|
||||
@pendingIndex = @getActiveIndex() + 1
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
|
||||
@webContents._goForward()
|
||||
else
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
|
||||
goToIndex: (index) ->
|
||||
return unless @canGoToIndex index
|
||||
@pendingIndex = index
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
@webContents._loadUrl @history[@pendingIndex].url, {}
|
||||
|
||||
goToOffset: (offset) ->
|
||||
return unless @canGoToOffset offset
|
||||
@goToIndex @currentIndex + offset
|
||||
pendingIndex = @currentIndex + offset
|
||||
if @inPageIndex > -1 and pendingIndex >= @inPageIndex
|
||||
@pendingIndex = pendingIndex
|
||||
@webContents._goToOffset offset
|
||||
else
|
||||
@goToIndex pendingIndex
|
||||
|
||||
getActiveIndex: ->
|
||||
if @pendingIndex is -1 then @currentIndex else @pendingIndex
|
||||
|
|
|
@ -30,4 +30,8 @@ protocol.RequestFileJob =
|
|||
class RequestFileJob
|
||||
constructor: (@path) ->
|
||||
|
||||
protocol.RequestErrorJob =
|
||||
class RequestErrorJob
|
||||
constructor: (@error) ->
|
||||
|
||||
module.exports = protocol
|
||||
|
|
|
@ -29,7 +29,6 @@ module.exports.wrap = (webContents) ->
|
|||
|
||||
# The navigation controller.
|
||||
controller = new NavigationController(webContents)
|
||||
webContents.controller = controller
|
||||
for name, method of NavigationController.prototype when method instanceof Function
|
||||
do (name, method) ->
|
||||
webContents[name] = -> method.apply controller, arguments
|
||||
|
|
|
@ -16,19 +16,25 @@
|
|||
#include "base/command_line.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "chrome/browser/printing/printing_message_filter.h"
|
||||
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
|
||||
#include "chrome/browser/speech/tts_message_filter.h"
|
||||
#include "content/public/browser/browser_ppapi_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/resource_dispatcher_host.h"
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Next navigation should not restart renderer process.
|
||||
bool g_suppress_renderer_process_restart = false;
|
||||
|
||||
struct FindByProcessId {
|
||||
explicit FindByProcessId(int child_process_id)
|
||||
: child_process_id_(child_process_id) {
|
||||
|
@ -48,6 +54,11 @@ struct FindByProcessId {
|
|||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
|
||||
g_suppress_renderer_process_restart = true;
|
||||
}
|
||||
|
||||
AtomBrowserClient::AtomBrowserClient()
|
||||
: dying_render_process_(nullptr) {
|
||||
}
|
||||
|
@ -128,6 +139,11 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
|||
content::SiteInstance* current_instance,
|
||||
const GURL& url,
|
||||
content::SiteInstance** new_instance) {
|
||||
if (g_suppress_renderer_process_restart) {
|
||||
g_suppress_renderer_process_restart = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_instance->HasProcess())
|
||||
dying_render_process_ = current_instance->GetProcess();
|
||||
|
||||
|
@ -197,6 +213,15 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
|||
dying_render_process_ = nullptr;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::DidCreatePpapiPlugin(
|
||||
content::BrowserPpapiHost* browser_host) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(switches::kEnablePlugins))
|
||||
browser_host->GetPpapiHost()->AddHostFactoryFilter(
|
||||
scoped_ptr<ppapi::host::HostFactory>(
|
||||
new chrome::ChromeBrowserPepperHostFactory(browser_host)));
|
||||
}
|
||||
|
||||
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) {
|
||||
v8::V8::Initialize(); // Init V8 before creating main parts.
|
||||
|
|
|
@ -18,6 +18,9 @@ class AtomBrowserClient : public brightray::BrowserClient {
|
|||
AtomBrowserClient();
|
||||
virtual ~AtomBrowserClient();
|
||||
|
||||
// Don't force renderer process to restart for once.
|
||||
static void SuppressRendererProcessRestartForOnce();
|
||||
|
||||
protected:
|
||||
// content::ContentBrowserClient:
|
||||
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
|
||||
|
@ -35,6 +38,7 @@ class AtomBrowserClient : public brightray::BrowserClient {
|
|||
content::SiteInstance** new_instance);
|
||||
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
|
||||
int child_process_id) override;
|
||||
void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
|
||||
|
||||
private:
|
||||
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||
|
|
|
@ -107,6 +107,9 @@ ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event, guestInstanceId) ->
|
|||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_CURRENT_WEB_CONTENTS', (event) ->
|
||||
event.returnValue = valueToMeta event.sender, event.sender
|
||||
|
||||
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
|
||||
try
|
||||
args = unwrapArgs event.sender, args
|
||||
|
|
|
@ -303,18 +303,25 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
|
|||
options.Get(switches::kWidth, &width);
|
||||
options.Get(switches::kHeight, &height);
|
||||
|
||||
NSRect main_screen_rect = [[NSScreen mainScreen] frame];
|
||||
NSRect main_screen_rect = [[[NSScreen screens] objectAtIndex:0] frame];
|
||||
NSRect cocoa_bounds = NSMakeRect(
|
||||
round((NSWidth(main_screen_rect) - width) / 2) ,
|
||||
round((NSHeight(main_screen_rect) - height) / 2),
|
||||
width,
|
||||
height);
|
||||
|
||||
bool useStandardWindow = true;
|
||||
options.Get(switches::kStandardWindow, &useStandardWindow);
|
||||
|
||||
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
|
||||
NSMiniaturizableWindowMask | NSResizableWindowMask;
|
||||
if (!useStandardWindow) {
|
||||
styleMask |= NSTexturedBackgroundWindowMask;
|
||||
}
|
||||
|
||||
window_.reset([[AtomNSWindow alloc]
|
||||
initWithContentRect:cocoa_bounds
|
||||
styleMask:NSTitledWindowMask | NSClosableWindowMask |
|
||||
NSMiniaturizableWindowMask | NSResizableWindowMask |
|
||||
NSTexturedBackgroundWindowMask
|
||||
styleMask:styleMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:YES]);
|
||||
[window_ setShell:this];
|
||||
|
@ -463,7 +470,7 @@ void NativeWindowMac::SetBounds(const gfx::Rect& bounds) {
|
|||
bounds.width(),
|
||||
bounds.height());
|
||||
// Flip coordinates based on the primary screen.
|
||||
NSScreen* screen = [NSScreen mainScreen];
|
||||
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
|
||||
cocoa_bounds.origin.y =
|
||||
NSHeight([screen frame]) - bounds.height() - bounds.y();
|
||||
|
||||
|
@ -473,7 +480,7 @@ void NativeWindowMac::SetBounds(const gfx::Rect& bounds) {
|
|||
gfx::Rect NativeWindowMac::GetBounds() {
|
||||
NSRect frame = [window_ frame];
|
||||
gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
|
||||
NSScreen* screen = [NSScreen mainScreen];
|
||||
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
|
||||
bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
|
||||
return bounds;
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
#include "atom/browser/net/adapter_request_job.h"
|
||||
|
||||
#include "base/threading/sequenced_worker_pool.h"
|
||||
#include "atom/browser/net/url_request_buffer_job.h"
|
||||
#include "atom/browser/net/url_request_string_job.h"
|
||||
#include "atom/browser/net/asar/url_request_asar_job.h"
|
||||
#include "atom/common/asar/asar_util.h"
|
||||
#include "atom/browser/net/url_request_buffer_job.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/url_request/url_request_error_job.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundleIconFile</key>
|
||||
<string>atom.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.25.2</string>
|
||||
<string>0.26.0</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.8.0</string>
|
||||
<key>NSMainNibFile</key>
|
||||
|
|
|
@ -50,8 +50,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,25,2,0
|
||||
PRODUCTVERSION 0,25,2,0
|
||||
FILEVERSION 0,26,0,0
|
||||
PRODUCTVERSION 0,26,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -68,12 +68,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "0.25.2"
|
||||
VALUE "FileVersion", "0.26.0"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "0.25.2"
|
||||
VALUE "ProductVersion", "0.26.0"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
|
|
@ -109,8 +109,12 @@ bool StringToAccelerator(const std::string& description,
|
|||
modifiers |= ui::EF_SHIFT_DOWN;
|
||||
} else if (tokens[i] == "ctrl" || tokens[i] == "control") {
|
||||
modifiers |= ui::EF_CONTROL_DOWN;
|
||||
} else if (tokens[i] == "super") {
|
||||
modifiers |= ui::EF_COMMAND_DOWN;
|
||||
#if defined(OS_MACOSX)
|
||||
} else if (tokens[i] == "cmd" || tokens[i] == "command") {
|
||||
modifiers |= ui::EF_COMMAND_DOWN;
|
||||
#endif
|
||||
} else if (tokens[i] == "commandorcontrol" || tokens[i] == "cmdorctrl") {
|
||||
#if defined(OS_MACOSX)
|
||||
modifiers |= ui::EF_COMMAND_DOWN;
|
||||
|
@ -171,7 +175,7 @@ bool StringToAccelerator(const std::string& description,
|
|||
} else if (tokens[i].size() > 1 && tokens[i][0] == 'f') {
|
||||
// F1 - F24.
|
||||
int n;
|
||||
if (base::StringToInt(tokens[i].c_str() + 1, &n)) {
|
||||
if (base::StringToInt(tokens[i].c_str() + 1, &n) && n > 0 && n < 25) {
|
||||
key = static_cast<ui::KeyboardCode>(ui::VKEY_F1 + n - 1);
|
||||
} else {
|
||||
LOG(WARNING) << tokens[i] << "is not available on keyboard";
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
NSRect frame = [NSApp currentEvent].window.frame;
|
||||
gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
|
||||
// Flip coordinates to gfx (0,0 in top-left corner) using current screen.
|
||||
NSScreen* screen = [NSScreen mainScreen];
|
||||
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
|
||||
bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
|
||||
|
||||
trayIcon_->NotifyClicked(bounds);
|
||||
|
|
|
@ -88,6 +88,13 @@ class Archive : public mate::Wrappable {
|
|||
return mate::ConvertToV8(isolate, new_path);
|
||||
}
|
||||
|
||||
// Return the file descriptor.
|
||||
int GetFD() const {
|
||||
if (!archive_)
|
||||
return -1;
|
||||
return archive_->GetFD();
|
||||
}
|
||||
|
||||
// Free the resources used by archive.
|
||||
void Destroy() {
|
||||
archive_.reset();
|
||||
|
@ -102,6 +109,7 @@ class Archive : public mate::Wrappable {
|
|||
.SetMethod("readdir", &Archive::Readdir)
|
||||
.SetMethod("realpath", &Archive::Realpath)
|
||||
.SetMethod("copyFileOut", &Archive::CopyFileOut)
|
||||
.SetMethod("getFd", &Archive::GetFD)
|
||||
.SetMethod("destroy", &Archive::Destroy);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
#include "atom/common/asar/archive.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -104,6 +108,7 @@ bool FillFileInfoWithNode(Archive::FileInfo* info,
|
|||
|
||||
Archive::Archive(const base::FilePath& path)
|
||||
: path_(path),
|
||||
file_(path_, base::File::FLAG_OPEN | base::File::FLAG_READ),
|
||||
header_size_(0) {
|
||||
}
|
||||
|
||||
|
@ -111,15 +116,14 @@ Archive::~Archive() {
|
|||
}
|
||||
|
||||
bool Archive::Init() {
|
||||
base::File file(path_, base::File::FLAG_OPEN | base::File::FLAG_READ);
|
||||
if (!file.IsValid())
|
||||
if (!file_.IsValid())
|
||||
return false;
|
||||
|
||||
std::vector<char> buf;
|
||||
int len;
|
||||
|
||||
buf.resize(8);
|
||||
len = file.ReadAtCurrentPos(buf.data(), buf.size());
|
||||
len = file_.ReadAtCurrentPos(buf.data(), buf.size());
|
||||
if (len != static_cast<int>(buf.size())) {
|
||||
PLOG(ERROR) << "Failed to read header size from " << path_.value();
|
||||
return false;
|
||||
|
@ -132,7 +136,7 @@ bool Archive::Init() {
|
|||
}
|
||||
|
||||
buf.resize(size);
|
||||
len = file.ReadAtCurrentPos(buf.data(), buf.size());
|
||||
len = file_.ReadAtCurrentPos(buf.data(), buf.size());
|
||||
if (len != static_cast<int>(buf.size())) {
|
||||
PLOG(ERROR) << "Failed to read header from " << path_.value();
|
||||
return false;
|
||||
|
@ -250,7 +254,7 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) {
|
|||
}
|
||||
|
||||
scoped_ptr<ScopedTemporaryFile> temp_file(new ScopedTemporaryFile);
|
||||
if (!temp_file->InitFromFile(path_, info.offset, info.size))
|
||||
if (!temp_file->InitFromFile(&file_, info.offset, info.size))
|
||||
return false;
|
||||
|
||||
*out = temp_file->path();
|
||||
|
@ -258,4 +262,18 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) {
|
|||
return true;
|
||||
}
|
||||
|
||||
int Archive::GetFD() const {
|
||||
if (!file_.IsValid())
|
||||
return -1;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
return
|
||||
_open_osfhandle(reinterpret_cast<intptr_t>(file_.GetPlatformFile()), 0);
|
||||
#elif defined(OS_POSIX)
|
||||
return file_.GetPlatformFile();
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace asar
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "base/containers/scoped_ptr_hash_map.h"
|
||||
#include "base/files/file.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
|
@ -59,11 +60,15 @@ class Archive {
|
|||
// For unpacked file, this method will return its real path.
|
||||
bool CopyFileOut(const base::FilePath& path, base::FilePath* out);
|
||||
|
||||
// Returns the file's fd.
|
||||
int GetFD() const;
|
||||
|
||||
base::FilePath path() const { return path_; }
|
||||
base::DictionaryValue* header() const { return header_.get(); }
|
||||
|
||||
private:
|
||||
base::FilePath path_;
|
||||
base::File file_;
|
||||
uint32 header_size_;
|
||||
scoped_ptr<base::DictionaryValue> header_;
|
||||
|
||||
|
|
|
@ -36,17 +36,16 @@ bool ScopedTemporaryFile::Init() {
|
|||
return base::CreateTemporaryFile(&path_);
|
||||
}
|
||||
|
||||
bool ScopedTemporaryFile::InitFromFile(const base::FilePath& path,
|
||||
bool ScopedTemporaryFile::InitFromFile(base::File* src,
|
||||
uint64 offset, uint64 size) {
|
||||
if (!src->IsValid())
|
||||
return false;
|
||||
|
||||
if (!Init())
|
||||
return false;
|
||||
|
||||
base::File src(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
|
||||
if (!src.IsValid())
|
||||
return false;
|
||||
|
||||
std::vector<char> buf(size);
|
||||
int len = src.Read(offset, buf.data(), buf.size());
|
||||
int len = src->Read(offset, buf.data(), buf.size());
|
||||
if (len != static_cast<int>(size))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
|
||||
#include "base/files/file_path.h"
|
||||
|
||||
namespace base {
|
||||
class File;
|
||||
}
|
||||
|
||||
namespace asar {
|
||||
|
||||
// An object representing a temporary file that should be cleaned up when this
|
||||
|
@ -22,7 +26,7 @@ class ScopedTemporaryFile {
|
|||
bool Init();
|
||||
|
||||
// Init an temporary file and fill it with content of |path|.
|
||||
bool InitFromFile(const base::FilePath& path, uint64 offset, uint64 size);
|
||||
bool InitFromFile(base::File* src, uint64 offset, uint64 size);
|
||||
|
||||
base::FilePath path() const { return path_; }
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#define ATOM_VERSION_H
|
||||
|
||||
#define ATOM_MAJOR_VERSION 0
|
||||
#define ATOM_MINOR_VERSION 25
|
||||
#define ATOM_PATCH_VERSION 2
|
||||
#define ATOM_MINOR_VERSION 26
|
||||
#define ATOM_PATCH_VERSION 0
|
||||
|
||||
#define ATOM_VERSION_IS_RELEASE 1
|
||||
|
||||
|
|
|
@ -236,21 +236,20 @@ exports.wrapFsWithAsar = (fs) ->
|
|||
return fs.readFile realPath, options, callback
|
||||
|
||||
if not options
|
||||
options = encoding: null, flag: 'r'
|
||||
options = encoding: null
|
||||
else if util.isString options
|
||||
options = encoding: options, flag: 'r'
|
||||
options = encoding: options
|
||||
else if not util.isObject options
|
||||
throw new TypeError('Bad arguments')
|
||||
|
||||
flag = options.flag || 'r'
|
||||
encoding = options.encoding
|
||||
|
||||
buffer = new Buffer(info.size)
|
||||
open archive.path, flag, (error, fd) ->
|
||||
return callback error if error
|
||||
fs.read fd, buffer, 0, info.size, info.offset, (error) ->
|
||||
fs.close fd, ->
|
||||
callback error, if encoding then buffer.toString encoding else buffer
|
||||
fd = archive.getFd()
|
||||
return notFoundError asarPath, filePath, callback unless fd >= 0
|
||||
|
||||
fs.read fd, buffer, 0, info.size, info.offset, (error) ->
|
||||
callback error, if encoding then buffer.toString encoding else buffer
|
||||
|
||||
openSync = fs.openSync
|
||||
readFileSync = fs.readFileSync
|
||||
|
@ -270,23 +269,19 @@ exports.wrapFsWithAsar = (fs) ->
|
|||
return fs.readFileSync realPath, options
|
||||
|
||||
if not options
|
||||
options = encoding: null, flag: 'r'
|
||||
options = encoding: null
|
||||
else if util.isString options
|
||||
options = encoding: options, flag: 'r'
|
||||
options = encoding: options
|
||||
else if not util.isObject options
|
||||
throw new TypeError('Bad arguments')
|
||||
|
||||
flag = options.flag || 'r'
|
||||
encoding = options.encoding
|
||||
|
||||
buffer = new Buffer(info.size)
|
||||
fd = openSync archive.path, flag
|
||||
try
|
||||
fs.readSync fd, buffer, 0, info.size, info.offset
|
||||
catch e
|
||||
throw e
|
||||
finally
|
||||
fs.closeSync fd
|
||||
fd = archive.getFd()
|
||||
notFoundError asarPath, filePath unless fd >= 0
|
||||
|
||||
fs.readSync fd, buffer, 0, info.size, info.offset
|
||||
if encoding then buffer.toString encoding else buffer
|
||||
|
||||
readdir = fs.readdir
|
||||
|
|
|
@ -63,6 +63,12 @@ const char kDirectWrite[] = "direct-write";
|
|||
// Enable plugins.
|
||||
const char kEnablePlugins[] = "enable-plugins";
|
||||
|
||||
// Ppapi Flash path.
|
||||
const char kPpapiFlashPath[] = "ppapi-flash-path";
|
||||
|
||||
// Ppapi Flash version.
|
||||
const char kPpapiFlashVersion[] = "ppapi-flash-version";
|
||||
|
||||
// Instancd ID of guest WebContents.
|
||||
const char kGuestInstanceID[] = "guest-instance-id";
|
||||
|
||||
|
@ -78,6 +84,9 @@ const char kType[] = "type";
|
|||
// Disable auto-hiding cursor.
|
||||
const char kDisableAutoHideCursor[] = "disable-auto-hide-cursor";
|
||||
|
||||
// Use the OS X's standard window instead of the textured window.
|
||||
const char kStandardWindow[] = "standard-window";
|
||||
|
||||
// Web runtime features.
|
||||
const char kExperimentalFeatures[] = "experimental-features";
|
||||
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
|
||||
|
|
|
@ -37,11 +37,14 @@ extern const char kEnableLargerThanScreen[];
|
|||
extern const char kDarkTheme[];
|
||||
extern const char kDirectWrite[];
|
||||
extern const char kEnablePlugins[];
|
||||
extern const char kPpapiFlashPath[];
|
||||
extern const char kPpapiFlashVersion[];
|
||||
extern const char kGuestInstanceID[];
|
||||
extern const char kPreloadScript[];
|
||||
extern const char kTransparent[];
|
||||
extern const char kType[];
|
||||
extern const char kDisableAutoHideCursor[];
|
||||
extern const char kStandardWindow[];
|
||||
|
||||
extern const char kExperimentalFeatures[];
|
||||
extern const char kExperimentalCanvasFeatures[];
|
||||
|
|
|
@ -110,13 +110,20 @@ exports.require = (module) ->
|
|||
meta = ipc.sendSync 'ATOM_BROWSER_REQUIRE', module
|
||||
moduleCache[module] = metaToValue meta
|
||||
|
||||
# Get current window object.
|
||||
# Get current BrowserWindow object.
|
||||
windowCache = null
|
||||
exports.getCurrentWindow = ->
|
||||
return windowCache if windowCache?
|
||||
meta = ipc.sendSync 'ATOM_BROWSER_CURRENT_WINDOW', process.guestInstanceId
|
||||
windowCache = metaToValue meta
|
||||
|
||||
# Get current WebContents object.
|
||||
webContentsCache = null
|
||||
exports.getCurrentWebContents = ->
|
||||
return webContentsCache if webContentsCache?
|
||||
meta = ipc.sendSync 'ATOM_BROWSER_CURRENT_WEB_CONTENTS'
|
||||
webContentsCache = metaToValue meta
|
||||
|
||||
# Get a global object in browser.
|
||||
exports.getGlobal = (name) ->
|
||||
meta = ipc.sendSync 'ATOM_BROWSER_GLOBAL', name
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "atom/common/options_switches.h"
|
||||
#include "atom/renderer/atom_render_view_observer.h"
|
||||
#include "atom/renderer/guest_view_container.h"
|
||||
#include "chrome/renderer/pepper/pepper_helper.h"
|
||||
#include "chrome/renderer/printing/print_web_view_helper.h"
|
||||
#include "chrome/renderer/tts_dispatcher.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
|
@ -79,6 +80,11 @@ void AtomRendererClient::RenderThreadStarted() {
|
|||
content::RenderThread::Get()->AddObserver(this);
|
||||
}
|
||||
|
||||
void AtomRendererClient::RenderFrameCreated(
|
||||
content::RenderFrame* render_frame) {
|
||||
new PepperHelper(render_frame);
|
||||
}
|
||||
|
||||
void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
|
||||
new printing::PrintWebViewHelper(render_view);
|
||||
new AtomRenderViewObserver(render_view, this);
|
||||
|
|
|
@ -34,6 +34,7 @@ class AtomRendererClient : public content::ContentRendererClient,
|
|||
|
||||
// content::ContentRendererClient:
|
||||
void RenderThreadStarted() override;
|
||||
void RenderFrameCreated(content::RenderFrame*) override;
|
||||
void RenderViewCreated(content::RenderView*) override;
|
||||
blink::WebSpeechSynthesizer* OverrideSpeechSynthesizer(
|
||||
blink::WebSpeechSynthesizerClient* client) override;
|
||||
|
|
|
@ -74,9 +74,17 @@ window.confirm = (message, title='') ->
|
|||
window.prompt = ->
|
||||
throw new Error('prompt() is and will not be supported.')
|
||||
|
||||
# Simple implementation of postMessage.
|
||||
window.opener =
|
||||
postMessage: (message, targetOrigin='*') ->
|
||||
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', message, targetOrigin
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (message, targetOrigin) ->
|
||||
window.postMessage message, targetOrigin
|
||||
|
||||
# Forward history operations to browser.
|
||||
sendHistoryOperation = (args...) ->
|
||||
ipc.send 'ATOM_SHELL_NAVIGATION_CONTROLLER', args...
|
||||
window.history.back = -> sendHistoryOperation 'goBack'
|
||||
window.history.forward = -> sendHistoryOperation 'goForward'
|
||||
window.history.go = (offset) -> sendHistoryOperation 'goToOffset', offset
|
||||
|
|
|
@ -277,13 +277,6 @@ registerWebViewElement = ->
|
|||
remote.getGuestWebContents(internal.guestInstanceId)[m] args...
|
||||
proto[m] = createHandler m for m in methods
|
||||
|
||||
# Return dataUrl instead of nativeImage.
|
||||
proto.getFavicon = (args...) ->
|
||||
internal = v8Util.getHiddenValue this, 'internal'
|
||||
return unless internal
|
||||
favicon = remote.getGuestWebContents(internal.guestInstanceId)['getFavicon'] args...
|
||||
favicon.toDataUrl()
|
||||
|
||||
window.WebView = webFrame.registerEmbedderCustomElement 'webview',
|
||||
prototype: proto
|
||||
|
||||
|
|
74
atom/utility/atom_content_utility_client.cc
Normal file
74
atom/utility/atom_content_utility_client.cc
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/utility/atom_content_utility_client.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/time/time.h"
|
||||
#include "chrome/common/chrome_utility_messages.h"
|
||||
#include "chrome/utility/utility_message_handler.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/utility/utility_thread.h"
|
||||
#include "ipc/ipc_channel.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "chrome/utility/printing_handler.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
bool Send(IPC::Message* message) {
|
||||
return content::UtilityThread::Get()->Send(message);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace atom {
|
||||
|
||||
int64_t AtomContentUtilityClient::max_ipc_message_size_ =
|
||||
IPC::Channel::kMaximumMessageSize;
|
||||
|
||||
AtomContentUtilityClient::AtomContentUtilityClient()
|
||||
: filter_messages_(false) {
|
||||
#if defined(OS_WIN)
|
||||
handlers_.push_back(new PrintingHandler());
|
||||
#endif
|
||||
}
|
||||
|
||||
AtomContentUtilityClient::~AtomContentUtilityClient() {
|
||||
}
|
||||
|
||||
void AtomContentUtilityClient::UtilityThreadStarted() {
|
||||
}
|
||||
|
||||
bool AtomContentUtilityClient::OnMessageReceived(
|
||||
const IPC::Message& message) {
|
||||
if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type()))
|
||||
return false;
|
||||
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(AtomContentUtilityClient, message)
|
||||
IPC_MESSAGE_HANDLER(ChromeUtilityMsg_StartupPing, OnStartupPing)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
|
||||
for (Handlers::iterator it = handlers_.begin();
|
||||
!handled && it != handlers_.end(); ++it) {
|
||||
handled = (*it)->OnMessageReceived(message);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
void AtomContentUtilityClient::OnStartupPing() {
|
||||
Send(new ChromeUtilityHostMsg_ProcessStarted);
|
||||
// Don't release the process, we assume further messages are on the way.
|
||||
}
|
||||
|
||||
} // namespace atom
|
57
atom/utility/atom_content_utility_client.h
Normal file
57
atom/utility/atom_content_utility_client.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_UTILITY_ATOM_CONTENT_UTILITY_CLIENT_H_
|
||||
#define ATOM_UTILITY_ATOM_CONTENT_UTILITY_CLIENT_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/memory/scoped_vector.h"
|
||||
#include "content/public/utility/content_utility_client.h"
|
||||
#include "ipc/ipc_platform_file.h"
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
struct FileDescriptor;
|
||||
}
|
||||
|
||||
class UtilityMessageHandler;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomContentUtilityClient : public content::ContentUtilityClient {
|
||||
public:
|
||||
AtomContentUtilityClient();
|
||||
~AtomContentUtilityClient() override;
|
||||
|
||||
void UtilityThreadStarted() override;
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
|
||||
|
||||
static void set_max_ipc_message_size_for_test(int64_t max_message_size) {
|
||||
max_ipc_message_size_ = max_message_size;
|
||||
}
|
||||
|
||||
private:
|
||||
void OnStartupPing();
|
||||
|
||||
typedef ScopedVector<UtilityMessageHandler> Handlers;
|
||||
Handlers handlers_;
|
||||
|
||||
// Flag to enable whitelisting.
|
||||
bool filter_messages_;
|
||||
// A list of message_ids to filter.
|
||||
std::set<int> message_id_whitelist_;
|
||||
// Maximum IPC msg size (default to kMaximumMessageSize; override for testing)
|
||||
static int64_t max_ipc_message_size_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentUtilityClient);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_UTILITY_ATOM_CONTENT_UTILITY_CLIENT_H_
|
|
@ -58,6 +58,8 @@ void GlobalShortcutListenerWin::OnWndProc(HWND hwnd,
|
|||
modifiers |= (LOWORD(lparam) & MOD_SHIFT) ? ui::EF_SHIFT_DOWN : 0;
|
||||
modifiers |= (LOWORD(lparam) & MOD_ALT) ? ui::EF_ALT_DOWN : 0;
|
||||
modifiers |= (LOWORD(lparam) & MOD_CONTROL) ? ui::EF_CONTROL_DOWN : 0;
|
||||
modifiers |= (LOWORD(lparam) & MOD_WIN) ? ui::EF_COMMAND_DOWN : 0;
|
||||
|
||||
ui::Accelerator accelerator(
|
||||
ui::KeyboardCodeForWindowsKeyCode(key_code), modifiers);
|
||||
|
||||
|
@ -72,6 +74,8 @@ bool GlobalShortcutListenerWin::RegisterAcceleratorImpl(
|
|||
modifiers |= accelerator.IsShiftDown() ? MOD_SHIFT : 0;
|
||||
modifiers |= accelerator.IsCtrlDown() ? MOD_CONTROL : 0;
|
||||
modifiers |= accelerator.IsAltDown() ? MOD_ALT : 0;
|
||||
modifiers |= accelerator.IsCmdDown() ? MOD_WIN : 0;
|
||||
|
||||
static int hotkey_id = 0;
|
||||
bool success = !!RegisterHotKey(
|
||||
gfx::SingletonHwnd::GetInstance()->hwnd(),
|
||||
|
|
|
@ -35,6 +35,7 @@ int GetNativeModifiers(const ui::Accelerator& accelerator) {
|
|||
modifiers |= accelerator.IsShiftDown() ? ShiftMask : 0;
|
||||
modifiers |= accelerator.IsCtrlDown() ? ControlMask : 0;
|
||||
modifiers |= accelerator.IsAltDown() ? Mod1Mask : 0;
|
||||
modifiers |= accelerator.IsCmdDown() ? Mod4Mask : 0;
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
@ -148,6 +149,8 @@ void GlobalShortcutListenerX11::OnXKeyPressEvent(::XEvent* x_event) {
|
|||
modifiers |= (x_event->xkey.state & ShiftMask) ? ui::EF_SHIFT_DOWN : 0;
|
||||
modifiers |= (x_event->xkey.state & ControlMask) ? ui::EF_CONTROL_DOWN : 0;
|
||||
modifiers |= (x_event->xkey.state & Mod1Mask) ? ui::EF_ALT_DOWN : 0;
|
||||
// For Windows key
|
||||
modifiers |= (x_event->xkey.state & Mod4Mask) ? ui::EF_COMMAND_DOWN: 0;
|
||||
|
||||
ui::Accelerator accelerator(
|
||||
ui::KeyboardCodeFromXKeyEvent(x_event), modifiers);
|
||||
|
|
495
chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc
Normal file
495
chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc
Normal file
|
@ -0,0 +1,495 @@
|
|||
// Copyright 2014 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 "chrome/browser/printing/pdf_to_emf_converter.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "base/files/file.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/logging.h"
|
||||
#include "chrome/common/chrome_utility_messages.h"
|
||||
#include "chrome/common/print_messages.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/child_process_data.h"
|
||||
#include "content/public/browser/utility_process_host.h"
|
||||
#include "content/public/browser/utility_process_host_client.h"
|
||||
#include "printing/emf_win.h"
|
||||
#include "printing/pdf_render_settings.h"
|
||||
|
||||
namespace printing {
|
||||
|
||||
namespace {
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
class PdfToEmfConverterImpl;
|
||||
|
||||
// Allows to delete temporary directory after all temporary files created inside
|
||||
// are closed. Windows cannot delete directory with opened files. Directory is
|
||||
// used to store PDF and metafiles. PDF should be gone by the time utility
|
||||
// process exits. Metafiles should be gone when all LazyEmf destroyed.
|
||||
class RefCountedTempDir
|
||||
: public base::RefCountedThreadSafe<RefCountedTempDir,
|
||||
BrowserThread::DeleteOnFileThread> {
|
||||
public:
|
||||
RefCountedTempDir() { ignore_result(temp_dir_.CreateUniqueTempDir()); }
|
||||
bool IsValid() const { return temp_dir_.IsValid(); }
|
||||
const base::FilePath& GetPath() const { return temp_dir_.path(); }
|
||||
|
||||
private:
|
||||
friend struct BrowserThread::DeleteOnThread<BrowserThread::FILE>;
|
||||
friend class base::DeleteHelper<RefCountedTempDir>;
|
||||
~RefCountedTempDir() {}
|
||||
|
||||
base::ScopedTempDir temp_dir_;
|
||||
DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir);
|
||||
};
|
||||
|
||||
typedef scoped_ptr<base::File, BrowserThread::DeleteOnFileThread>
|
||||
ScopedTempFile;
|
||||
|
||||
// Wrapper for Emf to keep only file handle in memory, and load actual data only
|
||||
// on playback. Emf::InitFromFile() can play metafile directly from disk, but it
|
||||
// can't open file handles. We need file handles to reliably delete temporary
|
||||
// files, and to efficiently interact with utility process.
|
||||
class LazyEmf : public MetafilePlayer {
|
||||
public:
|
||||
LazyEmf(const scoped_refptr<RefCountedTempDir>& temp_dir, ScopedTempFile file)
|
||||
: temp_dir_(temp_dir), file_(file.Pass()) {}
|
||||
virtual ~LazyEmf() { Close(); }
|
||||
|
||||
virtual bool SafePlayback(HDC hdc) const override;
|
||||
virtual bool SaveTo(base::File* file) const override;
|
||||
|
||||
private:
|
||||
void Close() const;
|
||||
bool LoadEmf(Emf* emf) const;
|
||||
|
||||
mutable scoped_refptr<RefCountedTempDir> temp_dir_;
|
||||
mutable ScopedTempFile file_; // Mutable because of consts in base class.
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LazyEmf);
|
||||
};
|
||||
|
||||
// Converts PDF into EMF.
|
||||
// Class uses 3 threads: UI, IO and FILE.
|
||||
// Internal workflow is following:
|
||||
// 1. Create instance on the UI thread. (files_, settings_,)
|
||||
// 2. Create pdf file on the FILE thread.
|
||||
// 3. Start utility process and start conversion on the IO thread.
|
||||
// 4. Utility process returns page count.
|
||||
// 5. For each page:
|
||||
// 1. Clients requests page with file handle to a temp file.
|
||||
// 2. Utility converts the page, save it to the file and reply.
|
||||
//
|
||||
// All these steps work sequentially, so no data should be accessed
|
||||
// simultaneously by several threads.
|
||||
class PdfToEmfUtilityProcessHostClient
|
||||
: public content::UtilityProcessHostClient {
|
||||
public:
|
||||
PdfToEmfUtilityProcessHostClient(
|
||||
base::WeakPtr<PdfToEmfConverterImpl> converter,
|
||||
const PdfRenderSettings& settings);
|
||||
|
||||
void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
||||
const PdfToEmfConverter::StartCallback& start_callback);
|
||||
|
||||
void GetPage(int page_number,
|
||||
const PdfToEmfConverter::GetPageCallback& get_page_callback);
|
||||
|
||||
void Stop();
|
||||
|
||||
// UtilityProcessHostClient implementation.
|
||||
virtual void OnProcessCrashed(int exit_code) override;
|
||||
virtual void OnProcessLaunchFailed() override;
|
||||
virtual bool OnMessageReceived(const IPC::Message& message) override;
|
||||
|
||||
private:
|
||||
class GetPageCallbackData {
|
||||
MOVE_ONLY_TYPE_FOR_CPP_03(GetPageCallbackData, RValue);
|
||||
|
||||
public:
|
||||
GetPageCallbackData(int page_number,
|
||||
PdfToEmfConverter::GetPageCallback callback)
|
||||
: page_number_(page_number), callback_(callback) {}
|
||||
|
||||
// Move constructor for STL.
|
||||
GetPageCallbackData(RValue other) { this->operator=(other); }
|
||||
|
||||
// Move assignment for STL.
|
||||
GetPageCallbackData& operator=(RValue rhs) {
|
||||
page_number_ = rhs.object->page_number_;
|
||||
callback_ = rhs.object->callback_;
|
||||
emf_ = rhs.object->emf_.Pass();
|
||||
return *this;
|
||||
}
|
||||
|
||||
int page_number() const { return page_number_; }
|
||||
const PdfToEmfConverter::GetPageCallback& callback() const {
|
||||
return callback_;
|
||||
}
|
||||
ScopedTempFile emf() { return emf_.Pass(); }
|
||||
void set_emf(ScopedTempFile emf) { emf_ = emf.Pass(); }
|
||||
|
||||
private:
|
||||
int page_number_;
|
||||
PdfToEmfConverter::GetPageCallback callback_;
|
||||
ScopedTempFile emf_;
|
||||
};
|
||||
|
||||
virtual ~PdfToEmfUtilityProcessHostClient();
|
||||
|
||||
bool Send(IPC::Message* msg);
|
||||
|
||||
// Message handlers.
|
||||
void OnProcessStarted();
|
||||
void OnPageCount(int page_count);
|
||||
void OnPageDone(bool success, float scale_factor);
|
||||
|
||||
void OnFailed();
|
||||
void OnTempPdfReady(ScopedTempFile pdf);
|
||||
void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf);
|
||||
|
||||
scoped_refptr<RefCountedTempDir> temp_dir_;
|
||||
|
||||
// Used to suppress callbacks after PdfToEmfConverterImpl is deleted.
|
||||
base::WeakPtr<PdfToEmfConverterImpl> converter_;
|
||||
PdfRenderSettings settings_;
|
||||
scoped_refptr<base::RefCountedMemory> data_;
|
||||
|
||||
// Document loaded callback.
|
||||
PdfToEmfConverter::StartCallback start_callback_;
|
||||
|
||||
// Process host for IPC.
|
||||
base::WeakPtr<content::UtilityProcessHost> utility_process_host_;
|
||||
|
||||
// Queue of callbacks for GetPage() requests. Utility process should reply
|
||||
// with PageDone in the same order as requests were received.
|
||||
// Use containers that keeps element pointers valid after push() and pop().
|
||||
typedef std::queue<GetPageCallbackData> GetPageCallbacks;
|
||||
GetPageCallbacks get_page_callbacks_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient);
|
||||
};
|
||||
|
||||
class PdfToEmfConverterImpl : public PdfToEmfConverter {
|
||||
public:
|
||||
PdfToEmfConverterImpl();
|
||||
|
||||
virtual ~PdfToEmfConverterImpl();
|
||||
|
||||
virtual void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
||||
const PdfRenderSettings& conversion_settings,
|
||||
const StartCallback& start_callback) override;
|
||||
|
||||
virtual void GetPage(int page_number,
|
||||
const GetPageCallback& get_page_callback) override;
|
||||
|
||||
// Helps to cancel callbacks if this object is destroyed.
|
||||
void RunCallback(const base::Closure& callback);
|
||||
|
||||
private:
|
||||
scoped_refptr<PdfToEmfUtilityProcessHostClient> utility_client_;
|
||||
base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl);
|
||||
};
|
||||
|
||||
ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) {
|
||||
if (!temp_dir->get())
|
||||
*temp_dir = new RefCountedTempDir();
|
||||
ScopedTempFile file;
|
||||
if (!(*temp_dir)->IsValid())
|
||||
return file.Pass();
|
||||
base::FilePath path;
|
||||
if (!base::CreateTemporaryFileInDir((*temp_dir)->GetPath(), &path))
|
||||
return file.Pass();
|
||||
file.reset(new base::File(path,
|
||||
base::File::FLAG_CREATE_ALWAYS |
|
||||
base::File::FLAG_WRITE |
|
||||
base::File::FLAG_READ |
|
||||
base::File::FLAG_DELETE_ON_CLOSE |
|
||||
base::File::FLAG_TEMPORARY));
|
||||
if (!file->IsValid())
|
||||
file.reset();
|
||||
return file.Pass();
|
||||
}
|
||||
|
||||
ScopedTempFile CreateTempPdfFile(
|
||||
const scoped_refptr<base::RefCountedMemory>& data,
|
||||
scoped_refptr<RefCountedTempDir>* temp_dir) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
|
||||
|
||||
ScopedTempFile pdf_file = CreateTempFile(temp_dir);
|
||||
if (!pdf_file ||
|
||||
static_cast<int>(data->size()) !=
|
||||
pdf_file->WriteAtCurrentPos(data->front_as<char>(), data->size())) {
|
||||
pdf_file.reset();
|
||||
}
|
||||
pdf_file->Seek(base::File::FROM_BEGIN, 0);
|
||||
return pdf_file.Pass();
|
||||
}
|
||||
|
||||
bool LazyEmf::SafePlayback(HDC hdc) const {
|
||||
Emf emf;
|
||||
bool result = LoadEmf(&emf) && emf.SafePlayback(hdc);
|
||||
// TODO(vitalybuka): Fix destruction of metafiles. For some reasons
|
||||
// instances of Emf are not deleted. crbug.com/411683
|
||||
// It's known that the Emf going to be played just once to a printer. So just
|
||||
// release file here.
|
||||
Close();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool LazyEmf::SaveTo(base::File* file) const {
|
||||
Emf emf;
|
||||
return LoadEmf(&emf) && emf.SaveTo(file);
|
||||
}
|
||||
|
||||
void LazyEmf::Close() const {
|
||||
file_.reset();
|
||||
temp_dir_ = NULL;
|
||||
}
|
||||
|
||||
bool LazyEmf::LoadEmf(Emf* emf) const {
|
||||
file_->Seek(base::File::FROM_BEGIN, 0);
|
||||
int64 size = file_->GetLength();
|
||||
if (size <= 0)
|
||||
return false;
|
||||
std::vector<char> data(size);
|
||||
if (file_->ReadAtCurrentPos(data.data(), data.size()) != size)
|
||||
return false;
|
||||
return emf->InitFromData(data.data(), data.size());
|
||||
}
|
||||
|
||||
PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient(
|
||||
base::WeakPtr<PdfToEmfConverterImpl> converter,
|
||||
const PdfRenderSettings& settings)
|
||||
: converter_(converter), settings_(settings) {
|
||||
}
|
||||
|
||||
PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() {
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::Start(
|
||||
const scoped_refptr<base::RefCountedMemory>& data,
|
||||
const PdfToEmfConverter::StartCallback& start_callback) {
|
||||
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
|
||||
BrowserThread::PostTask(BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
base::Bind(&PdfToEmfUtilityProcessHostClient::Start,
|
||||
this,
|
||||
data,
|
||||
start_callback));
|
||||
return;
|
||||
}
|
||||
data_ = data;
|
||||
|
||||
// Store callback before any OnFailed() call to make it called on failure.
|
||||
start_callback_ = start_callback;
|
||||
|
||||
// NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load
|
||||
// gdiplus.dll, change how rendering happens, and not be able to correctly
|
||||
// generate when sent to a metafile DC.
|
||||
utility_process_host_ =
|
||||
content::UtilityProcessHost::Create(
|
||||
this, base::MessageLoop::current()->message_loop_proxy())
|
||||
->AsWeakPtr();
|
||||
if (!utility_process_host_)
|
||||
return OnFailed();
|
||||
// Should reply with OnProcessStarted().
|
||||
Send(new ChromeUtilityMsg_StartupPing);
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnProcessStarted() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
if (!utility_process_host_)
|
||||
return OnFailed();
|
||||
|
||||
scoped_refptr<base::RefCountedMemory> data = data_;
|
||||
data_ = NULL;
|
||||
BrowserThread::PostTaskAndReplyWithResult(
|
||||
BrowserThread::FILE,
|
||||
FROM_HERE,
|
||||
base::Bind(&CreateTempPdfFile, data, &temp_dir_),
|
||||
base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this));
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
if (!utility_process_host_)
|
||||
return OnFailed();
|
||||
base::ProcessHandle process = utility_process_host_->GetData().handle;
|
||||
// Should reply with OnPageCount().
|
||||
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(
|
||||
IPC::GetFileHandleForProcess(pdf->GetPlatformFile(), process, false),
|
||||
settings_));
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
if (start_callback_.is_null())
|
||||
return OnFailed();
|
||||
BrowserThread::PostTask(BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&PdfToEmfConverterImpl::RunCallback,
|
||||
converter_,
|
||||
base::Bind(start_callback_, page_count)));
|
||||
start_callback_.Reset();
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::GetPage(
|
||||
int page_number,
|
||||
const PdfToEmfConverter::GetPageCallback& get_page_callback) {
|
||||
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
base::Bind(&PdfToEmfUtilityProcessHostClient::GetPage,
|
||||
this,
|
||||
page_number,
|
||||
get_page_callback));
|
||||
return;
|
||||
}
|
||||
|
||||
// Store callback before any OnFailed() call to make it called on failure.
|
||||
get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback));
|
||||
|
||||
if (!utility_process_host_)
|
||||
return OnFailed();
|
||||
|
||||
BrowserThread::PostTaskAndReplyWithResult(
|
||||
BrowserThread::FILE,
|
||||
FROM_HERE,
|
||||
base::Bind(&CreateTempFile, &temp_dir_),
|
||||
base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady,
|
||||
this,
|
||||
&get_page_callbacks_.back()));
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnTempEmfReady(
|
||||
GetPageCallbackData* callback_data,
|
||||
ScopedTempFile emf) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
if (!utility_process_host_)
|
||||
return OnFailed();
|
||||
base::ProcessHandle process = utility_process_host_->GetData().handle;
|
||||
IPC::PlatformFileForTransit transit =
|
||||
IPC::GetFileHandleForProcess(emf->GetPlatformFile(), process, false);
|
||||
callback_data->set_emf(emf.Pass());
|
||||
// Should reply with OnPageDone().
|
||||
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage(
|
||||
callback_data->page_number(), transit));
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success,
|
||||
float scale_factor) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
if (get_page_callbacks_.empty())
|
||||
return OnFailed();
|
||||
scoped_ptr<MetafilePlayer> emf;
|
||||
GetPageCallbackData& data = get_page_callbacks_.front();
|
||||
if (success)
|
||||
emf.reset(new LazyEmf(temp_dir_, data.emf().Pass()));
|
||||
BrowserThread::PostTask(BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&PdfToEmfConverterImpl::RunCallback,
|
||||
converter_,
|
||||
base::Bind(data.callback(),
|
||||
data.page_number(),
|
||||
scale_factor,
|
||||
base::Passed(&emf))));
|
||||
get_page_callbacks_.pop();
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::Stop() {
|
||||
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this));
|
||||
return;
|
||||
}
|
||||
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop());
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) {
|
||||
OnFailed();
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnProcessLaunchFailed() {
|
||||
OnFailed();
|
||||
}
|
||||
|
||||
bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
|
||||
const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message)
|
||||
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted, OnProcessStarted)
|
||||
IPC_MESSAGE_HANDLER(
|
||||
ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
|
||||
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
|
||||
OnPageDone)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) {
|
||||
if (utility_process_host_)
|
||||
return utility_process_host_->Send(msg);
|
||||
delete msg;
|
||||
return false;
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnFailed() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
if (!start_callback_.is_null())
|
||||
OnPageCount(0);
|
||||
while (!get_page_callbacks_.empty())
|
||||
OnPageDone(false, 0.0f);
|
||||
utility_process_host_.reset();
|
||||
}
|
||||
|
||||
PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) {
|
||||
}
|
||||
|
||||
PdfToEmfConverterImpl::~PdfToEmfConverterImpl() {
|
||||
if (utility_client_.get())
|
||||
utility_client_->Stop();
|
||||
}
|
||||
|
||||
void PdfToEmfConverterImpl::Start(
|
||||
const scoped_refptr<base::RefCountedMemory>& data,
|
||||
const PdfRenderSettings& conversion_settings,
|
||||
const StartCallback& start_callback) {
|
||||
DCHECK(!utility_client_.get());
|
||||
utility_client_ = new PdfToEmfUtilityProcessHostClient(
|
||||
weak_ptr_factory_.GetWeakPtr(), conversion_settings);
|
||||
utility_client_->Start(data, start_callback);
|
||||
}
|
||||
|
||||
void PdfToEmfConverterImpl::GetPage(int page_number,
|
||||
const GetPageCallback& get_page_callback) {
|
||||
utility_client_->GetPage(page_number, get_page_callback);
|
||||
}
|
||||
|
||||
void PdfToEmfConverterImpl::RunCallback(const base::Closure& callback) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PdfToEmfConverter::~PdfToEmfConverter() {
|
||||
}
|
||||
|
||||
// static
|
||||
scoped_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() {
|
||||
return scoped_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl());
|
||||
}
|
||||
|
||||
} // namespace printing
|
48
chromium_src/chrome/browser/printing/pdf_to_emf_converter.h
Normal file
48
chromium_src/chrome/browser/printing/pdf_to_emf_converter.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
#ifndef CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_
|
||||
#define CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/ref_counted_memory.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace printing {
|
||||
|
||||
class MetafilePlayer;
|
||||
class PdfRenderSettings;
|
||||
|
||||
class PdfToEmfConverter {
|
||||
public:
|
||||
typedef base::Callback<void(int page_count)> StartCallback;
|
||||
typedef base::Callback<void(int page_number,
|
||||
float scale_factor,
|
||||
scoped_ptr<MetafilePlayer> emf)> GetPageCallback;
|
||||
|
||||
virtual ~PdfToEmfConverter();
|
||||
|
||||
static scoped_ptr<PdfToEmfConverter> CreateDefault();
|
||||
|
||||
// Starts conversion of PDF provided as |data|. Calls |start_callback|
|
||||
// with positive |page_count|. |page_count| is 0 if initialization failed.
|
||||
virtual void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
||||
const PdfRenderSettings& conversion_settings,
|
||||
const StartCallback& start_callback) = 0;
|
||||
|
||||
// Requests conversion of the page. |page_number| is 0-base page number in
|
||||
// PDF provided in Start() call.
|
||||
// Calls |get_page_callback| after conversion. |emf| of callback in not NULL
|
||||
// if conversion succeeded.
|
||||
virtual void GetPage(int page_number,
|
||||
const GetPageCallback& get_page_callback) = 0;
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_
|
|
@ -17,6 +17,12 @@
|
|||
#include "printing/printed_document.h"
|
||||
#include "printing/printed_page.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "chrome/browser/printing/pdf_to_emf_converter.h"
|
||||
#include "printing/pdf_render_settings.h"
|
||||
#endif
|
||||
|
||||
|
||||
using base::TimeDelta;
|
||||
|
||||
namespace {
|
||||
|
@ -272,6 +278,103 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) {
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
class PrintJob::PdfToEmfState {
|
||||
public:
|
||||
PdfToEmfState(const gfx::Size& page_size, const gfx::Rect& content_area)
|
||||
: page_count_(0),
|
||||
current_page_(0),
|
||||
pages_in_progress_(0),
|
||||
page_size_(page_size),
|
||||
content_area_(content_area),
|
||||
converter_(PdfToEmfConverter::CreateDefault()) {}
|
||||
|
||||
void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
||||
const PdfRenderSettings& conversion_settings,
|
||||
const PdfToEmfConverter::StartCallback& start_callback) {
|
||||
converter_->Start(data, conversion_settings, start_callback);
|
||||
}
|
||||
|
||||
void GetMorePages(
|
||||
const PdfToEmfConverter::GetPageCallback& get_page_callback) {
|
||||
const int kMaxNumberOfTempFilesPerDocument = 3;
|
||||
while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument &&
|
||||
current_page_ < page_count_) {
|
||||
++pages_in_progress_;
|
||||
converter_->GetPage(current_page_++, get_page_callback);
|
||||
}
|
||||
}
|
||||
|
||||
void OnPageProcessed(
|
||||
const PdfToEmfConverter::GetPageCallback& get_page_callback) {
|
||||
--pages_in_progress_;
|
||||
GetMorePages(get_page_callback);
|
||||
// Release converter if we don't need this any more.
|
||||
if (!pages_in_progress_ && current_page_ >= page_count_)
|
||||
converter_.reset();
|
||||
}
|
||||
|
||||
void set_page_count(int page_count) { page_count_ = page_count; }
|
||||
gfx::Size page_size() const { return page_size_; }
|
||||
gfx::Rect content_area() const { return content_area_; }
|
||||
|
||||
private:
|
||||
int page_count_;
|
||||
int current_page_;
|
||||
int pages_in_progress_;
|
||||
gfx::Size page_size_;
|
||||
gfx::Rect content_area_;
|
||||
scoped_ptr<PdfToEmfConverter> converter_;
|
||||
};
|
||||
|
||||
void PrintJob::StartPdfToEmfConversion(
|
||||
const scoped_refptr<base::RefCountedMemory>& bytes,
|
||||
const gfx::Size& page_size,
|
||||
const gfx::Rect& content_area) {
|
||||
DCHECK(!ptd_to_emf_state_.get());
|
||||
ptd_to_emf_state_.reset(new PdfToEmfState(page_size, content_area));
|
||||
const int kPrinterDpi = settings().dpi();
|
||||
ptd_to_emf_state_->Start(
|
||||
bytes,
|
||||
printing::PdfRenderSettings(content_area, kPrinterDpi, true),
|
||||
base::Bind(&PrintJob::OnPdfToEmfStarted, this));
|
||||
}
|
||||
|
||||
void PrintJob::OnPdfToEmfStarted(int page_count) {
|
||||
if (page_count <= 0) {
|
||||
ptd_to_emf_state_.reset();
|
||||
Cancel();
|
||||
return;
|
||||
}
|
||||
ptd_to_emf_state_->set_page_count(page_count);
|
||||
ptd_to_emf_state_->GetMorePages(
|
||||
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
|
||||
}
|
||||
|
||||
void PrintJob::OnPdfToEmfPageConverted(int page_number,
|
||||
float scale_factor,
|
||||
scoped_ptr<MetafilePlayer> emf) {
|
||||
DCHECK(ptd_to_emf_state_);
|
||||
if (!document_.get() || !emf) {
|
||||
ptd_to_emf_state_.reset();
|
||||
Cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the rendered document. It will send notifications to the listener.
|
||||
document_->SetPage(page_number,
|
||||
emf.Pass(),
|
||||
scale_factor,
|
||||
ptd_to_emf_state_->page_size(),
|
||||
ptd_to_emf_state_->content_area());
|
||||
|
||||
ptd_to_emf_state_->GetMorePages(
|
||||
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
|
||||
}
|
||||
|
||||
#endif // OS_WIN
|
||||
|
||||
void PrintJob::OnDocumentDone() {
|
||||
// Be sure to live long enough. The instance could be destroyed by the
|
||||
// JOB_DONE broadcast.
|
||||
|
|
|
@ -90,6 +90,19 @@ class PrintJob : public PrintJobWorkerOwner,
|
|||
// Access the current printed document. Warning: may be NULL.
|
||||
PrintedDocument* document() const;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void StartPdfToEmfConversion(
|
||||
const scoped_refptr<base::RefCountedMemory>& bytes,
|
||||
const gfx::Size& page_size,
|
||||
const gfx::Rect& content_area);
|
||||
|
||||
void OnPdfToEmfStarted(int page_count);
|
||||
void OnPdfToEmfPageConverted(int page_number,
|
||||
float scale_factor,
|
||||
scoped_ptr<MetafilePlayer> emf);
|
||||
|
||||
#endif // OS_WIN
|
||||
|
||||
protected:
|
||||
virtual ~PrintJob();
|
||||
|
||||
|
@ -137,6 +150,11 @@ class PrintJob : public PrintJobWorkerOwner,
|
|||
// the notified calls Cancel() again.
|
||||
bool is_canceling_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
class PdfToEmfState;
|
||||
scoped_ptr<PdfToEmfState> ptd_to_emf_state_;
|
||||
#endif // OS_WIN
|
||||
|
||||
// Used at shutdown so that we can quit a nested message loop.
|
||||
base::WeakPtrFactory<PrintJob> quit_factory_;
|
||||
|
||||
|
|
|
@ -156,6 +156,8 @@ void PrintViewManagerBase::OnDidPrintPage(
|
|||
params.data_size);
|
||||
|
||||
document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf"));
|
||||
print_job_->StartPdfToEmfConversion(
|
||||
bytes, params.page_size, params.content_area);
|
||||
}
|
||||
#endif // !OS_WIN
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright (c) 2012 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 "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h"
|
||||
#include "chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h"
|
||||
#include "chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h"
|
||||
#include "chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h"
|
||||
#include "content/public/browser/browser_ppapi_host.h"
|
||||
#include "ppapi/host/message_filter_host.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ppapi/host/resource_host.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
|
||||
using ppapi::host::MessageFilterHost;
|
||||
using ppapi::host::ResourceHost;
|
||||
using ppapi::host::ResourceMessageFilter;
|
||||
|
||||
namespace chrome {
|
||||
|
||||
ChromeBrowserPepperHostFactory::ChromeBrowserPepperHostFactory(
|
||||
content::BrowserPpapiHost* host)
|
||||
: host_(host) {}
|
||||
|
||||
ChromeBrowserPepperHostFactory::~ChromeBrowserPepperHostFactory() {}
|
||||
|
||||
scoped_ptr<ResourceHost> ChromeBrowserPepperHostFactory::CreateResourceHost(
|
||||
ppapi::host::PpapiHost* host,
|
||||
PP_Resource resource,
|
||||
PP_Instance instance,
|
||||
const IPC::Message& message) {
|
||||
DCHECK(host == host_->GetPpapiHost());
|
||||
|
||||
// Make sure the plugin is giving us a valid instance for this resource.
|
||||
if (!host_->IsValidInstance(instance))
|
||||
return scoped_ptr<ResourceHost>();
|
||||
|
||||
// Private interfaces.
|
||||
if (host_->GetPpapiHost()->permissions().HasPermission(
|
||||
ppapi::PERMISSION_PRIVATE)) {
|
||||
switch (message.type()) {
|
||||
case PpapiHostMsg_Broker_Create::ID: {
|
||||
scoped_refptr<ResourceMessageFilter> broker_filter(
|
||||
new PepperBrokerMessageFilter(instance, host_));
|
||||
return scoped_ptr<ResourceHost>(new MessageFilterHost(
|
||||
host_->GetPpapiHost(), instance, resource, broker_filter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flash interfaces.
|
||||
if (host_->GetPpapiHost()->permissions().HasPermission(
|
||||
ppapi::PERMISSION_FLASH)) {
|
||||
switch (message.type()) {
|
||||
case PpapiHostMsg_Flash_Create::ID:
|
||||
return scoped_ptr<ResourceHost>(
|
||||
new PepperFlashBrowserHost(host_, instance, resource));
|
||||
case PpapiHostMsg_FlashClipboard_Create::ID: {
|
||||
scoped_refptr<ResourceMessageFilter> clipboard_filter(
|
||||
new PepperFlashClipboardMessageFilter);
|
||||
return scoped_ptr<ResourceHost>(new MessageFilterHost(
|
||||
host_->GetPpapiHost(), instance, resource, clipboard_filter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Permissions for the following interfaces will be checked at the
|
||||
// time of the corresponding instance's methods calls (because
|
||||
// permission check can be performed only on the UI
|
||||
// thread). Currently these interfaces are available only for
|
||||
// whitelisted apps which may not have access to the other private
|
||||
// interfaces.
|
||||
if (message.type() == PpapiHostMsg_IsolatedFileSystem_Create::ID) {
|
||||
PepperIsolatedFileSystemMessageFilter* isolated_fs_filter =
|
||||
PepperIsolatedFileSystemMessageFilter::Create(instance, host_);
|
||||
if (!isolated_fs_filter)
|
||||
return scoped_ptr<ResourceHost>();
|
||||
return scoped_ptr<ResourceHost>(
|
||||
new MessageFilterHost(host, instance, resource, isolated_fs_filter));
|
||||
}
|
||||
|
||||
return scoped_ptr<ResourceHost>();
|
||||
}
|
||||
|
||||
} // namespace chrome
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_
|
||||
#define CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "ppapi/host/host_factory.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserPpapiHost;
|
||||
} // namespace content
|
||||
|
||||
namespace chrome {
|
||||
|
||||
class ChromeBrowserPepperHostFactory : public ppapi::host::HostFactory {
|
||||
public:
|
||||
// Non-owning pointer to the filter must outlive this class.
|
||||
explicit ChromeBrowserPepperHostFactory(content::BrowserPpapiHost* host);
|
||||
~ChromeBrowserPepperHostFactory() override;
|
||||
|
||||
scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost(
|
||||
ppapi::host::PpapiHost* host,
|
||||
PP_Resource resource,
|
||||
PP_Instance instance,
|
||||
const IPC::Message& message) override;
|
||||
|
||||
private:
|
||||
// Non-owning pointer.
|
||||
content::BrowserPpapiHost* host_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserPepperHostFactory);
|
||||
};
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) 2012 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 "chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "content/public/browser/browser_ppapi_host.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
#include "ppapi/c/pp_errors.h"
|
||||
#include "ppapi/host/dispatch_host_message.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
using content::BrowserPpapiHost;
|
||||
using content::BrowserThread;
|
||||
using content::RenderProcessHost;
|
||||
|
||||
namespace chrome {
|
||||
|
||||
PepperBrokerMessageFilter::PepperBrokerMessageFilter(PP_Instance instance,
|
||||
BrowserPpapiHost* host)
|
||||
: document_url_(host->GetDocumentURLForInstance(instance)) {
|
||||
int unused;
|
||||
host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused);
|
||||
}
|
||||
|
||||
PepperBrokerMessageFilter::~PepperBrokerMessageFilter() {}
|
||||
|
||||
scoped_refptr<base::TaskRunner>
|
||||
PepperBrokerMessageFilter::OverrideTaskRunnerForMessage(
|
||||
const IPC::Message& message) {
|
||||
return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
|
||||
}
|
||||
|
||||
int32_t PepperBrokerMessageFilter::OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
PPAPI_BEGIN_MESSAGE_MAP(PepperBrokerMessageFilter, msg)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Broker_IsAllowed,
|
||||
OnIsAllowed)
|
||||
PPAPI_END_MESSAGE_MAP()
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int32_t PepperBrokerMessageFilter::OnIsAllowed(
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
} // namespace chrome
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_MESSAGE_FILTER_H_
|
||||
#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_MESSAGE_FILTER_H_
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "ppapi/c/pp_instance.h"
|
||||
#include "ppapi/host/resource_message_filter.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserPpapiHost;
|
||||
}
|
||||
|
||||
namespace ppapi {
|
||||
namespace host {
|
||||
struct HostMessageContext;
|
||||
}
|
||||
}
|
||||
|
||||
namespace chrome {
|
||||
|
||||
// This filter handles messages for the PepperBrokerHost on the UI thread.
|
||||
class PepperBrokerMessageFilter : public ppapi::host::ResourceMessageFilter {
|
||||
public:
|
||||
PepperBrokerMessageFilter(PP_Instance instance,
|
||||
content::BrowserPpapiHost* host);
|
||||
|
||||
private:
|
||||
~PepperBrokerMessageFilter() override;
|
||||
|
||||
// ppapi::host::ResourceMessageFilter overrides.
|
||||
scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
|
||||
const IPC::Message& message) override;
|
||||
int32_t OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) override;
|
||||
|
||||
int32_t OnIsAllowed(ppapi::host::HostMessageContext* context);
|
||||
|
||||
int render_process_id_;
|
||||
GURL document_url_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperBrokerMessageFilter);
|
||||
};
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_MESSAGE_FILTER_H_
|
|
@ -0,0 +1,114 @@
|
|||
// Copyright (c) 2012 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 "chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h"
|
||||
|
||||
#include "base/time/time.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_ppapi_host.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
#include "ppapi/c/pp_errors.h"
|
||||
#include "ppapi/c/private/ppb_flash.h"
|
||||
#include "ppapi/host/dispatch_host_message.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
#include "ppapi/proxy/resource_message_params.h"
|
||||
#include "ppapi/shared_impl/time_conversion.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h>
|
||||
#elif defined(OS_MACOSX)
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
using content::BrowserPpapiHost;
|
||||
using content::BrowserThread;
|
||||
using content::RenderProcessHost;
|
||||
|
||||
namespace chrome {
|
||||
|
||||
PepperFlashBrowserHost::PepperFlashBrowserHost(BrowserPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource)
|
||||
: ResourceHost(host->GetPpapiHost(), instance, resource),
|
||||
host_(host),
|
||||
weak_factory_(this) {
|
||||
int unused;
|
||||
host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused);
|
||||
}
|
||||
|
||||
PepperFlashBrowserHost::~PepperFlashBrowserHost() {}
|
||||
|
||||
int32_t PepperFlashBrowserHost::OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
PPAPI_BEGIN_MESSAGE_MAP(PepperFlashBrowserHost, msg)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_UpdateActivity,
|
||||
OnUpdateActivity)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetLocalTimeZoneOffset,
|
||||
OnGetLocalTimeZoneOffset)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
|
||||
PpapiHostMsg_Flash_GetLocalDataRestrictions, OnGetLocalDataRestrictions)
|
||||
PPAPI_END_MESSAGE_MAP()
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int32_t PepperFlashBrowserHost::OnUpdateActivity(
|
||||
ppapi::host::HostMessageContext* host_context) {
|
||||
#if defined(OS_WIN)
|
||||
// Reading then writing back the same value to the screensaver timeout system
|
||||
// setting resets the countdown which prevents the screensaver from turning
|
||||
// on "for a while". As long as the plugin pings us with this message faster
|
||||
// than the screensaver timeout, it won't go on.
|
||||
int value = 0;
|
||||
if (SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &value, 0))
|
||||
SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, value, NULL, 0);
|
||||
#elif defined(OS_MACOSX)
|
||||
// UpdateSystemActivity(OverallAct);
|
||||
#else
|
||||
// TODO(brettw) implement this for other platforms.
|
||||
#endif
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
int32_t PepperFlashBrowserHost::OnGetLocalTimeZoneOffset(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
const base::Time& t) {
|
||||
// The reason for this processing being in the browser process is that on
|
||||
// Linux, the localtime calls require filesystem access prohibited by the
|
||||
// sandbox.
|
||||
host_context->reply_msg = PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply(
|
||||
ppapi::PPGetLocalTimeZoneOffset(t));
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
int32_t PepperFlashBrowserHost::OnGetLocalDataRestrictions(
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
// Getting the Flash LSO settings requires using the CookieSettings which
|
||||
// belong to the profile which lives on the UI thread. We lazily initialize
|
||||
// |cookie_settings_| by grabbing the reference from the UI thread and then
|
||||
// call |GetLocalDataRestrictions| with it.
|
||||
GURL document_url = host_->GetDocumentURLForInstance(pp_instance());
|
||||
GURL plugin_url = host_->GetPluginURLForInstance(pp_instance());
|
||||
GetLocalDataRestrictions(context->MakeReplyMessageContext(),
|
||||
document_url,
|
||||
plugin_url);
|
||||
return PP_OK_COMPLETIONPENDING;
|
||||
}
|
||||
|
||||
void PepperFlashBrowserHost::GetLocalDataRestrictions(
|
||||
ppapi::host::ReplyMessageContext reply_context,
|
||||
const GURL& document_url,
|
||||
const GURL& plugin_url) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||
|
||||
PP_FlashLSORestrictions restrictions = PP_FLASHLSORESTRICTIONS_NONE;
|
||||
SendReply(reply_context,
|
||||
PpapiPluginMsg_Flash_GetLocalDataRestrictionsReply(
|
||||
static_cast<int32_t>(restrictions)));
|
||||
}
|
||||
|
||||
} // namespace chrome
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_
|
||||
#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "ppapi/host/host_message_context.h"
|
||||
#include "ppapi/host/resource_host.h"
|
||||
|
||||
namespace base {
|
||||
class Time;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class BrowserPpapiHost;
|
||||
class ResourceContext;
|
||||
}
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace chrome {
|
||||
|
||||
class PepperFlashBrowserHost : public ppapi::host::ResourceHost {
|
||||
public:
|
||||
PepperFlashBrowserHost(content::BrowserPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource);
|
||||
~PepperFlashBrowserHost() override;
|
||||
|
||||
// ppapi::host::ResourceHost override.
|
||||
int32_t OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) override;
|
||||
|
||||
private:
|
||||
int32_t OnUpdateActivity(ppapi::host::HostMessageContext* host_context);
|
||||
int32_t OnGetLocalTimeZoneOffset(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
const base::Time& t);
|
||||
int32_t OnGetLocalDataRestrictions(ppapi::host::HostMessageContext* context);
|
||||
|
||||
void GetLocalDataRestrictions(ppapi::host::ReplyMessageContext reply_context,
|
||||
const GURL& document_url,
|
||||
const GURL& plugin_url);
|
||||
|
||||
content::BrowserPpapiHost* host_;
|
||||
int render_process_id_;
|
||||
// For fetching the Flash LSO settings.
|
||||
base::WeakPtrFactory<PepperFlashBrowserHost> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperFlashBrowserHost);
|
||||
};
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_
|
|
@ -0,0 +1,376 @@
|
|||
// Copyright (c) 2012 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 "chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h"
|
||||
|
||||
#include "base/pickle.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "ipc/ipc_message.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
#include "ppapi/c/pp_errors.h"
|
||||
#include "ppapi/c/private/ppb_flash_clipboard.h"
|
||||
#include "ppapi/host/dispatch_host_message.h"
|
||||
#include "ppapi/host/host_message_context.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
#include "ppapi/proxy/resource_message_params.h"
|
||||
#include "ui/base/clipboard/scoped_clipboard_writer.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace chrome {
|
||||
|
||||
namespace {
|
||||
|
||||
const size_t kMaxClipboardWriteSize = 1000000;
|
||||
|
||||
ui::ClipboardType ConvertClipboardType(uint32_t type) {
|
||||
switch (type) {
|
||||
case PP_FLASH_CLIPBOARD_TYPE_STANDARD:
|
||||
return ui::CLIPBOARD_TYPE_COPY_PASTE;
|
||||
case PP_FLASH_CLIPBOARD_TYPE_SELECTION:
|
||||
return ui::CLIPBOARD_TYPE_SELECTION;
|
||||
}
|
||||
NOTREACHED();
|
||||
return ui::CLIPBOARD_TYPE_COPY_PASTE;
|
||||
}
|
||||
|
||||
// Functions to pack/unpack custom data from a pickle. See the header file for
|
||||
// more detail on custom formats in Pepper.
|
||||
// TODO(raymes): Currently pepper custom formats are stored in their own
|
||||
// native format type. However we should be able to store them in the same way
|
||||
// as "Web Custom" formats are. This would allow clipboard data to be shared
|
||||
// between pepper applications and web applications. However currently web apps
|
||||
// assume all data that is placed on the clipboard is UTF16 and pepper allows
|
||||
// arbitrary data so this change would require some reworking of the chrome
|
||||
// clipboard interface for custom data.
|
||||
bool JumpToFormatInPickle(const base::string16& format, PickleIterator* iter) {
|
||||
size_t size = 0;
|
||||
if (!iter->ReadSizeT(&size))
|
||||
return false;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
base::string16 stored_format;
|
||||
if (!iter->ReadString16(&stored_format))
|
||||
return false;
|
||||
if (stored_format == format)
|
||||
return true;
|
||||
int skip_length;
|
||||
if (!iter->ReadLength(&skip_length))
|
||||
return false;
|
||||
if (!iter->SkipBytes(skip_length))
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsFormatAvailableInPickle(const base::string16& format,
|
||||
const Pickle& pickle) {
|
||||
PickleIterator iter(pickle);
|
||||
return JumpToFormatInPickle(format, &iter);
|
||||
}
|
||||
|
||||
std::string ReadDataFromPickle(const base::string16& format,
|
||||
const Pickle& pickle) {
|
||||
std::string result;
|
||||
PickleIterator iter(pickle);
|
||||
if (!JumpToFormatInPickle(format, &iter) || !iter.ReadString(&result))
|
||||
return std::string();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool WriteDataToPickle(const std::map<base::string16, std::string>& data,
|
||||
Pickle* pickle) {
|
||||
pickle->WriteSizeT(data.size());
|
||||
for (std::map<base::string16, std::string>::const_iterator it = data.begin();
|
||||
it != data.end();
|
||||
++it) {
|
||||
if (!pickle->WriteString16(it->first))
|
||||
return false;
|
||||
if (!pickle->WriteString(it->second))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PepperFlashClipboardMessageFilter::PepperFlashClipboardMessageFilter() {}
|
||||
|
||||
PepperFlashClipboardMessageFilter::~PepperFlashClipboardMessageFilter() {}
|
||||
|
||||
scoped_refptr<base::TaskRunner>
|
||||
PepperFlashClipboardMessageFilter::OverrideTaskRunnerForMessage(
|
||||
const IPC::Message& msg) {
|
||||
// Clipboard writes should always occur on the UI thread due to the
|
||||
// restrictions of various platform APIs. In general, the clipboard is not
|
||||
// thread-safe, so all clipboard calls should be serviced from the UI thread.
|
||||
if (msg.type() == PpapiHostMsg_FlashClipboard_WriteData::ID)
|
||||
return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
|
||||
|
||||
// Windows needs clipboard reads to be serviced from the IO thread because
|
||||
// these are sync IPCs which can result in deadlocks with plugins if serviced
|
||||
// from the UI thread. Note that Windows clipboard calls ARE thread-safe so it
|
||||
// is ok for reads and writes to be serviced from different threads.
|
||||
#if !defined(OS_WIN)
|
||||
return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
|
||||
#else
|
||||
return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t PepperFlashClipboardMessageFilter::OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
PPAPI_BEGIN_MESSAGE_MAP(PepperFlashClipboardMessageFilter, msg)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(
|
||||
PpapiHostMsg_FlashClipboard_RegisterCustomFormat,
|
||||
OnMsgRegisterCustomFormat)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(
|
||||
PpapiHostMsg_FlashClipboard_IsFormatAvailable, OnMsgIsFormatAvailable)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_ReadData,
|
||||
OnMsgReadData)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_WriteData,
|
||||
OnMsgWriteData)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(
|
||||
PpapiHostMsg_FlashClipboard_GetSequenceNumber, OnMsgGetSequenceNumber)
|
||||
PPAPI_END_MESSAGE_MAP()
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int32_t PepperFlashClipboardMessageFilter::OnMsgRegisterCustomFormat(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
const std::string& format_name) {
|
||||
uint32_t format = custom_formats_.RegisterFormat(format_name);
|
||||
if (format == PP_FLASH_CLIPBOARD_FORMAT_INVALID)
|
||||
return PP_ERROR_FAILED;
|
||||
host_context->reply_msg =
|
||||
PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply(format);
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
int32_t PepperFlashClipboardMessageFilter::OnMsgIsFormatAvailable(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
uint32_t clipboard_type,
|
||||
uint32_t format) {
|
||||
if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
|
||||
NOTIMPLEMENTED();
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
|
||||
ui::ClipboardType type = ConvertClipboardType(clipboard_type);
|
||||
bool available = false;
|
||||
switch (format) {
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: {
|
||||
bool plain = clipboard->IsFormatAvailable(
|
||||
ui::Clipboard::GetPlainTextFormatType(), type);
|
||||
bool plainw = clipboard->IsFormatAvailable(
|
||||
ui::Clipboard::GetPlainTextWFormatType(), type);
|
||||
available = plain || plainw;
|
||||
break;
|
||||
}
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_HTML:
|
||||
available = clipboard->IsFormatAvailable(
|
||||
ui::Clipboard::GetHtmlFormatType(), type);
|
||||
break;
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_RTF:
|
||||
available =
|
||||
clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), type);
|
||||
break;
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
|
||||
break;
|
||||
default:
|
||||
if (custom_formats_.IsFormatRegistered(format)) {
|
||||
std::string format_name = custom_formats_.GetFormatName(format);
|
||||
std::string clipboard_data;
|
||||
clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(),
|
||||
&clipboard_data);
|
||||
Pickle pickle(clipboard_data.data(), clipboard_data.size());
|
||||
available =
|
||||
IsFormatAvailableInPickle(base::UTF8ToUTF16(format_name), pickle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return available ? PP_OK : PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int32_t PepperFlashClipboardMessageFilter::OnMsgReadData(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
uint32_t clipboard_type,
|
||||
uint32_t format) {
|
||||
if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
|
||||
NOTIMPLEMENTED();
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
|
||||
ui::ClipboardType type = ConvertClipboardType(clipboard_type);
|
||||
std::string clipboard_string;
|
||||
int32_t result = PP_ERROR_FAILED;
|
||||
switch (format) {
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: {
|
||||
if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
|
||||
type)) {
|
||||
base::string16 text;
|
||||
clipboard->ReadText(type, &text);
|
||||
if (!text.empty()) {
|
||||
result = PP_OK;
|
||||
clipboard_string = base::UTF16ToUTF8(text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If the PlainTextW format isn't available or is empty, take the
|
||||
// ASCII text format.
|
||||
if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
|
||||
type)) {
|
||||
result = PP_OK;
|
||||
clipboard->ReadAsciiText(type, &clipboard_string);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_HTML: {
|
||||
if (!clipboard->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(),
|
||||
type)) {
|
||||
break;
|
||||
}
|
||||
|
||||
base::string16 html;
|
||||
std::string url;
|
||||
uint32 fragment_start;
|
||||
uint32 fragment_end;
|
||||
clipboard->ReadHTML(type, &html, &url, &fragment_start, &fragment_end);
|
||||
result = PP_OK;
|
||||
clipboard_string = base::UTF16ToUTF8(
|
||||
html.substr(fragment_start, fragment_end - fragment_start));
|
||||
break;
|
||||
}
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_RTF: {
|
||||
if (!clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(),
|
||||
type)) {
|
||||
break;
|
||||
}
|
||||
result = PP_OK;
|
||||
clipboard->ReadRTF(type, &clipboard_string);
|
||||
break;
|
||||
}
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
|
||||
break;
|
||||
default: {
|
||||
if (custom_formats_.IsFormatRegistered(format)) {
|
||||
base::string16 format_name =
|
||||
base::UTF8ToUTF16(custom_formats_.GetFormatName(format));
|
||||
std::string clipboard_data;
|
||||
clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(),
|
||||
&clipboard_data);
|
||||
Pickle pickle(clipboard_data.data(), clipboard_data.size());
|
||||
if (IsFormatAvailableInPickle(format_name, pickle)) {
|
||||
result = PP_OK;
|
||||
clipboard_string = ReadDataFromPickle(format_name, pickle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == PP_OK) {
|
||||
host_context->reply_msg =
|
||||
PpapiPluginMsg_FlashClipboard_ReadDataReply(clipboard_string);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t PepperFlashClipboardMessageFilter::OnMsgWriteData(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
uint32_t clipboard_type,
|
||||
const std::vector<uint32_t>& formats,
|
||||
const std::vector<std::string>& data) {
|
||||
if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
|
||||
NOTIMPLEMENTED();
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
if (formats.size() != data.size())
|
||||
return PP_ERROR_FAILED;
|
||||
|
||||
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
|
||||
ui::ClipboardType type = ConvertClipboardType(clipboard_type);
|
||||
// If no formats are passed in clear the clipboard.
|
||||
if (formats.size() == 0) {
|
||||
clipboard->Clear(type);
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
ui::ScopedClipboardWriter scw(type);
|
||||
std::map<base::string16, std::string> custom_data_map;
|
||||
int32_t res = PP_OK;
|
||||
for (uint32_t i = 0; i < formats.size(); ++i) {
|
||||
if (data[i].length() > kMaxClipboardWriteSize) {
|
||||
res = PP_ERROR_NOSPACE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (formats[i]) {
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT:
|
||||
scw.WriteText(base::UTF8ToUTF16(data[i]));
|
||||
break;
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_HTML:
|
||||
scw.WriteHTML(base::UTF8ToUTF16(data[i]), std::string());
|
||||
break;
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_RTF:
|
||||
scw.WriteRTF(data[i]);
|
||||
break;
|
||||
case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
|
||||
res = PP_ERROR_BADARGUMENT;
|
||||
break;
|
||||
default:
|
||||
if (custom_formats_.IsFormatRegistered(formats[i])) {
|
||||
std::string format_name = custom_formats_.GetFormatName(formats[i]);
|
||||
custom_data_map[base::UTF8ToUTF16(format_name)] = data[i];
|
||||
} else {
|
||||
// Invalid format.
|
||||
res = PP_ERROR_BADARGUMENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (res != PP_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
if (custom_data_map.size() > 0) {
|
||||
Pickle pickle;
|
||||
if (WriteDataToPickle(custom_data_map, &pickle)) {
|
||||
scw.WritePickledData(pickle,
|
||||
ui::Clipboard::GetPepperCustomDataFormatType());
|
||||
} else {
|
||||
res = PP_ERROR_BADARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (res != PP_OK) {
|
||||
// Need to clear the objects so nothing is written.
|
||||
scw.Reset();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t PepperFlashClipboardMessageFilter::OnMsgGetSequenceNumber(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
uint32_t clipboard_type) {
|
||||
if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
|
||||
NOTIMPLEMENTED();
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
|
||||
ui::ClipboardType type = ConvertClipboardType(clipboard_type);
|
||||
int64_t sequence_number = clipboard->GetSequenceNumber(type);
|
||||
host_context->reply_msg =
|
||||
PpapiPluginMsg_FlashClipboard_GetSequenceNumberReply(sequence_number);
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
} // namespace chrome
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_H_
|
||||
#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "ppapi/host/resource_message_filter.h"
|
||||
#include "ppapi/shared_impl/flash_clipboard_format_registry.h"
|
||||
|
||||
namespace ppapi {
|
||||
namespace host {
|
||||
struct HostMessageContext;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
class ScopedClipboardWriter;
|
||||
}
|
||||
|
||||
namespace chrome {
|
||||
|
||||
// Resource message filter for accessing the clipboard in Pepper. Pepper
|
||||
// supports reading/writing custom formats from the clipboard. Currently, all
|
||||
// custom formats that are read/written from the clipboard through pepper are
|
||||
// stored in a single real clipboard format (in the same way the "web custom"
|
||||
// clipboard formats are). This is done so that we don't have to have use real
|
||||
// clipboard types for each custom clipboard format which may be a limited
|
||||
// resource on a particular platform.
|
||||
class PepperFlashClipboardMessageFilter
|
||||
: public ppapi::host::ResourceMessageFilter {
|
||||
public:
|
||||
PepperFlashClipboardMessageFilter();
|
||||
|
||||
protected:
|
||||
// ppapi::host::ResourceMessageFilter overrides.
|
||||
scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
|
||||
const IPC::Message& msg) override;
|
||||
int32_t OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) override;
|
||||
|
||||
private:
|
||||
~PepperFlashClipboardMessageFilter() override;
|
||||
|
||||
int32_t OnMsgRegisterCustomFormat(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
const std::string& format_name);
|
||||
int32_t OnMsgIsFormatAvailable(ppapi::host::HostMessageContext* host_context,
|
||||
uint32_t clipboard_type,
|
||||
uint32_t format);
|
||||
int32_t OnMsgReadData(ppapi::host::HostMessageContext* host_context,
|
||||
uint32_t clipoard_type,
|
||||
uint32_t format);
|
||||
int32_t OnMsgWriteData(ppapi::host::HostMessageContext* host_context,
|
||||
uint32_t clipboard_type,
|
||||
const std::vector<uint32_t>& formats,
|
||||
const std::vector<std::string>& data);
|
||||
int32_t OnMsgGetSequenceNumber(ppapi::host::HostMessageContext* host_context,
|
||||
uint32_t clipboard_type);
|
||||
|
||||
int32_t WriteClipboardDataItem(uint32_t format,
|
||||
const std::string& data,
|
||||
ui::ScopedClipboardWriter* scw);
|
||||
|
||||
ppapi::FlashClipboardFormatRegistry custom_formats_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperFlashClipboardMessageFilter);
|
||||
};
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_H_
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright 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 "chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h"
|
||||
|
||||
#include "content/public/browser/browser_ppapi_host.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "ppapi/c/pp_errors.h"
|
||||
#include "ppapi/host/dispatch_host_message.h"
|
||||
#include "ppapi/host/host_message_context.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
#include "ppapi/shared_impl/file_system_util.h"
|
||||
#include "storage/browser/fileapi/isolated_context.h"
|
||||
|
||||
namespace chrome {
|
||||
|
||||
// static
|
||||
PepperIsolatedFileSystemMessageFilter*
|
||||
PepperIsolatedFileSystemMessageFilter::Create(PP_Instance instance,
|
||||
content::BrowserPpapiHost* host) {
|
||||
int render_process_id;
|
||||
int unused_render_frame_id;
|
||||
if (!host->GetRenderFrameIDsForInstance(
|
||||
instance, &render_process_id, &unused_render_frame_id)) {
|
||||
return NULL;
|
||||
}
|
||||
return new PepperIsolatedFileSystemMessageFilter(
|
||||
render_process_id,
|
||||
host->GetProfileDataDirectory(),
|
||||
host->GetDocumentURLForInstance(instance),
|
||||
host->GetPpapiHost());
|
||||
}
|
||||
|
||||
PepperIsolatedFileSystemMessageFilter::PepperIsolatedFileSystemMessageFilter(
|
||||
int render_process_id,
|
||||
const base::FilePath& profile_directory,
|
||||
const GURL& document_url,
|
||||
ppapi::host::PpapiHost* ppapi_host)
|
||||
: render_process_id_(render_process_id),
|
||||
profile_directory_(profile_directory),
|
||||
document_url_(document_url),
|
||||
ppapi_host_(ppapi_host) {
|
||||
}
|
||||
|
||||
PepperIsolatedFileSystemMessageFilter::
|
||||
~PepperIsolatedFileSystemMessageFilter() {}
|
||||
|
||||
scoped_refptr<base::TaskRunner>
|
||||
PepperIsolatedFileSystemMessageFilter::OverrideTaskRunnerForMessage(
|
||||
const IPC::Message& msg) {
|
||||
// In order to reach ExtensionSystem, we need to get ProfileManager first.
|
||||
// ProfileManager lives in UI thread, so we need to do this in UI thread.
|
||||
return content::BrowserThread::GetMessageLoopProxyForThread(
|
||||
content::BrowserThread::UI);
|
||||
}
|
||||
|
||||
int32_t PepperIsolatedFileSystemMessageFilter::OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
PPAPI_BEGIN_MESSAGE_MAP(PepperIsolatedFileSystemMessageFilter, msg)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(
|
||||
PpapiHostMsg_IsolatedFileSystem_BrowserOpen,
|
||||
OnOpenFileSystem)
|
||||
PPAPI_END_MESSAGE_MAP()
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int32_t PepperIsolatedFileSystemMessageFilter::OnOpenFileSystem(
|
||||
ppapi::host::HostMessageContext* context,
|
||||
PP_IsolatedFileSystemType_Private type) {
|
||||
switch (type) {
|
||||
case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_INVALID:
|
||||
case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX:
|
||||
break;
|
||||
case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE:
|
||||
return OpenPluginPrivateFileSystem(context);
|
||||
}
|
||||
NOTREACHED();
|
||||
context->reply_msg =
|
||||
PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(std::string());
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int32_t PepperIsolatedFileSystemMessageFilter::OpenPluginPrivateFileSystem(
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
DCHECK(ppapi_host_);
|
||||
// Only plugins with private permission can open the filesystem.
|
||||
if (!ppapi_host_->permissions().HasPermission(ppapi::PERMISSION_PRIVATE))
|
||||
return PP_ERROR_NOACCESS;
|
||||
|
||||
const std::string& root_name = ppapi::IsolatedFileSystemTypeToRootName(
|
||||
PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE);
|
||||
const std::string& fsid =
|
||||
storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
|
||||
storage::kFileSystemTypePluginPrivate, root_name, base::FilePath());
|
||||
|
||||
// Grant full access of isolated filesystem to renderer process.
|
||||
content::ChildProcessSecurityPolicy* policy =
|
||||
content::ChildProcessSecurityPolicy::GetInstance();
|
||||
policy->GrantCreateReadWriteFileSystem(render_process_id_, fsid);
|
||||
|
||||
context->reply_msg = PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(fsid);
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
} // namespace chrome
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright 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.
|
||||
|
||||
#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_
|
||||
#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "ppapi/c/pp_instance.h"
|
||||
#include "ppapi/c/pp_resource.h"
|
||||
#include "ppapi/c/private/ppb_isolated_file_system_private.h"
|
||||
#include "ppapi/host/resource_host.h"
|
||||
#include "ppapi/host/resource_message_filter.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
class Profile;
|
||||
|
||||
namespace content {
|
||||
class BrowserPpapiHost;
|
||||
}
|
||||
|
||||
namespace ppapi {
|
||||
namespace host {
|
||||
struct HostMessageContext;
|
||||
} // namespace host
|
||||
} // namespace ppapi
|
||||
|
||||
namespace chrome {
|
||||
|
||||
class PepperIsolatedFileSystemMessageFilter
|
||||
: public ppapi::host::ResourceMessageFilter {
|
||||
public:
|
||||
static PepperIsolatedFileSystemMessageFilter* Create(
|
||||
PP_Instance instance,
|
||||
content::BrowserPpapiHost* host);
|
||||
|
||||
// ppapi::host::ResourceMessageFilter implementation.
|
||||
scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
|
||||
const IPC::Message& msg) override;
|
||||
int32_t OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) override;
|
||||
|
||||
private:
|
||||
PepperIsolatedFileSystemMessageFilter(int render_process_id,
|
||||
const base::FilePath& profile_directory,
|
||||
const GURL& document_url,
|
||||
ppapi::host::PpapiHost* ppapi_host_);
|
||||
|
||||
~PepperIsolatedFileSystemMessageFilter() override;
|
||||
|
||||
// Returns filesystem id of isolated filesystem if valid, or empty string
|
||||
// otherwise. This must run on the UI thread because ProfileManager only
|
||||
// allows access on that thread.
|
||||
|
||||
int32_t OnOpenFileSystem(ppapi::host::HostMessageContext* context,
|
||||
PP_IsolatedFileSystemType_Private type);
|
||||
int32_t OpenPluginPrivateFileSystem(ppapi::host::HostMessageContext* context);
|
||||
|
||||
const int render_process_id_;
|
||||
// Keep a copy from original thread.
|
||||
const base::FilePath profile_directory_;
|
||||
const GURL document_url_;
|
||||
|
||||
// Not owned by this object.
|
||||
ppapi::host::PpapiHost* ppapi_host_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperIsolatedFileSystemMessageFilter);
|
||||
};
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_
|
169
chromium_src/chrome/common/chrome_utility_messages.h
Normal file
169
chromium_src/chrome/common/chrome_utility_messages.h
Normal file
|
@ -0,0 +1,169 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
// Multiply-included message file, so no include guard.
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <Windows.h>
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/strings/string16.h"
|
||||
#include "base/tuple.h"
|
||||
#include "base/values.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
#include "ipc/ipc_platform_file.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/gfx/ipc/gfx_param_traits.h"
|
||||
|
||||
// Singly-included section for typedefs.
|
||||
#ifndef CHROME_COMMON_CHROME_UTILITY_MESSAGES_H_
|
||||
#define CHROME_COMMON_CHROME_UTILITY_MESSAGES_H_
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// A vector of filters, each being a Tuple containing a display string (i.e.
|
||||
// "Text Files") and a filter pattern (i.e. "*.txt").
|
||||
typedef std::vector<Tuple<base::string16, base::string16>>
|
||||
GetOpenFileNameFilter;
|
||||
#endif // OS_WIN
|
||||
|
||||
#endif // CHROME_COMMON_CHROME_UTILITY_MESSAGES_H_
|
||||
|
||||
#define IPC_MESSAGE_START ChromeUtilityMsgStart
|
||||
|
||||
|
||||
#if defined(OS_WIN)
|
||||
IPC_STRUCT_BEGIN(ChromeUtilityMsg_GetSaveFileName_Params)
|
||||
IPC_STRUCT_MEMBER(HWND, owner)
|
||||
IPC_STRUCT_MEMBER(DWORD, flags)
|
||||
IPC_STRUCT_MEMBER(GetOpenFileNameFilter, filters)
|
||||
IPC_STRUCT_MEMBER(int, one_based_filter_index)
|
||||
IPC_STRUCT_MEMBER(base::FilePath, suggested_filename)
|
||||
IPC_STRUCT_MEMBER(base::FilePath, initial_directory)
|
||||
IPC_STRUCT_MEMBER(base::string16, default_extension)
|
||||
IPC_STRUCT_END()
|
||||
#endif // OS_WIN
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Utility process messages:
|
||||
// These are messages from the browser to the utility process.
|
||||
|
||||
// Tell the utility process to parse a JSON string into a Value object.
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_ParseJSON,
|
||||
std::string /* JSON to parse */)
|
||||
|
||||
// Tell the utility process to decode the given image data.
|
||||
IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_DecodeImage,
|
||||
std::vector<unsigned char> /* encoded image contents */,
|
||||
bool /* shrink image if needed for IPC msg limit */)
|
||||
|
||||
// Tell the utility process to decode the given JPEG image data with a robust
|
||||
// libjpeg codec.
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_RobustJPEGDecodeImage,
|
||||
std::vector<unsigned char>) // encoded image contents
|
||||
|
||||
// Tell the utility process to patch the given |input_file| using |patch_file|
|
||||
// and place the output in |output_file|. The patch should use the bsdiff
|
||||
// algorithm (Courgette's version).
|
||||
IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_PatchFileBsdiff,
|
||||
base::FilePath /* input_file */,
|
||||
base::FilePath /* patch_file */,
|
||||
base::FilePath /* output_file */)
|
||||
|
||||
// Tell the utility process to patch the given |input_file| using |patch_file|
|
||||
// and place the output in |output_file|. The patch should use the Courgette
|
||||
// algorithm.
|
||||
IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_PatchFileCourgette,
|
||||
base::FilePath /* input_file */,
|
||||
base::FilePath /* patch_file */,
|
||||
base::FilePath /* output_file */)
|
||||
|
||||
|
||||
// Requests the utility process to respond with a
|
||||
// ChromeUtilityHostMsg_ProcessStarted message once it has started. This may
|
||||
// be used if the host process needs a handle to the running utility process.
|
||||
IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_StartupPing)
|
||||
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Invokes ui::base::win::OpenFileViaShell from the utility process.
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_OpenFileViaShell,
|
||||
base::FilePath /* full_path */)
|
||||
|
||||
// Invokes ui::base::win::OpenFolderViaShell from the utility process.
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_OpenFolderViaShell,
|
||||
base::FilePath /* full_path */)
|
||||
|
||||
// Instructs the utility process to invoke GetOpenFileName. |owner| is the
|
||||
// parent of the modal dialog, |flags| are OFN_* flags. |filter| constrains the
|
||||
// user's file choices. |initial_directory| and |filename| select the directory
|
||||
// to be displayed and the file to be initially selected.
|
||||
//
|
||||
// Either ChromeUtilityHostMsg_GetOpenFileName_Failed or
|
||||
// ChromeUtilityHostMsg_GetOpenFileName_Result will be returned when the
|
||||
// operation completes whether due to error or user action.
|
||||
IPC_MESSAGE_CONTROL5(ChromeUtilityMsg_GetOpenFileName,
|
||||
HWND /* owner */,
|
||||
DWORD /* flags */,
|
||||
GetOpenFileNameFilter /* filter */,
|
||||
base::FilePath /* initial_directory */,
|
||||
base::FilePath /* filename */)
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_GetSaveFileName,
|
||||
ChromeUtilityMsg_GetSaveFileName_Params /* params */)
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Utility process host messages:
|
||||
// These are messages from the utility process to the browser.
|
||||
|
||||
// Reply when the utility process successfully parsed a JSON string.
|
||||
//
|
||||
// WARNING: The result can be of any Value subclass type, but we can't easily
|
||||
// pass indeterminate value types by const object reference with our IPC macros,
|
||||
// so we put the result Value into a ListValue. Handlers should examine the
|
||||
// first (and only) element of the ListValue for the actual result.
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_ParseJSON_Succeeded,
|
||||
base::ListValue)
|
||||
|
||||
// Reply when the utility process failed in parsing a JSON string.
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_ParseJSON_Failed,
|
||||
std::string /* error message, if any*/)
|
||||
|
||||
// Reply when the utility process has failed while unpacking and parsing a
|
||||
// web resource. |error_message| is a user-readable explanation of what
|
||||
// went wrong.
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_UnpackWebResource_Failed,
|
||||
std::string /* error_message, if any */)
|
||||
|
||||
// Reply when the utility process has succeeded in decoding the image.
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_DecodeImage_Succeeded,
|
||||
SkBitmap) // decoded image
|
||||
|
||||
// Reply when an error occurred decoding the image.
|
||||
IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_DecodeImage_Failed)
|
||||
|
||||
// Reply when a file has been patched.
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_PatchFile_Finished, int /* result */)
|
||||
|
||||
|
||||
// Reply when the utility process has started.
|
||||
IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_ProcessStarted)
|
||||
|
||||
|
||||
#if defined(OS_WIN)
|
||||
IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_GetOpenFileName_Failed)
|
||||
IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_GetOpenFileName_Result,
|
||||
base::FilePath /* directory */,
|
||||
std::vector<base::FilePath> /* filenames */)
|
||||
IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_GetSaveFileName_Failed)
|
||||
IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_GetSaveFileName_Result,
|
||||
base::FilePath /* path */,
|
||||
int /* one_based_filter_index */)
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_BuildDirectWriteFontCache,
|
||||
base::FilePath /* cache file path */)
|
||||
#endif // defined(OS_WIN)
|
|
@ -17,6 +17,13 @@
|
|||
#include "ui/gfx/native_widget_types.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ipc/ipc_platform_file.h"
|
||||
#include "printing/backend/print_backend.h"
|
||||
#include "printing/page_range.h"
|
||||
#include "printing/pdf_render_settings.h"
|
||||
#endif
|
||||
|
||||
#ifndef CHROME_COMMON_PRINT_MESSAGES_H_
|
||||
#define CHROME_COMMON_PRINT_MESSAGES_H_
|
||||
|
||||
|
@ -239,3 +246,31 @@ IPC_MESSAGE_ROUTED0(PrintHostMsg_ShowInvalidPrinterSettingsError)
|
|||
// Tell the browser printing failed.
|
||||
IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintingFailed,
|
||||
int /* document cookie */)
|
||||
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Tell the utility process to start rendering the given PDF into a metafile.
|
||||
// Utility process would be alive until
|
||||
// ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop message.
|
||||
IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles,
|
||||
IPC::PlatformFileForTransit, /* input_file */
|
||||
printing::PdfRenderSettings /* settings */)
|
||||
|
||||
// Requests conversion of the next page.
|
||||
IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage,
|
||||
int /* page_number */,
|
||||
IPC::PlatformFileForTransit /* output_file */)
|
||||
|
||||
// Requests utility process to stop conversion and exit.
|
||||
IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop)
|
||||
|
||||
// Reply when the utility process loaded PDF. |page_count| is 0, if loading
|
||||
// failed.
|
||||
IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount,
|
||||
int /* page_count */)
|
||||
|
||||
// Reply when the utility process rendered the PDF page.
|
||||
IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
|
||||
bool /* success */,
|
||||
float /* scale_factor */)
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright (c) 2012 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 "chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "chrome/renderer/pepper/pepper_flash_font_file_host.h"
|
||||
#include "chrome/renderer/pepper/pepper_flash_fullscreen_host.h"
|
||||
#include "chrome/renderer/pepper/pepper_flash_menu_host.h"
|
||||
#include "chrome/renderer/pepper/pepper_flash_renderer_host.h"
|
||||
#include "content/public/renderer/renderer_ppapi_host.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ppapi/host/resource_host.h"
|
||||
#include "ppapi/proxy/ppapi_message_utils.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
|
||||
using ppapi::host::ResourceHost;
|
||||
|
||||
ChromeRendererPepperHostFactory::ChromeRendererPepperHostFactory(
|
||||
content::RendererPpapiHost* host)
|
||||
: host_(host) {}
|
||||
|
||||
ChromeRendererPepperHostFactory::~ChromeRendererPepperHostFactory() {}
|
||||
|
||||
scoped_ptr<ResourceHost> ChromeRendererPepperHostFactory::CreateResourceHost(
|
||||
ppapi::host::PpapiHost* host,
|
||||
PP_Resource resource,
|
||||
PP_Instance instance,
|
||||
const IPC::Message& message) {
|
||||
DCHECK_EQ(host_->GetPpapiHost(), host);
|
||||
|
||||
// Make sure the plugin is giving us a valid instance for this resource.
|
||||
if (!host_->IsValidInstance(instance))
|
||||
return scoped_ptr<ResourceHost>();
|
||||
|
||||
if (host_->GetPpapiHost()->permissions().HasPermission(
|
||||
ppapi::PERMISSION_FLASH)) {
|
||||
switch (message.type()) {
|
||||
case PpapiHostMsg_Flash_Create::ID: {
|
||||
return scoped_ptr<ResourceHost>(
|
||||
new PepperFlashRendererHost(host_, instance, resource));
|
||||
}
|
||||
case PpapiHostMsg_FlashFullscreen_Create::ID: {
|
||||
return scoped_ptr<ResourceHost>(
|
||||
new PepperFlashFullscreenHost(host_, instance, resource));
|
||||
}
|
||||
case PpapiHostMsg_FlashMenu_Create::ID: {
|
||||
ppapi::proxy::SerializedFlashMenu serialized_menu;
|
||||
if (ppapi::UnpackMessage<PpapiHostMsg_FlashMenu_Create>(
|
||||
message, &serialized_menu)) {
|
||||
return scoped_ptr<ResourceHost>(new PepperFlashMenuHost(
|
||||
host_, instance, resource, serialized_menu));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(raymes): PDF also needs access to the FlashFontFileHost currently.
|
||||
// We should either rename PPB_FlashFont_File to PPB_FontFile_Private or get
|
||||
// rid of its use in PDF if possible.
|
||||
if (host_->GetPpapiHost()->permissions().HasPermission(
|
||||
ppapi::PERMISSION_FLASH) ||
|
||||
host_->GetPpapiHost()->permissions().HasPermission(
|
||||
ppapi::PERMISSION_PRIVATE)) {
|
||||
switch (message.type()) {
|
||||
case PpapiHostMsg_FlashFontFile_Create::ID: {
|
||||
ppapi::proxy::SerializedFontDescription description;
|
||||
PP_PrivateFontCharset charset;
|
||||
if (ppapi::UnpackMessage<PpapiHostMsg_FlashFontFile_Create>(
|
||||
message, &description, &charset)) {
|
||||
return scoped_ptr<ResourceHost>(new PepperFlashFontFileHost(
|
||||
host_, instance, resource, description, charset));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return scoped_ptr<ResourceHost>();
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
#ifndef CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_
|
||||
#define CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "ppapi/host/host_factory.h"
|
||||
|
||||
namespace content {
|
||||
class RendererPpapiHost;
|
||||
}
|
||||
|
||||
class ChromeRendererPepperHostFactory : public ppapi::host::HostFactory {
|
||||
public:
|
||||
explicit ChromeRendererPepperHostFactory(content::RendererPpapiHost* host);
|
||||
~ChromeRendererPepperHostFactory() override;
|
||||
|
||||
// HostFactory.
|
||||
scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost(
|
||||
ppapi::host::PpapiHost* host,
|
||||
PP_Resource resource,
|
||||
PP_Instance instance,
|
||||
const IPC::Message& message) override;
|
||||
|
||||
private:
|
||||
// Not owned by this object.
|
||||
content::RendererPpapiHost* host_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ChromeRendererPepperHostFactory);
|
||||
};
|
||||
|
||||
#endif // CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2012 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 "chrome/renderer/pepper/pepper_flash_font_file_host.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "content/public/renderer/renderer_ppapi_host.h"
|
||||
#include "ppapi/c/pp_errors.h"
|
||||
#include "ppapi/host/dispatch_host_message.h"
|
||||
#include "ppapi/host/host_message_context.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
#include "ppapi/proxy/serialized_structs.h"
|
||||
|
||||
#if defined(OS_LINUX) || defined(OS_OPENBSD)
|
||||
#include "content/public/common/child_process_sandbox_support_linux.h"
|
||||
#endif
|
||||
|
||||
PepperFlashFontFileHost::PepperFlashFontFileHost(
|
||||
content::RendererPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource,
|
||||
const ppapi::proxy::SerializedFontDescription& description,
|
||||
PP_PrivateFontCharset charset)
|
||||
: ResourceHost(host->GetPpapiHost(), instance, resource) {
|
||||
#if defined(OS_LINUX) || defined(OS_OPENBSD)
|
||||
fd_.reset(content::MatchFontWithFallback(
|
||||
description.face.c_str(),
|
||||
description.weight >= PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD,
|
||||
description.italic,
|
||||
charset,
|
||||
PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT));
|
||||
#endif // defined(OS_LINUX) || defined(OS_OPENBSD)
|
||||
}
|
||||
|
||||
PepperFlashFontFileHost::~PepperFlashFontFileHost() {}
|
||||
|
||||
int32_t PepperFlashFontFileHost::OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
PPAPI_BEGIN_MESSAGE_MAP(PepperFlashFontFileHost, msg)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFontFile_GetFontTable,
|
||||
OnGetFontTable)
|
||||
PPAPI_END_MESSAGE_MAP()
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int32_t PepperFlashFontFileHost::OnGetFontTable(
|
||||
ppapi::host::HostMessageContext* context,
|
||||
uint32_t table) {
|
||||
std::string contents;
|
||||
int32_t result = PP_ERROR_FAILED;
|
||||
#if defined(OS_LINUX) || defined(OS_OPENBSD)
|
||||
int fd = fd_.get();
|
||||
if (fd != -1) {
|
||||
size_t length = 0;
|
||||
if (content::GetFontTable(fd, table, 0 /* offset */, NULL, &length)) {
|
||||
contents.resize(length);
|
||||
uint8_t* contents_ptr =
|
||||
reinterpret_cast<uint8_t*>(const_cast<char*>(contents.c_str()));
|
||||
if (content::GetFontTable(
|
||||
fd, table, 0 /* offset */, contents_ptr, &length)) {
|
||||
result = PP_OK;
|
||||
} else {
|
||||
contents.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // defined(OS_LINUX) || defined(OS_OPENBSD)
|
||||
|
||||
context->reply_msg = PpapiPluginMsg_FlashFontFile_GetFontTableReply(contents);
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_
|
||||
#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "ppapi/c/private/pp_private_font_charset.h"
|
||||
#include "ppapi/host/resource_host.h"
|
||||
|
||||
#if defined(OS_LINUX) || defined(OS_OPENBSD)
|
||||
#include "base/files/scoped_file.h"
|
||||
#endif
|
||||
|
||||
namespace content {
|
||||
class RendererPpapiHost;
|
||||
}
|
||||
|
||||
namespace ppapi {
|
||||
namespace proxy {
|
||||
struct SerializedFontDescription;
|
||||
}
|
||||
}
|
||||
|
||||
class PepperFlashFontFileHost : public ppapi::host::ResourceHost {
|
||||
public:
|
||||
PepperFlashFontFileHost(
|
||||
content::RendererPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource,
|
||||
const ppapi::proxy::SerializedFontDescription& description,
|
||||
PP_PrivateFontCharset charset);
|
||||
~PepperFlashFontFileHost() override;
|
||||
|
||||
int32_t OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) override;
|
||||
|
||||
private:
|
||||
int32_t OnGetFontTable(ppapi::host::HostMessageContext* context,
|
||||
uint32_t table);
|
||||
|
||||
#if defined(OS_LINUX) || defined(OS_OPENBSD)
|
||||
base::ScopedFD fd_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperFlashFontFileHost);
|
||||
};
|
||||
|
||||
#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 2012 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 "chrome/renderer/pepper/pepper_flash_fullscreen_host.h"
|
||||
|
||||
#include "content/public/renderer/pepper_plugin_instance.h"
|
||||
#include "content/public/renderer/renderer_ppapi_host.h"
|
||||
#include "ppapi/c/pp_errors.h"
|
||||
#include "ppapi/host/dispatch_host_message.h"
|
||||
#include "ppapi/host/host_message_context.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
|
||||
PepperFlashFullscreenHost::PepperFlashFullscreenHost(
|
||||
content::RendererPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource)
|
||||
: ResourceHost(host->GetPpapiHost(), instance, resource),
|
||||
renderer_ppapi_host_(host) {}
|
||||
|
||||
PepperFlashFullscreenHost::~PepperFlashFullscreenHost() {}
|
||||
|
||||
int32_t PepperFlashFullscreenHost::OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
PPAPI_BEGIN_MESSAGE_MAP(PepperFlashFullscreenHost, msg)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(
|
||||
PpapiHostMsg_FlashFullscreen_SetFullscreen,
|
||||
OnSetFullscreen)
|
||||
PPAPI_END_MESSAGE_MAP()
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int32_t PepperFlashFullscreenHost::OnSetFullscreen(
|
||||
ppapi::host::HostMessageContext* context,
|
||||
bool fullscreen) {
|
||||
content::PepperPluginInstance* plugin_instance =
|
||||
renderer_ppapi_host_->GetPluginInstance(pp_instance());
|
||||
if (plugin_instance && plugin_instance->FlashSetFullscreen(fullscreen, true))
|
||||
return PP_OK;
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_
|
||||
#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "ppapi/host/resource_host.h"
|
||||
|
||||
namespace content {
|
||||
class RendererPpapiHost;
|
||||
}
|
||||
|
||||
class PepperFlashFullscreenHost : public ppapi::host::ResourceHost {
|
||||
public:
|
||||
PepperFlashFullscreenHost(content::RendererPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource);
|
||||
~PepperFlashFullscreenHost() override;
|
||||
|
||||
int32_t OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) override;
|
||||
|
||||
private:
|
||||
int32_t OnSetFullscreen(ppapi::host::HostMessageContext* context,
|
||||
bool fullscreen);
|
||||
|
||||
// Non-owning pointer.
|
||||
content::RendererPpapiHost* renderer_ppapi_host_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperFlashFullscreenHost);
|
||||
};
|
||||
|
||||
#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_
|
202
chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc
Normal file
202
chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc
Normal file
|
@ -0,0 +1,202 @@
|
|||
// Copyright (c) 2012 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 "chrome/renderer/pepper/pepper_flash_menu_host.h"
|
||||
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/common/context_menu_params.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "content/public/renderer/renderer_ppapi_host.h"
|
||||
#include "ipc/ipc_message.h"
|
||||
#include "ppapi/c/private/ppb_flash_menu.h"
|
||||
#include "ppapi/host/dispatch_host_message.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
#include "ppapi/proxy/serialized_flash_menu.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Maximum depth of submenus allowed (e.g., 1 indicates that submenus are
|
||||
// allowed, but not sub-submenus).
|
||||
const size_t kMaxMenuDepth = 2;
|
||||
|
||||
// Maximum number of entries in any single menu (including separators).
|
||||
const size_t kMaxMenuEntries = 50;
|
||||
|
||||
// Maximum total number of entries in the |menu_id_map| (see below).
|
||||
// (Limit to 500 real entries; reserve the 0 action as an invalid entry.)
|
||||
const size_t kMaxMenuIdMapEntries = 501;
|
||||
|
||||
// Converts menu data from one form to another.
|
||||
// - |depth| is the current nested depth (call it starting with 0).
|
||||
// - |menu_id_map| is such that |menu_id_map[output_item.action] ==
|
||||
// input_item.id| (where |action| is what a |MenuItem| has, |id| is what a
|
||||
// |PP_Flash_MenuItem| has).
|
||||
bool ConvertMenuData(const PP_Flash_Menu* in_menu,
|
||||
size_t depth,
|
||||
std::vector<content::MenuItem>* out_menu,
|
||||
std::vector<int32_t>* menu_id_map) {
|
||||
if (depth > kMaxMenuDepth || !in_menu)
|
||||
return false;
|
||||
|
||||
// Clear the output, just in case.
|
||||
out_menu->clear();
|
||||
|
||||
if (!in_menu->count)
|
||||
return true; // Nothing else to do.
|
||||
|
||||
if (!in_menu->items || in_menu->count > kMaxMenuEntries)
|
||||
return false;
|
||||
for (uint32_t i = 0; i < in_menu->count; i++) {
|
||||
content::MenuItem item;
|
||||
|
||||
PP_Flash_MenuItem_Type type = in_menu->items[i].type;
|
||||
switch (type) {
|
||||
case PP_FLASH_MENUITEM_TYPE_NORMAL:
|
||||
item.type = content::MenuItem::OPTION;
|
||||
break;
|
||||
case PP_FLASH_MENUITEM_TYPE_CHECKBOX:
|
||||
item.type = content::MenuItem::CHECKABLE_OPTION;
|
||||
break;
|
||||
case PP_FLASH_MENUITEM_TYPE_SEPARATOR:
|
||||
item.type = content::MenuItem::SEPARATOR;
|
||||
break;
|
||||
case PP_FLASH_MENUITEM_TYPE_SUBMENU:
|
||||
item.type = content::MenuItem::SUBMENU;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (in_menu->items[i].name)
|
||||
item.label = base::UTF8ToUTF16(in_menu->items[i].name);
|
||||
if (menu_id_map->size() >= kMaxMenuIdMapEntries)
|
||||
return false;
|
||||
item.action = static_cast<unsigned>(menu_id_map->size());
|
||||
// This sets |(*menu_id_map)[item.action] = in_menu->items[i].id|.
|
||||
menu_id_map->push_back(in_menu->items[i].id);
|
||||
item.enabled = PP_ToBool(in_menu->items[i].enabled);
|
||||
item.checked = PP_ToBool(in_menu->items[i].checked);
|
||||
if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU) {
|
||||
if (!ConvertMenuData(
|
||||
in_menu->items[i].submenu, depth + 1, &item.submenu, menu_id_map))
|
||||
return false;
|
||||
}
|
||||
|
||||
out_menu->push_back(item);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PepperFlashMenuHost::PepperFlashMenuHost(
|
||||
content::RendererPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource,
|
||||
const ppapi::proxy::SerializedFlashMenu& serial_menu)
|
||||
: ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource),
|
||||
renderer_ppapi_host_(host),
|
||||
showing_context_menu_(false),
|
||||
context_menu_request_id_(0),
|
||||
has_saved_context_menu_action_(false),
|
||||
saved_context_menu_action_(0) {
|
||||
menu_id_map_.push_back(0); // Reserve |menu_id_map_[0]|.
|
||||
if (!ConvertMenuData(serial_menu.pp_menu(), 0, &menu_data_, &menu_id_map_)) {
|
||||
menu_data_.clear();
|
||||
menu_id_map_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
PepperFlashMenuHost::~PepperFlashMenuHost() {
|
||||
if (showing_context_menu_) {
|
||||
content::RenderFrame* render_frame =
|
||||
renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance());
|
||||
if (render_frame)
|
||||
render_frame->CancelContextMenu(context_menu_request_id_);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t PepperFlashMenuHost::OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
PPAPI_BEGIN_MESSAGE_MAP(PepperFlashMenuHost, msg)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashMenu_Show,
|
||||
OnHostMsgShow)
|
||||
PPAPI_END_MESSAGE_MAP()
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int32_t PepperFlashMenuHost::OnHostMsgShow(
|
||||
ppapi::host::HostMessageContext* context,
|
||||
const PP_Point& location) {
|
||||
// Note that all early returns must do a SendMenuReply. The sync result for
|
||||
// this message isn't used, so to forward the error to the plugin, we need to
|
||||
// additionally call SendMenuReply explicitly.
|
||||
if (menu_data_.empty()) {
|
||||
SendMenuReply(PP_ERROR_FAILED, -1);
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
if (showing_context_menu_) {
|
||||
SendMenuReply(PP_ERROR_INPROGRESS, -1);
|
||||
return PP_ERROR_INPROGRESS;
|
||||
}
|
||||
|
||||
content::RenderFrame* render_frame =
|
||||
renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance());
|
||||
|
||||
content::ContextMenuParams params;
|
||||
params.x = location.x;
|
||||
params.y = location.y;
|
||||
params.custom_context.is_pepper_menu = true;
|
||||
params.custom_context.render_widget_id =
|
||||
renderer_ppapi_host_->GetRoutingIDForWidget(pp_instance());
|
||||
params.custom_items = menu_data_;
|
||||
|
||||
// Transform the position to be in render frame's coordinates.
|
||||
gfx::Point render_frame_pt = renderer_ppapi_host_->PluginPointToRenderFrame(
|
||||
pp_instance(), gfx::Point(location.x, location.y));
|
||||
params.x = render_frame_pt.x();
|
||||
params.y = render_frame_pt.y();
|
||||
|
||||
showing_context_menu_ = true;
|
||||
context_menu_request_id_ = render_frame->ShowContextMenu(this, params);
|
||||
|
||||
// Note: the show message is sync so this OK is for the sync reply which we
|
||||
// don't actually use (see the comment in the resource file for this). The
|
||||
// async message containing the context menu action will be sent in the
|
||||
// future.
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
void PepperFlashMenuHost::OnMenuAction(int request_id, unsigned action) {
|
||||
// Just save the action.
|
||||
DCHECK(!has_saved_context_menu_action_);
|
||||
has_saved_context_menu_action_ = true;
|
||||
saved_context_menu_action_ = action;
|
||||
}
|
||||
|
||||
void PepperFlashMenuHost::OnMenuClosed(int request_id) {
|
||||
if (has_saved_context_menu_action_ &&
|
||||
saved_context_menu_action_ < menu_id_map_.size()) {
|
||||
SendMenuReply(PP_OK, menu_id_map_[saved_context_menu_action_]);
|
||||
has_saved_context_menu_action_ = false;
|
||||
saved_context_menu_action_ = 0;
|
||||
} else {
|
||||
SendMenuReply(PP_ERROR_USERCANCEL, -1);
|
||||
}
|
||||
|
||||
showing_context_menu_ = false;
|
||||
context_menu_request_id_ = 0;
|
||||
}
|
||||
|
||||
void PepperFlashMenuHost::SendMenuReply(int32_t result, int action) {
|
||||
ppapi::host::ReplyMessageContext reply_context(
|
||||
ppapi::proxy::ResourceMessageReplyParams(pp_resource(), 0),
|
||||
NULL,
|
||||
MSG_ROUTING_NONE);
|
||||
reply_context.params.set_result(result);
|
||||
host()->SendReply(reply_context, PpapiPluginMsg_FlashMenu_ShowReply(action));
|
||||
}
|
69
chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h
Normal file
69
chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_MENU_HOST_H_
|
||||
#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_MENU_HOST_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "content/public/renderer/context_menu_client.h"
|
||||
#include "ppapi/c/pp_point.h"
|
||||
#include "ppapi/host/host_message_context.h"
|
||||
#include "ppapi/host/resource_host.h"
|
||||
|
||||
namespace content {
|
||||
class RendererPpapiHost;
|
||||
struct MenuItem;
|
||||
}
|
||||
|
||||
namespace ppapi {
|
||||
namespace proxy {
|
||||
class SerializedFlashMenu;
|
||||
}
|
||||
}
|
||||
|
||||
class PepperFlashMenuHost : public ppapi::host::ResourceHost,
|
||||
public content::ContextMenuClient {
|
||||
public:
|
||||
PepperFlashMenuHost(content::RendererPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource,
|
||||
const ppapi::proxy::SerializedFlashMenu& serial_menu);
|
||||
~PepperFlashMenuHost() override;
|
||||
|
||||
int32_t OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) override;
|
||||
|
||||
private:
|
||||
int32_t OnHostMsgShow(ppapi::host::HostMessageContext* context,
|
||||
const PP_Point& location);
|
||||
|
||||
// ContextMenuClient implementation.
|
||||
void OnMenuAction(int request_id, unsigned action) override;
|
||||
void OnMenuClosed(int request_id) override;
|
||||
|
||||
void SendMenuReply(int32_t result, int action);
|
||||
|
||||
content::RendererPpapiHost* renderer_ppapi_host_;
|
||||
|
||||
bool showing_context_menu_;
|
||||
int context_menu_request_id_;
|
||||
|
||||
std::vector<content::MenuItem> menu_data_;
|
||||
|
||||
// We send |MenuItem|s, which have an |unsigned| "action" field instead of
|
||||
// an |int32_t| ID. (CONTENT also limits the range of valid values for
|
||||
// actions.) This maps actions to IDs.
|
||||
std::vector<int32_t> menu_id_map_;
|
||||
|
||||
// Used to send a single context menu "completion" upon menu close.
|
||||
bool has_saved_context_menu_action_;
|
||||
unsigned saved_context_menu_action_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperFlashMenuHost);
|
||||
};
|
||||
|
||||
#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_MENU_HOST_H_
|
|
@ -0,0 +1,373 @@
|
|||
// Copyright (c) 2012 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 "chrome/renderer/pepper/pepper_flash_renderer_host.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/metrics/histogram.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "content/public/renderer/pepper_plugin_instance.h"
|
||||
#include "content/public/renderer/render_thread.h"
|
||||
#include "content/public/renderer/renderer_ppapi_host.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
#include "net/http/http_util.h"
|
||||
#include "ppapi/c/pp_errors.h"
|
||||
#include "ppapi/c/trusted/ppb_browser_font_trusted.h"
|
||||
#include "ppapi/host/dispatch_host_message.h"
|
||||
#include "ppapi/proxy/host_dispatcher.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
#include "ppapi/proxy/resource_message_params.h"
|
||||
#include "ppapi/proxy/serialized_structs.h"
|
||||
#include "ppapi/thunk/enter.h"
|
||||
#include "ppapi/thunk/ppb_image_data_api.h"
|
||||
#include "skia/ext/platform_canvas.h"
|
||||
#include "third_party/skia/include/core/SkCanvas.h"
|
||||
#include "third_party/skia/include/core/SkMatrix.h"
|
||||
#include "third_party/skia/include/core/SkPaint.h"
|
||||
#include "third_party/skia/include/core/SkPoint.h"
|
||||
#include "third_party/skia/include/core/SkTemplates.h"
|
||||
#include "third_party/skia/include/core/SkTypeface.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
using ppapi::thunk::EnterResourceNoLock;
|
||||
using ppapi::thunk::PPB_ImageData_API;
|
||||
|
||||
namespace {
|
||||
|
||||
// Some non-simple HTTP request headers that Flash may set.
|
||||
// (Please see http://www.w3.org/TR/cors/#simple-header for the definition of
|
||||
// simple headers.)
|
||||
//
|
||||
// The list and the enum defined below are used to collect data about request
|
||||
// headers used in PPB_Flash.Navigate() calls, in order to understand the impact
|
||||
// of rejecting PPB_Flash.Navigate() requests with non-simple headers.
|
||||
//
|
||||
// TODO(yzshen): We should be able to remove the histogram recording code once
|
||||
// we get the answer.
|
||||
const char* const kRejectedHttpRequestHeaders[] = {
|
||||
"authorization", //
|
||||
"cache-control", //
|
||||
"content-encoding", //
|
||||
"content-md5", //
|
||||
"content-type", // If the media type is not one of those covered by the
|
||||
// simple header definition.
|
||||
"expires", //
|
||||
"from", //
|
||||
"if-match", //
|
||||
"if-none-match", //
|
||||
"if-range", //
|
||||
"if-unmodified-since", //
|
||||
"pragma", //
|
||||
"referer" //
|
||||
};
|
||||
|
||||
// Please note that new entries should be added right above
|
||||
// FLASH_NAVIGATE_USAGE_ENUM_COUNT, and existing entries shouldn't be re-ordered
|
||||
// or removed, since this ordering is used in a histogram.
|
||||
enum FlashNavigateUsage {
|
||||
// This section must be in the same order as kRejectedHttpRequestHeaders.
|
||||
REJECT_AUTHORIZATION = 0,
|
||||
REJECT_CACHE_CONTROL,
|
||||
REJECT_CONTENT_ENCODING,
|
||||
REJECT_CONTENT_MD5,
|
||||
REJECT_CONTENT_TYPE,
|
||||
REJECT_EXPIRES,
|
||||
REJECT_FROM,
|
||||
REJECT_IF_MATCH,
|
||||
REJECT_IF_NONE_MATCH,
|
||||
REJECT_IF_RANGE,
|
||||
REJECT_IF_UNMODIFIED_SINCE,
|
||||
REJECT_PRAGMA,
|
||||
REJECT_REFERER,
|
||||
|
||||
// The navigate request is rejected because of headers not listed above
|
||||
// (e.g., custom headers).
|
||||
REJECT_OTHER_HEADERS,
|
||||
|
||||
// Total number of rejected navigate requests.
|
||||
TOTAL_REJECTED_NAVIGATE_REQUESTS,
|
||||
|
||||
// Total number of navigate requests.
|
||||
TOTAL_NAVIGATE_REQUESTS,
|
||||
FLASH_NAVIGATE_USAGE_ENUM_COUNT
|
||||
};
|
||||
|
||||
static base::LazyInstance<std::map<std::string, FlashNavigateUsage> >
|
||||
g_rejected_headers = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
bool IsSimpleHeader(const std::string& lower_case_header_name,
|
||||
const std::string& header_value) {
|
||||
if (lower_case_header_name == "accept" ||
|
||||
lower_case_header_name == "accept-language" ||
|
||||
lower_case_header_name == "content-language") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lower_case_header_name == "content-type") {
|
||||
std::string lower_case_mime_type;
|
||||
std::string lower_case_charset;
|
||||
bool had_charset = false;
|
||||
net::HttpUtil::ParseContentType(header_value,
|
||||
&lower_case_mime_type,
|
||||
&lower_case_charset,
|
||||
&had_charset,
|
||||
NULL);
|
||||
return lower_case_mime_type == "application/x-www-form-urlencoded" ||
|
||||
lower_case_mime_type == "multipart/form-data" ||
|
||||
lower_case_mime_type == "text/plain";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RecordFlashNavigateUsage(FlashNavigateUsage usage) {
|
||||
DCHECK_NE(FLASH_NAVIGATE_USAGE_ENUM_COUNT, usage);
|
||||
UMA_HISTOGRAM_ENUMERATION(
|
||||
"Plugin.FlashNavigateUsage", usage, FLASH_NAVIGATE_USAGE_ENUM_COUNT);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PepperFlashRendererHost::PepperFlashRendererHost(
|
||||
content::RendererPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource)
|
||||
: ResourceHost(host->GetPpapiHost(), instance, resource),
|
||||
host_(host),
|
||||
weak_factory_(this) {}
|
||||
|
||||
PepperFlashRendererHost::~PepperFlashRendererHost() {
|
||||
// This object may be destroyed in the middle of a sync message. If that is
|
||||
// the case, make sure we respond to all the pending navigate calls.
|
||||
std::vector<ppapi::host::ReplyMessageContext>::reverse_iterator it;
|
||||
for (it = navigate_replies_.rbegin(); it != navigate_replies_.rend(); ++it)
|
||||
SendReply(*it, IPC::Message());
|
||||
}
|
||||
|
||||
int32_t PepperFlashRendererHost::OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
PPAPI_BEGIN_MESSAGE_MAP(PepperFlashRendererHost, msg)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetProxyForURL,
|
||||
OnGetProxyForURL)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_SetInstanceAlwaysOnTop,
|
||||
OnSetInstanceAlwaysOnTop)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_DrawGlyphs,
|
||||
OnDrawGlyphs)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_Navigate, OnNavigate)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_IsRectTopmost,
|
||||
OnIsRectTopmost)
|
||||
PPAPI_END_MESSAGE_MAP()
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int32_t PepperFlashRendererHost::OnGetProxyForURL(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
const std::string& url) {
|
||||
GURL gurl(url);
|
||||
if (!gurl.is_valid())
|
||||
return PP_ERROR_FAILED;
|
||||
std::string proxy;
|
||||
bool result = content::RenderThread::Get()->ResolveProxy(gurl, &proxy);
|
||||
if (!result)
|
||||
return PP_ERROR_FAILED;
|
||||
host_context->reply_msg = PpapiPluginMsg_Flash_GetProxyForURLReply(proxy);
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
int32_t PepperFlashRendererHost::OnSetInstanceAlwaysOnTop(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
bool on_top) {
|
||||
content::PepperPluginInstance* plugin_instance =
|
||||
host_->GetPluginInstance(pp_instance());
|
||||
if (plugin_instance)
|
||||
plugin_instance->SetAlwaysOnTop(on_top);
|
||||
// Since no reply is sent for this message, it doesn't make sense to return an
|
||||
// error.
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
int32_t PepperFlashRendererHost::OnDrawGlyphs(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
ppapi::proxy::PPBFlash_DrawGlyphs_Params params) {
|
||||
if (params.glyph_indices.size() != params.glyph_advances.size() ||
|
||||
params.glyph_indices.empty())
|
||||
return PP_ERROR_FAILED;
|
||||
|
||||
// Set up the typeface.
|
||||
int style = SkTypeface::kNormal;
|
||||
if (static_cast<PP_BrowserFont_Trusted_Weight>(params.font_desc.weight) >=
|
||||
PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD)
|
||||
style |= SkTypeface::kBold;
|
||||
if (params.font_desc.italic)
|
||||
style |= SkTypeface::kItalic;
|
||||
skia::RefPtr<SkTypeface> typeface = skia::AdoptRef(SkTypeface::CreateFromName(
|
||||
params.font_desc.face.c_str(), static_cast<SkTypeface::Style>(style)));
|
||||
if (!typeface)
|
||||
return PP_ERROR_FAILED;
|
||||
|
||||
EnterResourceNoLock<PPB_ImageData_API> enter(
|
||||
params.image_data.host_resource(), true);
|
||||
if (enter.failed())
|
||||
return PP_ERROR_FAILED;
|
||||
|
||||
// Set up the canvas.
|
||||
PPB_ImageData_API* image = static_cast<PPB_ImageData_API*>(enter.object());
|
||||
SkCanvas* canvas = image->GetCanvas();
|
||||
bool needs_unmapping = false;
|
||||
if (!canvas) {
|
||||
needs_unmapping = true;
|
||||
image->Map();
|
||||
canvas = image->GetCanvas();
|
||||
if (!canvas)
|
||||
return PP_ERROR_FAILED; // Failure mapping.
|
||||
}
|
||||
|
||||
SkAutoCanvasRestore acr(canvas, true);
|
||||
|
||||
// Clip is applied in pixels before the transform.
|
||||
SkRect clip_rect = {
|
||||
SkIntToScalar(params.clip.point.x), SkIntToScalar(params.clip.point.y),
|
||||
SkIntToScalar(params.clip.point.x + params.clip.size.width),
|
||||
SkIntToScalar(params.clip.point.y + params.clip.size.height)};
|
||||
canvas->clipRect(clip_rect);
|
||||
|
||||
// Convert & set the matrix.
|
||||
SkMatrix matrix;
|
||||
matrix.set(SkMatrix::kMScaleX, SkFloatToScalar(params.transformation[0][0]));
|
||||
matrix.set(SkMatrix::kMSkewX, SkFloatToScalar(params.transformation[0][1]));
|
||||
matrix.set(SkMatrix::kMTransX, SkFloatToScalar(params.transformation[0][2]));
|
||||
matrix.set(SkMatrix::kMSkewY, SkFloatToScalar(params.transformation[1][0]));
|
||||
matrix.set(SkMatrix::kMScaleY, SkFloatToScalar(params.transformation[1][1]));
|
||||
matrix.set(SkMatrix::kMTransY, SkFloatToScalar(params.transformation[1][2]));
|
||||
matrix.set(SkMatrix::kMPersp0, SkFloatToScalar(params.transformation[2][0]));
|
||||
matrix.set(SkMatrix::kMPersp1, SkFloatToScalar(params.transformation[2][1]));
|
||||
matrix.set(SkMatrix::kMPersp2, SkFloatToScalar(params.transformation[2][2]));
|
||||
canvas->concat(matrix);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setColor(params.color);
|
||||
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setHinting(SkPaint::kFull_Hinting);
|
||||
paint.setTextSize(SkIntToScalar(params.font_desc.size));
|
||||
paint.setTypeface(typeface.get()); // Takes a ref and manages lifetime.
|
||||
if (params.allow_subpixel_aa) {
|
||||
paint.setSubpixelText(true);
|
||||
paint.setLCDRenderText(true);
|
||||
}
|
||||
|
||||
SkScalar x = SkIntToScalar(params.position.x);
|
||||
SkScalar y = SkIntToScalar(params.position.y);
|
||||
|
||||
// Build up the skia advances.
|
||||
size_t glyph_count = params.glyph_indices.size();
|
||||
if (glyph_count) {
|
||||
std::vector<SkPoint> storage;
|
||||
storage.resize(glyph_count);
|
||||
SkPoint* sk_positions = &storage[0];
|
||||
for (uint32_t i = 0; i < glyph_count; i++) {
|
||||
sk_positions[i].set(x, y);
|
||||
x += SkFloatToScalar(params.glyph_advances[i].x);
|
||||
y += SkFloatToScalar(params.glyph_advances[i].y);
|
||||
}
|
||||
|
||||
canvas->drawPosText(
|
||||
¶ms.glyph_indices[0], glyph_count * 2, sk_positions, paint);
|
||||
}
|
||||
|
||||
if (needs_unmapping)
|
||||
image->Unmap();
|
||||
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
// CAUTION: This code is subtle because Navigate is a sync call which may
|
||||
// cause re-entrancy or cause the instance to be destroyed. If the instance
|
||||
// is destroyed we need to ensure that we respond to all outstanding sync
|
||||
// messages so that the plugin process does not remain blocked.
|
||||
int32_t PepperFlashRendererHost::OnNavigate(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
const ppapi::URLRequestInfoData& data,
|
||||
const std::string& target,
|
||||
bool from_user_action) {
|
||||
// If our PepperPluginInstance is already destroyed, just return a failure.
|
||||
content::PepperPluginInstance* plugin_instance =
|
||||
host_->GetPluginInstance(pp_instance());
|
||||
if (!plugin_instance)
|
||||
return PP_ERROR_FAILED;
|
||||
|
||||
std::map<std::string, FlashNavigateUsage>& rejected_headers =
|
||||
g_rejected_headers.Get();
|
||||
if (rejected_headers.empty()) {
|
||||
for (size_t i = 0; i < arraysize(kRejectedHttpRequestHeaders); ++i)
|
||||
rejected_headers[kRejectedHttpRequestHeaders[i]] =
|
||||
static_cast<FlashNavigateUsage>(i);
|
||||
}
|
||||
|
||||
net::HttpUtil::HeadersIterator header_iter(
|
||||
data.headers.begin(), data.headers.end(), "\n\r");
|
||||
bool rejected = false;
|
||||
while (header_iter.GetNext()) {
|
||||
std::string lower_case_header_name =
|
||||
base::StringToLowerASCII(header_iter.name());
|
||||
if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) {
|
||||
rejected = true;
|
||||
|
||||
std::map<std::string, FlashNavigateUsage>::const_iterator iter =
|
||||
rejected_headers.find(lower_case_header_name);
|
||||
FlashNavigateUsage usage =
|
||||
iter != rejected_headers.end() ? iter->second : REJECT_OTHER_HEADERS;
|
||||
RecordFlashNavigateUsage(usage);
|
||||
}
|
||||
}
|
||||
|
||||
RecordFlashNavigateUsage(TOTAL_NAVIGATE_REQUESTS);
|
||||
if (rejected) {
|
||||
RecordFlashNavigateUsage(TOTAL_REJECTED_NAVIGATE_REQUESTS);
|
||||
return PP_ERROR_NOACCESS;
|
||||
}
|
||||
|
||||
// Navigate may call into Javascript (e.g. with a "javascript:" URL),
|
||||
// or do things like navigate away from the page, either one of which will
|
||||
// need to re-enter into the plugin. It is safe, because it is essentially
|
||||
// equivalent to NPN_GetURL, where Flash would expect re-entrancy.
|
||||
ppapi::proxy::HostDispatcher* host_dispatcher =
|
||||
ppapi::proxy::HostDispatcher::GetForInstance(pp_instance());
|
||||
host_dispatcher->set_allow_plugin_reentrancy();
|
||||
|
||||
// Grab a weak pointer to ourselves on the stack so we can check if we are
|
||||
// still alive.
|
||||
base::WeakPtr<PepperFlashRendererHost> weak_ptr = weak_factory_.GetWeakPtr();
|
||||
// Keep track of reply contexts in case we are destroyed during a Navigate
|
||||
// call. Even if we are destroyed, we still need to send these replies to
|
||||
// unblock the plugin process.
|
||||
navigate_replies_.push_back(host_context->MakeReplyMessageContext());
|
||||
plugin_instance->Navigate(data, target.c_str(), from_user_action);
|
||||
// This object might have been destroyed by this point. If it is destroyed
|
||||
// the reply will be sent in the destructor. Otherwise send the reply here.
|
||||
if (weak_ptr.get()) {
|
||||
SendReply(navigate_replies_.back(), IPC::Message());
|
||||
navigate_replies_.pop_back();
|
||||
}
|
||||
|
||||
// Return PP_OK_COMPLETIONPENDING so that no reply is automatically sent.
|
||||
return PP_OK_COMPLETIONPENDING;
|
||||
}
|
||||
|
||||
int32_t PepperFlashRendererHost::OnIsRectTopmost(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
const PP_Rect& rect) {
|
||||
content::PepperPluginInstance* plugin_instance =
|
||||
host_->GetPluginInstance(pp_instance());
|
||||
if (plugin_instance &&
|
||||
plugin_instance->IsRectTopmost(gfx::Rect(
|
||||
rect.point.x, rect.point.y, rect.size.width, rect.size.height)))
|
||||
return PP_OK;
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_RENDERER_HOST_H_
|
||||
#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_RENDERER_HOST_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "ppapi/host/host_message_context.h"
|
||||
#include "ppapi/host/resource_host.h"
|
||||
|
||||
struct PP_Rect;
|
||||
|
||||
namespace ppapi {
|
||||
struct URLRequestInfoData;
|
||||
}
|
||||
|
||||
namespace ppapi {
|
||||
namespace proxy {
|
||||
struct PPBFlash_DrawGlyphs_Params;
|
||||
}
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class RendererPpapiHost;
|
||||
}
|
||||
|
||||
class PepperFlashRendererHost : public ppapi::host::ResourceHost {
|
||||
public:
|
||||
PepperFlashRendererHost(content::RendererPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource);
|
||||
~PepperFlashRendererHost() override;
|
||||
|
||||
// ppapi::host::ResourceHost override.
|
||||
int32_t OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) override;
|
||||
|
||||
private:
|
||||
int32_t OnGetProxyForURL(ppapi::host::HostMessageContext* host_context,
|
||||
const std::string& url);
|
||||
int32_t OnSetInstanceAlwaysOnTop(
|
||||
ppapi::host::HostMessageContext* host_context,
|
||||
bool on_top);
|
||||
int32_t OnDrawGlyphs(ppapi::host::HostMessageContext* host_context,
|
||||
ppapi::proxy::PPBFlash_DrawGlyphs_Params params);
|
||||
int32_t OnNavigate(ppapi::host::HostMessageContext* host_context,
|
||||
const ppapi::URLRequestInfoData& data,
|
||||
const std::string& target,
|
||||
bool from_user_action);
|
||||
int32_t OnIsRectTopmost(ppapi::host::HostMessageContext* host_context,
|
||||
const PP_Rect& rect);
|
||||
|
||||
// A stack of ReplyMessageContexts to track Navigate() calls which have not
|
||||
// yet been replied to.
|
||||
std::vector<ppapi::host::ReplyMessageContext> navigate_replies_;
|
||||
|
||||
content::RendererPpapiHost* host_;
|
||||
base::WeakPtrFactory<PepperFlashRendererHost> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperFlashRendererHost);
|
||||
};
|
||||
|
||||
#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_RENDERER_HOST_H_
|
26
chromium_src/chrome/renderer/pepper/pepper_helper.cc
Normal file
26
chromium_src/chrome/renderer/pepper/pepper_helper.cc
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2012 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 "chrome/renderer/pepper/pepper_helper.h"
|
||||
|
||||
#include "chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h"
|
||||
#include "chrome/renderer/pepper/pepper_shared_memory_message_filter.h"
|
||||
#include "content/public/renderer/renderer_ppapi_host.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
|
||||
PepperHelper::PepperHelper(content::RenderFrame* render_frame)
|
||||
: RenderFrameObserver(render_frame) {}
|
||||
|
||||
PepperHelper::~PepperHelper() {}
|
||||
|
||||
void PepperHelper::DidCreatePepperPlugin(content::RendererPpapiHost* host) {
|
||||
// TODO(brettw) figure out how to hook up the host factory. It needs some
|
||||
// kind of filter-like system to allow dynamic additions.
|
||||
host->GetPpapiHost()->AddHostFactoryFilter(
|
||||
scoped_ptr<ppapi::host::HostFactory>(
|
||||
new ChromeRendererPepperHostFactory(host)));
|
||||
host->GetPpapiHost()->AddInstanceMessageFilter(
|
||||
scoped_ptr<ppapi::host::InstanceMessageFilter>(
|
||||
new PepperSharedMemoryMessageFilter(host)));
|
||||
}
|
25
chromium_src/chrome/renderer/pepper/pepper_helper.h
Normal file
25
chromium_src/chrome/renderer/pepper/pepper_helper.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
#ifndef CHROME_RENDERER_PEPPER_PEPPER_HELPER_H_
|
||||
#define CHROME_RENDERER_PEPPER_PEPPER_HELPER_H_
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "content/public/renderer/render_frame_observer.h"
|
||||
|
||||
// This class listens for Pepper creation events from the RenderFrame and
|
||||
// attaches the parts required for Chrome-specific plugin support.
|
||||
class PepperHelper : public content::RenderFrameObserver {
|
||||
public:
|
||||
explicit PepperHelper(content::RenderFrame* render_frame);
|
||||
~PepperHelper() override;
|
||||
|
||||
// RenderFrameObserver.
|
||||
void DidCreatePepperPlugin(content::RendererPpapiHost* host) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperHelper);
|
||||
};
|
||||
|
||||
#endif // CHROME_RENDERER_PEPPER_PEPPER_HELPER_H_
|
|
@ -0,0 +1,72 @@
|
|||
// 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 "chrome/renderer/pepper/pepper_shared_memory_message_filter.h"
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/shared_memory.h"
|
||||
#include "base/process/process_handle.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/renderer/pepper_plugin_instance.h"
|
||||
#include "content/public/renderer/render_thread.h"
|
||||
#include "content/public/renderer/renderer_ppapi_host.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
#include "ppapi/shared_impl/var_tracker.h"
|
||||
|
||||
PepperSharedMemoryMessageFilter::PepperSharedMemoryMessageFilter(
|
||||
content::RendererPpapiHost* host)
|
||||
: InstanceMessageFilter(host->GetPpapiHost()), host_(host) {}
|
||||
|
||||
PepperSharedMemoryMessageFilter::~PepperSharedMemoryMessageFilter() {}
|
||||
|
||||
bool PepperSharedMemoryMessageFilter::OnInstanceMessageReceived(
|
||||
const IPC::Message& msg) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(PepperSharedMemoryMessageFilter, msg)
|
||||
IPC_MESSAGE_HANDLER(PpapiHostMsg_SharedMemory_CreateSharedMemory,
|
||||
OnHostMsgCreateSharedMemory)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool PepperSharedMemoryMessageFilter::Send(IPC::Message* msg) {
|
||||
return host_->GetPpapiHost()->Send(msg);
|
||||
}
|
||||
|
||||
void PepperSharedMemoryMessageFilter::OnHostMsgCreateSharedMemory(
|
||||
PP_Instance instance,
|
||||
uint32_t size,
|
||||
int* host_handle_id,
|
||||
ppapi::proxy::SerializedHandle* plugin_handle) {
|
||||
plugin_handle->set_null_shmem();
|
||||
*host_handle_id = -1;
|
||||
scoped_ptr<base::SharedMemory> shm(content::RenderThread::Get()
|
||||
->HostAllocateSharedMemoryBuffer(size)
|
||||
.Pass());
|
||||
if (!shm.get())
|
||||
return;
|
||||
|
||||
base::SharedMemoryHandle host_shm_handle;
|
||||
shm->ShareToProcess(base::GetCurrentProcessHandle(), &host_shm_handle);
|
||||
*host_handle_id =
|
||||
content::PepperPluginInstance::Get(instance)
|
||||
->GetVarTracker()
|
||||
->TrackSharedMemoryHandle(instance, host_shm_handle, size);
|
||||
|
||||
base::PlatformFile host_handle =
|
||||
#if defined(OS_WIN)
|
||||
host_shm_handle;
|
||||
#elif defined(OS_POSIX)
|
||||
host_shm_handle.fd;
|
||||
#else
|
||||
#error Not implemented.
|
||||
#endif
|
||||
// We set auto_close to false since we need our file descriptor to
|
||||
// actually be duplicated on linux. The shared memory destructor will
|
||||
// close the original handle for us.
|
||||
plugin_handle->set_shmem(host_->ShareHandleWithRemote(host_handle, false),
|
||||
size);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
// 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.
|
||||
|
||||
#ifndef CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_
|
||||
#define CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "ppapi/c/pp_instance.h"
|
||||
#include "ppapi/host/instance_message_filter.h"
|
||||
|
||||
namespace content {
|
||||
class RendererPpapiHost;
|
||||
}
|
||||
|
||||
namespace ppapi {
|
||||
namespace proxy {
|
||||
class SerializedHandle;
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the backend for shared memory messages from a plugin process.
|
||||
class PepperSharedMemoryMessageFilter
|
||||
: public ppapi::host::InstanceMessageFilter {
|
||||
public:
|
||||
explicit PepperSharedMemoryMessageFilter(content::RendererPpapiHost* host);
|
||||
~PepperSharedMemoryMessageFilter() override;
|
||||
|
||||
// InstanceMessageFilter:
|
||||
bool OnInstanceMessageReceived(const IPC::Message& msg) override;
|
||||
|
||||
bool Send(IPC::Message* msg);
|
||||
|
||||
private:
|
||||
// Message handlers.
|
||||
void OnHostMsgCreateSharedMemory(
|
||||
PP_Instance instance,
|
||||
uint32_t size,
|
||||
int* host_shm_handle_id,
|
||||
ppapi::proxy::SerializedHandle* plugin_shm_handle);
|
||||
|
||||
content::RendererPpapiHost* host_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperSharedMemoryMessageFilter);
|
||||
};
|
||||
|
||||
#endif // CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_
|
144
chromium_src/chrome/utility/printing_handler.cc
Normal file
144
chromium_src/chrome/utility/printing_handler.cc
Normal file
|
@ -0,0 +1,144 @@
|
|||
// Copyright 2014 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 "chrome/utility/printing_handler.h"
|
||||
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/scoped_native_library.h"
|
||||
#include "chrome/common/print_messages.h"
|
||||
#include "content/public/utility/utility_thread.h"
|
||||
#include "pdf/pdf.h"
|
||||
#include "printing/page_range.h"
|
||||
#include "printing/pdf_render_settings.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "printing/emf_win.h"
|
||||
#include "ui/gfx/gdi_util.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
bool Send(IPC::Message* message) {
|
||||
return content::UtilityThread::Get()->Send(message);
|
||||
}
|
||||
|
||||
void ReleaseProcessIfNeeded() {
|
||||
content::UtilityThread::Get()->ReleaseProcessIfNeeded();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PrintingHandler::PrintingHandler() {}
|
||||
|
||||
PrintingHandler::~PrintingHandler() {}
|
||||
|
||||
bool PrintingHandler::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(PrintingHandler, message)
|
||||
#if defined(OS_WIN)
|
||||
IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles,
|
||||
OnRenderPDFPagesToMetafile)
|
||||
IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage,
|
||||
OnRenderPDFPagesToMetafileGetPage)
|
||||
IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop,
|
||||
OnRenderPDFPagesToMetafileStop)
|
||||
#endif // OS_WIN
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
return handled;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void PrintingHandler::OnRenderPDFPagesToMetafile(
|
||||
IPC::PlatformFileForTransit pdf_transit,
|
||||
const printing::PdfRenderSettings& settings) {
|
||||
pdf_rendering_settings_ = settings;
|
||||
base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit);
|
||||
int page_count = LoadPDF(pdf_file.Pass());
|
||||
//int page_count = 1;
|
||||
Send(
|
||||
new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount(page_count));
|
||||
}
|
||||
|
||||
void PrintingHandler::OnRenderPDFPagesToMetafileGetPage(
|
||||
int page_number,
|
||||
IPC::PlatformFileForTransit output_file) {
|
||||
base::File emf_file = IPC::PlatformFileForTransitToFile(output_file);
|
||||
float scale_factor = 1.0f;
|
||||
bool success =
|
||||
RenderPdfPageToMetafile(page_number, emf_file.Pass(), &scale_factor);
|
||||
Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone(
|
||||
success, scale_factor));
|
||||
}
|
||||
|
||||
void PrintingHandler::OnRenderPDFPagesToMetafileStop() {
|
||||
ReleaseProcessIfNeeded();
|
||||
}
|
||||
|
||||
int PrintingHandler::LoadPDF(base::File pdf_file) {
|
||||
int64 length64 = pdf_file.GetLength();
|
||||
if (length64 <= 0 || length64 > std::numeric_limits<int>::max())
|
||||
return 0;
|
||||
int length = static_cast<int>(length64);
|
||||
|
||||
pdf_data_.resize(length);
|
||||
if (length != pdf_file.Read(0, pdf_data_.data(), pdf_data_.size()))
|
||||
return 0;
|
||||
|
||||
int total_page_count = 0;
|
||||
if (!chrome_pdf::GetPDFDocInfo(
|
||||
&pdf_data_.front(), pdf_data_.size(), &total_page_count, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
return total_page_count;
|
||||
}
|
||||
|
||||
bool PrintingHandler::RenderPdfPageToMetafile(int page_number,
|
||||
base::File output_file,
|
||||
float* scale_factor) {
|
||||
printing::Emf metafile;
|
||||
metafile.Init();
|
||||
|
||||
// We need to scale down DC to fit an entire page into DC available area.
|
||||
// Current metafile is based on screen DC and have current screen size.
|
||||
// Writing outside of those boundaries will result in the cut-off output.
|
||||
// On metafiles (this is the case here), scaling down will still record
|
||||
// original coordinates and we'll be able to print in full resolution.
|
||||
// Before playback we'll need to counter the scaling up that will happen
|
||||
// in the service (print_system_win.cc).
|
||||
*scale_factor =
|
||||
gfx::CalculatePageScale(metafile.context(),
|
||||
pdf_rendering_settings_.area().right(),
|
||||
pdf_rendering_settings_.area().bottom());
|
||||
gfx::ScaleDC(metafile.context(), *scale_factor);
|
||||
|
||||
// The underlying metafile is of type Emf and ignores the arguments passed
|
||||
// to StartPage.
|
||||
metafile.StartPage(gfx::Size(), gfx::Rect(), 1);
|
||||
if (!chrome_pdf::RenderPDFPageToDC(
|
||||
&pdf_data_.front(),
|
||||
pdf_data_.size(),
|
||||
page_number,
|
||||
metafile.context(),
|
||||
pdf_rendering_settings_.dpi(),
|
||||
pdf_rendering_settings_.area().x(),
|
||||
pdf_rendering_settings_.area().y(),
|
||||
pdf_rendering_settings_.area().width(),
|
||||
pdf_rendering_settings_.area().height(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
pdf_rendering_settings_.autorotate())) {
|
||||
return false;
|
||||
}
|
||||
metafile.FinishPage();
|
||||
metafile.FinishDocument();
|
||||
return metafile.SaveTo(&output_file);
|
||||
}
|
||||
|
||||
#endif // OS_WIN
|
59
chromium_src/chrome/utility/printing_handler.h
Normal file
59
chromium_src/chrome/utility/printing_handler.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
#ifndef CHROME_UTILITY_PRINTING_HANDLER_H_
|
||||
#define CHROME_UTILITY_PRINTING_HANDLER_H_
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/macros.h"
|
||||
#include "chrome/utility/utility_message_handler.h"
|
||||
#include "ipc/ipc_platform_file.h"
|
||||
#include "printing/pdf_render_settings.h"
|
||||
|
||||
#if !defined(ENABLE_PRINT_PREVIEW) && !defined(OS_WIN)
|
||||
#error "Windows or full printing must be enabled"
|
||||
#endif
|
||||
|
||||
namespace printing {
|
||||
class PdfRenderSettings;
|
||||
struct PwgRasterSettings;
|
||||
struct PageRange;
|
||||
}
|
||||
|
||||
// Dispatches IPCs for printing.
|
||||
class PrintingHandler : public UtilityMessageHandler {
|
||||
public:
|
||||
PrintingHandler();
|
||||
~PrintingHandler() override;
|
||||
|
||||
// IPC::Listener:
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
|
||||
private:
|
||||
// IPC message handlers.
|
||||
#if defined(OS_WIN)
|
||||
void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit,
|
||||
const printing::PdfRenderSettings& settings);
|
||||
void OnRenderPDFPagesToMetafileGetPage(
|
||||
int page_number,
|
||||
IPC::PlatformFileForTransit output_file);
|
||||
void OnRenderPDFPagesToMetafileStop();
|
||||
#endif // OS_WIN
|
||||
|
||||
#if defined(OS_WIN)
|
||||
int LoadPDF(base::File pdf_file);
|
||||
bool RenderPdfPageToMetafile(int page_number,
|
||||
base::File output_file,
|
||||
float* scale_factor);
|
||||
#endif // OS_WIN
|
||||
|
||||
#if defined(OS_WIN)
|
||||
std::vector<char> pdf_data_;
|
||||
printing::PdfRenderSettings pdf_rendering_settings_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintingHandler);
|
||||
};
|
||||
|
||||
#endif // CHROME_UTILITY_PRINTING_HANDLER_H_
|
21
chromium_src/chrome/utility/utility_message_handler.h
Normal file
21
chromium_src/chrome/utility/utility_message_handler.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 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.
|
||||
|
||||
#ifndef CHROME_UTILITY_UTILITY_MESSAGE_HANDLER_H_
|
||||
#define CHROME_UTILITY_UTILITY_MESSAGE_HANDLER_H_
|
||||
|
||||
namespace IPC {
|
||||
class Message;
|
||||
}
|
||||
|
||||
class UtilityMessageHandler {
|
||||
public:
|
||||
virtual ~UtilityMessageHandler() {}
|
||||
|
||||
// Called when a message is received. Returns true iff the message was
|
||||
// handled.
|
||||
virtual bool OnMessageReceived(const IPC::Message& message) = 0;
|
||||
};
|
||||
|
||||
#endif // CHROME_UTILITY_UTILITY_MESSAGE_HANDLER_H_
|
|
@ -14,6 +14,9 @@ On Linux and Windows, the `Command` key would not have any effect, you can
|
|||
use `CommandOrControl` which represents `Command` on OS X and `Control` on
|
||||
Linux and Windows to define some accelerators.
|
||||
|
||||
The `Super` key is mapped to the `Windows` key on Windows and Linux and
|
||||
`Cmd` on OS X.
|
||||
|
||||
## Available modifiers
|
||||
|
||||
* `Command` (or `Cmd` for short)
|
||||
|
@ -21,6 +24,7 @@ Linux and Windows to define some accelerators.
|
|||
* `CommandOrControl` (or `CmdOrCtrl` for short)
|
||||
* `Alt`
|
||||
* `Shift`
|
||||
* `Super`
|
||||
|
||||
## Available key codes
|
||||
|
||||
|
|
|
@ -94,11 +94,6 @@ This method guarantees all `beforeunload` and `unload` handlers are correctly
|
|||
executed. It is possible that a window cancels the quitting by returning
|
||||
`false` in `beforeunload` handler.
|
||||
|
||||
## app.terminate()
|
||||
|
||||
Quit the application directly, it will not try to close all windows so cleanup
|
||||
code will not run.
|
||||
|
||||
## app.getPath(name)
|
||||
|
||||
* `name` String
|
||||
|
|
|
@ -72,6 +72,8 @@ You can also create a window without chrome by using
|
|||
* `type` String - Specifies the type of the window, possible types are
|
||||
`desktop`, `dock`, `toolbar`, `splash`, `notification`. This only works on
|
||||
Linux.
|
||||
* `standard-window` Boolean - Uses the OS X's standard window instead of the
|
||||
textured window. Defaults to `true`.
|
||||
* `web-preferences` Object - Settings of web page's features
|
||||
* `javascript` Boolean
|
||||
* `web-security` Boolean
|
||||
|
@ -741,10 +743,6 @@ Returns URL of current web page.
|
|||
|
||||
Returns the title of web page.
|
||||
|
||||
### WebContents.getFavicon()
|
||||
|
||||
Returns the favicon of web page as [NativeImage](native-image.md).
|
||||
|
||||
### WebContents.isLoading()
|
||||
|
||||
Returns whether web page is still loading resources.
|
||||
|
|
|
@ -62,6 +62,14 @@ Like `--host-rules` but these `rules` only apply to the host resolver.
|
|||
|
||||
Ignore certificate related errors.
|
||||
|
||||
## --ppapi-flash-path
|
||||
|
||||
Set path to pepper flash plugin for use.
|
||||
|
||||
## --ppapi-flash-version
|
||||
|
||||
Set the pepper flash version.
|
||||
|
||||
## --v=`log_level`
|
||||
|
||||
Gives the default maximal active V-logging level; 0 is the default. Normally
|
||||
|
|
|
@ -82,4 +82,25 @@ Create a request job which sends a string as response.
|
|||
* `encoding` String - Default is `UTF-8`
|
||||
* `data` Buffer
|
||||
|
||||
Create a request job which accepts a buffer and sends a string as response.
|
||||
Create a request job which sends a buffer as response.
|
||||
|
||||
## Class: protocol.RequestErrorJob(code)
|
||||
|
||||
* `code` Integer
|
||||
|
||||
Create a request job which sets appropriate network error message to console.
|
||||
Default message is `net::ERR_NOT_IMPLEMENTED`. Code should be in the following
|
||||
range.
|
||||
|
||||
* Ranges:
|
||||
* 0- 99 System related errors
|
||||
* 100-199 Connection related errors
|
||||
* 200-299 Certificate errors
|
||||
* 300-399 HTTP errors
|
||||
* 400-499 Cache errors
|
||||
* 500-599 ?
|
||||
* 600-699 FTP errors
|
||||
* 700-799 Certificate manager errors
|
||||
* 800-899 DNS resolver errors
|
||||
|
||||
Check the [network error list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h) for code and message relations.
|
||||
|
|
|
@ -49,7 +49,7 @@ Primary value types like strings and numbers, however, are sent by copy.
|
|||
|
||||
## Passing callbacks to the main process
|
||||
|
||||
Some APIs in the main process accept callbacks, and it would be attempting to
|
||||
Some APIs in the main process accept callbacks, and it would be tempting to
|
||||
pass callbacks when calling a remote function. The `remote` module does support
|
||||
doing this, but you should also be extremely careful with this.
|
||||
|
||||
|
@ -138,6 +138,10 @@ Returns the object returned by `require(module)` in the main process.
|
|||
Returns the [BrowserWindow](browser-window.md) object which this web page
|
||||
belongs to.
|
||||
|
||||
## remote.getCurrentWebContent()
|
||||
|
||||
Returns the WebContents object of this web page.
|
||||
|
||||
## remote.getGlobal(name)
|
||||
|
||||
* `name` String
|
||||
|
|
|
@ -130,10 +130,6 @@ Returns URL of guest page.
|
|||
|
||||
Returns the title of guest page.
|
||||
|
||||
### `<webview>`.getFavicon()
|
||||
|
||||
Returns the favicon of guest page as dataUrl.
|
||||
|
||||
### `<webview>`.isLoading()
|
||||
|
||||
Returns whether guest page is still loading resources.
|
||||
|
|
|
@ -281,6 +281,8 @@
|
|||
'atom/renderer/atom_renderer_client.h',
|
||||
'atom/renderer/guest_view_container.cc',
|
||||
'atom/renderer/guest_view_container.h',
|
||||
'atom/utility/atom_content_utility_client.cc',
|
||||
'atom/utility/atom_content_utility_client.h',
|
||||
'chromium_src/chrome/browser/browser_process.cc',
|
||||
'chromium_src/chrome/browser/browser_process.h',
|
||||
'chromium_src/chrome/browser/chrome_notification_types.h',
|
||||
|
@ -309,6 +311,16 @@
|
|||
'chromium_src/chrome/browser/printing/printer_query.h',
|
||||
'chromium_src/chrome/browser/printing/printing_message_filter.cc',
|
||||
'chromium_src/chrome/browser/printing/printing_message_filter.h',
|
||||
'chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc',
|
||||
'chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h',
|
||||
'chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc',
|
||||
'chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h',
|
||||
'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc',
|
||||
'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h',
|
||||
'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc',
|
||||
'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h',
|
||||
'chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc',
|
||||
'chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h',
|
||||
'chromium_src/chrome/browser/speech/tts_controller.h',
|
||||
'chromium_src/chrome/browser/speech/tts_controller_impl.cc',
|
||||
'chromium_src/chrome/browser/speech/tts_controller_impl.h',
|
||||
|
@ -325,11 +337,26 @@
|
|||
'chromium_src/chrome/browser/ui/views/color_chooser_aura.h',
|
||||
'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc',
|
||||
'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h',
|
||||
'chromium_src/chrome/common/chrome_utility_messages.h',
|
||||
'chromium_src/chrome/common/print_messages.cc',
|
||||
'chromium_src/chrome/common/print_messages.h',
|
||||
'chromium_src/chrome/common/tts_messages.h',
|
||||
'chromium_src/chrome/common/tts_utterance_request.cc',
|
||||
'chromium_src/chrome/common/tts_utterance_request.h',
|
||||
'chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc',
|
||||
'chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.cc',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_helper.cc',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_helper.h',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc',
|
||||
'chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h',
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper.cc',
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc',
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm',
|
||||
|
@ -339,6 +366,7 @@
|
|||
'chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h',
|
||||
'chromium_src/chrome/renderer/tts_dispatcher.cc',
|
||||
'chromium_src/chrome/renderer/tts_dispatcher.h',
|
||||
'chromium_src/chrome/utility/utility_message_handler.h',
|
||||
'chromium_src/library_loaders/libspeechd_loader.cc',
|
||||
'chromium_src/library_loaders/libspeechd.h',
|
||||
'<@(native_mate_files)',
|
||||
|
@ -348,6 +376,10 @@
|
|||
'chromium_src/chrome/browser/ui/views/color_chooser_dialog.cc',
|
||||
'chromium_src/chrome/browser/ui/views/color_chooser_dialog.h',
|
||||
'chromium_src/chrome/browser/ui/views/color_chooser_win.cc',
|
||||
'chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc',
|
||||
'chromium_src/chrome/browser/printing/pdf_to_emf_converter.h',
|
||||
'chromium_src/chrome/utility/printing_handler.cc',
|
||||
'chromium_src/chrome/utility/printing_handler.h',
|
||||
],
|
||||
'framework_sources': [
|
||||
'atom/app/atom_library_main.h',
|
||||
|
|
|
@ -35,12 +35,15 @@ TARGET_BINARIES = {
|
|||
'icudtl.dat',
|
||||
'libEGL.dll',
|
||||
'libGLESv2.dll',
|
||||
'msvcp120.dll',
|
||||
'msvcr120.dll',
|
||||
'node.dll',
|
||||
'content_resources_200_percent.pak',
|
||||
'ui_resources_200_percent.pak',
|
||||
'xinput1_3.dll',
|
||||
'natives_blob.bin',
|
||||
'snapshot_blob.bin',
|
||||
'vccorlib120.dll',
|
||||
],
|
||||
'linux': [
|
||||
PROJECT_NAME, # 'electron'
|
||||
|
@ -79,7 +82,8 @@ def main():
|
|||
force_build()
|
||||
create_symbols()
|
||||
copy_binaries()
|
||||
copy_chromedriver()
|
||||
copy_chrome_binary('chromedriver')
|
||||
copy_chrome_binary('mksnapshot')
|
||||
copy_license()
|
||||
|
||||
if PLATFORM == 'linux':
|
||||
|
@ -88,7 +92,8 @@ def main():
|
|||
|
||||
create_version()
|
||||
create_dist_zip()
|
||||
create_chromedriver_zip()
|
||||
create_chrome_binary_zip('chromedriver', get_chromedriver_version())
|
||||
create_chrome_binary_zip('mksnapshot', ATOM_SHELL_VERSION)
|
||||
create_symbols_zip()
|
||||
|
||||
|
||||
|
@ -107,13 +112,11 @@ def copy_binaries():
|
|||
symlinks=True)
|
||||
|
||||
|
||||
def copy_chromedriver():
|
||||
def copy_chrome_binary(binary):
|
||||
if PLATFORM == 'win32':
|
||||
chromedriver = 'chromedriver.exe'
|
||||
else:
|
||||
chromedriver = 'chromedriver'
|
||||
src = os.path.join(CHROMIUM_DIR, chromedriver)
|
||||
dest = os.path.join(DIST_DIR, chromedriver)
|
||||
binary += '.exe'
|
||||
src = os.path.join(CHROMIUM_DIR, binary)
|
||||
dest = os.path.join(DIST_DIR, binary)
|
||||
|
||||
# Copy file and keep the executable bit.
|
||||
shutil.copyfile(src, dest)
|
||||
|
@ -170,17 +173,17 @@ def create_dist_zip():
|
|||
make_zip(zip_file, files, dirs)
|
||||
|
||||
|
||||
def create_chromedriver_zip():
|
||||
dist_name = 'chromedriver-{0}-{1}-{2}.zip'.format(get_chromedriver_version(),
|
||||
PLATFORM, get_target_arch())
|
||||
def create_chrome_binary_zip(binary, version):
|
||||
dist_name = '{0}-{1}-{2}-{3}.zip'.format(binary, version, PLATFORM,
|
||||
get_target_arch())
|
||||
zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name)
|
||||
|
||||
with scoped_cwd(DIST_DIR):
|
||||
files = ['LICENSE']
|
||||
if PLATFORM == 'win32':
|
||||
files += ['chromedriver.exe']
|
||||
files += [binary + '.exe']
|
||||
else:
|
||||
files += ['chromedriver']
|
||||
files += [binary]
|
||||
make_zip(zip_file, files, [])
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import sys
|
|||
|
||||
|
||||
BASE_URL = 'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent'
|
||||
LIBCHROMIUMCONTENT_COMMIT = '07a73a610496e4a1b4f3abc3c2fb0516187ec460'
|
||||
LIBCHROMIUMCONTENT_COMMIT = '90a5b9c3792645067ad9517e60cf5eb99730e0f9'
|
||||
|
||||
PLATFORM = {
|
||||
'cygwin': 'win32',
|
||||
|
|
|
@ -4,10 +4,11 @@ import errno
|
|||
import sys
|
||||
import os
|
||||
|
||||
from lib.config import get_target_arch
|
||||
from lib.util import safe_mkdir, rm_rf, extract_zip, tempdir, download
|
||||
|
||||
|
||||
VERSION = 'v0.5.0'
|
||||
VERSION = 'v0.7.0'
|
||||
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
||||
FRAMEWORKS_URL = 'http://github.com/atom/atom-shell-frameworks/releases' \
|
||||
'/download/' + VERSION
|
||||
|
@ -28,7 +29,8 @@ def main():
|
|||
download_and_unzip('ReactiveCocoa')
|
||||
download_and_unzip('Squirrel')
|
||||
elif sys.platform in ['cygwin', 'win32']:
|
||||
download_and_unzip('directxsdk')
|
||||
download_and_unzip('directxsdk-' + get_target_arch())
|
||||
download_and_unzip('vs2012-crt-' + get_target_arch())
|
||||
|
||||
with open(version_file, 'w') as f:
|
||||
f.write(VERSION)
|
||||
|
|
|
@ -34,6 +34,9 @@ SYMBOLS_NAME = '{0}-{1}-{2}-{3}-symbols.zip'.format(PROJECT_NAME,
|
|||
CHROMEDRIVER_NAME = 'chromedriver-{0}-{1}-{2}.zip'.format(CHROMEDRIVER_VERSION,
|
||||
PLATFORM,
|
||||
get_target_arch())
|
||||
MKSNAPSHOT_NAME = 'mksnapshot-{0}-{1}-{2}.zip'.format(ATOM_SHELL_VERSION,
|
||||
PLATFORM,
|
||||
get_target_arch())
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -74,10 +77,12 @@ def main():
|
|||
upload_atom_shell(github, release_id, os.path.join(DIST_DIR, DIST_NAME))
|
||||
upload_atom_shell(github, release_id, os.path.join(DIST_DIR, SYMBOLS_NAME))
|
||||
|
||||
# Upload chromedriver for minor version update.
|
||||
# Upload chromedriver and mksnapshot for minor version update.
|
||||
if parse_version(args.version)[2] == '0':
|
||||
upload_atom_shell(github, release_id,
|
||||
os.path.join(DIST_DIR, CHROMEDRIVER_NAME))
|
||||
upload_atom_shell(github, release_id,
|
||||
os.path.join(DIST_DIR, MKSNAPSHOT_NAME))
|
||||
|
||||
if PLATFORM == 'win32':
|
||||
# Upload PDBs to Windows symbol server.
|
||||
|
|
|
@ -4,6 +4,7 @@ path = require 'path'
|
|||
remote = require 'remote'
|
||||
http = require 'http'
|
||||
url = require 'url'
|
||||
auth = require 'basic-auth'
|
||||
|
||||
BrowserWindow = remote.require 'browser-window'
|
||||
|
||||
|
@ -245,3 +246,26 @@ describe 'browser-window module', ->
|
|||
w.webContents.on 'did-finish-load', ->
|
||||
w.close()
|
||||
w.loadUrl "file://#{fixtures}/pages/f.html"
|
||||
|
||||
describe 'basic auth', ->
|
||||
it 'should authenticate with correct credentials', (done) ->
|
||||
ipc = remote.require 'ipc'
|
||||
server = http.createServer (req, res) ->
|
||||
action = url.parse(req.url, true).pathname
|
||||
if action == '/'
|
||||
credentials = auth(req)
|
||||
if credentials.name == 'test' and credentials.pass == 'test'
|
||||
res.end('Authenticated')
|
||||
server.close()
|
||||
else if action == '/jquery.js'
|
||||
js = fs.readFileSync(path.join(__dirname, 'static', 'jquery-2.0.3.min.js'))
|
||||
res.writeHead(200, {'Content-Type': 'text/javascript'})
|
||||
res.end(js, 'utf-8')
|
||||
server.listen 62342, '127.0.0.1'
|
||||
ipc.on 'console-message', (e, message) ->
|
||||
ipc.removeAllListeners 'console-message'
|
||||
assert.equal message, 'Authenticated'
|
||||
done()
|
||||
w.webContents.on 'did-finish-load', ->
|
||||
w.close()
|
||||
w.loadUrl "file://#{fixtures}/pages/basic-auth.html"
|
||||
|
|
|
@ -58,6 +58,21 @@ describe 'protocol module', ->
|
|||
assert false, 'Got error: ' + errorType + ' ' + error
|
||||
protocol.unregisterProtocol 'atom-string-job'
|
||||
|
||||
it 'returns RequestErrorJob should send error', (done) ->
|
||||
data = 'valar morghulis'
|
||||
job = new protocol.RequestErrorJob(-6)
|
||||
handler = remote.createFunctionWithReturnValue job
|
||||
protocol.registerProtocol 'atom-error-job', handler
|
||||
|
||||
$.ajax
|
||||
url: 'atom-error-job://fake-host'
|
||||
success: (response) ->
|
||||
assert false, 'should not reach here'
|
||||
error: (xhr, errorType, error) ->
|
||||
assert errorType, 'error'
|
||||
protocol.unregisterProtocol 'atom-error-job'
|
||||
done()
|
||||
|
||||
it 'returns RequestBufferJob should send buffer', (done) ->
|
||||
data = new Buffer("hello")
|
||||
job = new protocol.RequestBufferJob(data: data)
|
||||
|
|
17
spec/fixtures/pages/basic-auth.html
vendored
Normal file
17
spec/fixtures/pages/basic-auth.html
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
<html>
|
||||
<body>
|
||||
<script src='http://127.0.0.1:62342/jquery.js'></script>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "http://127.0.0.1:62342",
|
||||
headers: {
|
||||
"Authorization": "Basic " + btoa("test:test")
|
||||
},
|
||||
success: function (result){
|
||||
require('ipc').send('console-message', result);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -4,6 +4,7 @@
|
|||
"main": "static/main.js",
|
||||
"version": "0.1.0",
|
||||
"devDependencies": {
|
||||
"basic-auth": "^1.0.0",
|
||||
"formidable": "1.0.16",
|
||||
"graceful-fs": "3.0.5",
|
||||
"mocha": "2.1.0",
|
||||
|
|
2
vendor/brightray
vendored
2
vendor/brightray
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 32ba91f830a12f6f37017797b9b65d55037ad29d
|
||||
Subproject commit a929d75829270def615e342c79ea17634e8c5989
|
Loading…
Add table
Reference in a new issue