Merge remote-tracking branch 'atom/master'

This commit is contained in:
joshaber 2015-05-12 20:48:15 -04:00
commit 1c97fc79ad
90 changed files with 3937 additions and 112 deletions

View file

@ -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

View file

@ -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',
],
},
{

View file

@ -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

View file

@ -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);

View file

@ -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();
}

View file

@ -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);
};

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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;

View file

@ -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

View file

@ -30,4 +30,8 @@ protocol.RequestFileJob =
class RequestFileJob
constructor: (@path) ->
protocol.RequestErrorJob =
class RequestErrorJob
constructor: (@error) ->
module.exports = protocol

View file

@ -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

View file

@ -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.

View file

@ -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(

View file

@ -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

View file

@ -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;
}

View file

@ -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"

View file

@ -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>

View file

@ -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

View file

@ -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";

View file

@ -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);

View file

@ -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);
}

View file

@ -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

View file

@ -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_;

View file

@ -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;

View file

@ -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_; }

View file

@ -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

View file

@ -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

View file

@ -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";

View file

@ -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[];

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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

View 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

View 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_

View file

@ -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(),

View file

@ -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);

View 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

View 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_

View file

@ -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.

View file

@ -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_;

View file

@ -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
}

View file

@ -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

View file

@ -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_

View file

@ -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

View file

@ -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_

View file

@ -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

View file

@ -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_

View file

@ -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

View file

@ -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_

View file

@ -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

View file

@ -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_

View 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)

View file

@ -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

View file

@ -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>();
}

View file

@ -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_

View file

@ -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;
}

View file

@ -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_

View file

@ -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;
}

View file

@ -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_

View 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));
}

View 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_

View file

@ -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(
&params.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;
}

View 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_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_

View 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)));
}

View 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_

View file

@ -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);
}

View file

@ -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_

View 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

View 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_

View 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_

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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',

View file

@ -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, [])

View file

@ -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',

View file

@ -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)

View file

@ -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.

View file

@ -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"

View file

@ -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
View 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>

View file

@ -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

@ -1 +1 @@
Subproject commit 32ba91f830a12f6f37017797b9b65d55037ad29d
Subproject commit a929d75829270def615e342c79ea17634e8c5989