ppapi flash plugin support

This commit is contained in:
deepak1556 2015-04-28 21:15:58 +05:30
parent be06a3d562
commit 3fdc4543b8
35 changed files with 2520 additions and 0 deletions

View file

@ -0,0 +1,94 @@
// 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));
}
#if 0
case PpapiHostMsg_FlashDRM_Create::ID:
return scoped_ptr<ResourceHost>(
new PepperFlashDRMHost(host_, instance, resource));
#endif
}
}
// 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_