summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-10-19 14:37:37 +0100
committerIain Merrick <husky@google.com>2010-10-19 14:37:37 +0100
commit3345a6884c488ff3a535c2c9acdd33d74b37e311 (patch)
tree7784b988ef1698cb6967ea1bdf07616237716c6c /webkit/glue/plugins
parentefc8475837ec58186051f23bb03542620424f6ce (diff)
downloadexternal_chromium-3345a6884c488ff3a535c2c9acdd33d74b37e311.zip
external_chromium-3345a6884c488ff3a535c2c9acdd33d74b37e311.tar.gz
external_chromium-3345a6884c488ff3a535c2c9acdd33d74b37e311.tar.bz2
Merge Chromium at 7.0.540.0 : Initial merge by git
Not including third_party/icu as it contains huge data files that break Gerrit, and aren't actually used. Change-Id: I428a386e70f3b58cacd28677b8cfda282e891e15
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r--webkit/glue/plugins/gtk_plugin_container_manager.cc16
-rw-r--r--webkit/glue/plugins/pepper_buffer.cc10
-rw-r--r--webkit/glue/plugins/pepper_buffer.h5
-rw-r--r--webkit/glue/plugins/pepper_device_context_2d.cc553
-rw-r--r--webkit/glue/plugins/pepper_device_context_2d.h175
-rw-r--r--webkit/glue/plugins/pepper_directory_reader.cc9
-rw-r--r--webkit/glue/plugins/pepper_directory_reader.h9
-rw-r--r--webkit/glue/plugins/pepper_event_conversion.cc293
-rw-r--r--webkit/glue/plugins/pepper_event_conversion.h18
-rw-r--r--webkit/glue/plugins/pepper_file_chooser.cc85
-rw-r--r--webkit/glue/plugins/pepper_file_chooser.h20
-rw-r--r--webkit/glue/plugins/pepper_file_io.cc258
-rw-r--r--webkit/glue/plugins/pepper_file_io.h40
-rw-r--r--webkit/glue/plugins/pepper_file_ref.cc42
-rw-r--r--webkit/glue/plugins/pepper_file_ref.h20
-rw-r--r--webkit/glue/plugins/pepper_file_system.cc222
-rw-r--r--webkit/glue/plugins/pepper_file_system.h9
-rw-r--r--webkit/glue/plugins/pepper_font.cc296
-rw-r--r--webkit/glue/plugins/pepper_font.h28
-rw-r--r--webkit/glue/plugins/pepper_image_data.cc25
-rw-r--r--webkit/glue/plugins/pepper_image_data.h11
-rw-r--r--webkit/glue/plugins/pepper_plugin_delegate.h154
-rw-r--r--webkit/glue/plugins/pepper_plugin_instance.cc303
-rw-r--r--webkit/glue/plugins/pepper_plugin_instance.h88
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.cc215
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.h37
-rw-r--r--webkit/glue/plugins/pepper_private.cc157
-rw-r--r--webkit/glue/plugins/pepper_private.h2
-rw-r--r--webkit/glue/plugins/pepper_resource.cc14
-rw-r--r--webkit/glue/plugins/pepper_resource.h43
-rw-r--r--webkit/glue/plugins/pepper_resource_tracker.cc21
-rw-r--r--webkit/glue/plugins/pepper_resource_tracker.h15
-rw-r--r--webkit/glue/plugins/pepper_scrollbar.cc34
-rw-r--r--webkit/glue/plugins/pepper_scrollbar.h10
-rw-r--r--webkit/glue/plugins/pepper_url_loader.cc95
-rw-r--r--webkit/glue/plugins/pepper_url_loader.h21
-rw-r--r--webkit/glue/plugins/pepper_url_request_info.cc46
-rw-r--r--webkit/glue/plugins/pepper_url_request_info.h9
-rw-r--r--webkit/glue/plugins/pepper_url_response_info.cc17
-rw-r--r--webkit/glue/plugins/pepper_url_response_info.h6
-rw-r--r--webkit/glue/plugins/pepper_var.cc984
-rw-r--r--webkit/glue/plugins/pepper_var.h245
-rw-r--r--webkit/glue/plugins/pepper_webplugin_impl.cc18
-rw-r--r--webkit/glue/plugins/pepper_widget.cc19
-rw-r--r--webkit/glue/plugins/pepper_widget.h8
-rw-r--r--webkit/glue/plugins/plugin_host.cc3
-rw-r--r--webkit/glue/plugins/plugin_instance.cc16
-rw-r--r--webkit/glue/plugins/plugin_instance.h1
-rw-r--r--webkit/glue/plugins/plugin_lib.cc20
-rw-r--r--webkit/glue/plugins/plugin_lib.h2
-rw-r--r--webkit/glue/plugins/plugin_lib_mac.mm3
-rw-r--r--webkit/glue/plugins/plugin_lib_posix.cc13
-rw-r--r--webkit/glue/plugins/plugin_lib_unittest.cc1
-rw-r--r--webkit/glue/plugins/plugin_lib_win.cc13
-rw-r--r--webkit/glue/plugins/plugin_list.cc22
-rw-r--r--webkit/glue/plugins/plugin_list_mac.mm8
-rw-r--r--webkit/glue/plugins/plugin_list_posix.cc26
-rw-r--r--webkit/glue/plugins/plugin_list_win.cc20
-rw-r--r--webkit/glue/plugins/plugin_stream.h15
-rw-r--r--webkit/glue/plugins/ppb_private.h94
-rw-r--r--webkit/glue/plugins/test/npapi_test.cc50
-rw-r--r--webkit/glue/plugins/test/plugin_arguments_test.cc5
-rw-r--r--webkit/glue/plugins/test/plugin_geturl_test.cc6
-rw-r--r--webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc23
-rw-r--r--webkit/glue/plugins/test/plugin_npobject_lifetime_test.h3
-rw-r--r--webkit/glue/plugins/test/plugin_schedule_timer_test.h4
-rw-r--r--webkit/glue/plugins/test/plugin_test.h13
-rw-r--r--webkit/glue/plugins/test/plugin_test_factory.cc6
-rw-r--r--webkit/glue/plugins/test/plugin_thread_async_call_test.cc1
-rw-r--r--webkit/glue/plugins/test/plugin_thread_async_call_test.h15
-rw-r--r--webkit/glue/plugins/test/plugin_windowed_test.cc8
-rw-r--r--webkit/glue/plugins/test/plugin_windowless_test.cc7
-rw-r--r--webkit/glue/plugins/webplugin.cc3
-rw-r--r--webkit/glue/plugins/webplugin.h1
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.cc36
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h63
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_gtk.cc117
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_mac.mm73
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_win.cc21
-rw-r--r--webkit/glue/plugins/webplugin_impl.cc11
-rw-r--r--webkit/glue/plugins/webplugin_impl.h3
-rw-r--r--webkit/glue/plugins/webview_plugin.cc52
-rw-r--r--webkit/glue/plugins/webview_plugin.h27
83 files changed, 3376 insertions, 2134 deletions
diff --git a/webkit/glue/plugins/gtk_plugin_container_manager.cc b/webkit/glue/plugins/gtk_plugin_container_manager.cc
index 9d9ee4b..f26b44c 100644
--- a/webkit/glue/plugins/gtk_plugin_container_manager.cc
+++ b/webkit/glue/plugins/gtk_plugin_container_manager.cc
@@ -65,17 +65,21 @@ void GtkPluginContainerManager::MovePluginContainer(
return;
}
- DCHECK(GTK_WIDGET_REALIZED(widget));
gtk_widget_show(widget);
if (!move.rects_valid)
return;
- GdkRectangle clip_rect = move.clip_rect.ToGdkRectangle();
- GdkRegion* clip_region = gdk_region_rectangle(&clip_rect);
- gfx::SubtractRectanglesFromRegion(clip_region, move.cutout_rects);
- gdk_window_shape_combine_region(widget->window, clip_region, 0, 0);
- gdk_region_destroy(clip_region);
+ // TODO(piman): if the widget hasn't been realized (e.g. the tab has been
+ // torn off and the parent gtk widget has been detached from the hierarchy),
+ // we lose the cutout information.
+ if (GTK_WIDGET_REALIZED(widget)) {
+ GdkRectangle clip_rect = move.clip_rect.ToGdkRectangle();
+ GdkRegion* clip_region = gdk_region_rectangle(&clip_rect);
+ gfx::SubtractRectanglesFromRegion(clip_region, move.cutout_rects);
+ gdk_window_shape_combine_region(widget->window, clip_region, 0, 0);
+ gdk_region_destroy(clip_region);
+ }
// Update the window position. Resizing is handled by WebPluginDelegate.
// TODO(deanm): Verify that we only need to move and not resize.
diff --git a/webkit/glue/plugins/pepper_buffer.cc b/webkit/glue/plugins/pepper_buffer.cc
index 1c0bdd8..c3acef8 100644
--- a/webkit/glue/plugins/pepper_buffer.cc
+++ b/webkit/glue/plugins/pepper_buffer.cc
@@ -8,10 +8,10 @@
#include "base/logging.h"
#include "base/scoped_ptr.h"
+#include "third_party/ppapi/c/dev/ppb_buffer_dev.h"
#include "third_party/ppapi/c/pp_instance.h"
#include "third_party/ppapi/c/pp_module.h"
#include "third_party/ppapi/c/pp_resource.h"
-#include "third_party/ppapi/c/ppb_buffer.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
@@ -22,11 +22,11 @@ namespace {
PP_Resource Create(PP_Module module_id, int32_t size) {
PluginModule* module = PluginModule::FromPPModule(module_id);
if (!module)
- return NULL;
+ return 0;
scoped_refptr<Buffer> buffer(new Buffer(module));
if (!buffer->Init(size))
- return NULL;
+ return 0;
return buffer->GetReference();
}
@@ -57,7 +57,7 @@ void Unmap(PP_Resource resource) {
return buffer->Unmap();
}
-const PPB_Buffer ppb_buffer = {
+const PPB_Buffer_Dev ppb_buffer = {
&Create,
&IsBuffer,
&Describe,
@@ -76,7 +76,7 @@ Buffer::~Buffer() {
}
// static
-const PPB_Buffer* Buffer::GetInterface() {
+const PPB_Buffer_Dev* Buffer::GetInterface() {
return &ppb_buffer;
}
diff --git a/webkit/glue/plugins/pepper_buffer.h b/webkit/glue/plugins/pepper_buffer.h
index 5d750ec..2f20e55 100644
--- a/webkit/glue/plugins/pepper_buffer.h
+++ b/webkit/glue/plugins/pepper_buffer.h
@@ -7,9 +7,10 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
-#include "third_party/ppapi/c/ppb_buffer.h"
#include "webkit/glue/plugins/pepper_resource.h"
+struct PPB_Buffer_Dev;
+
namespace pepper {
class PluginInstance;
@@ -28,7 +29,7 @@ class Buffer : public Resource {
// Returns a pointer to the interface implementing PPB_Buffer that is
// exposed to the plugin.
- static const PPB_Buffer* GetInterface();
+ static const PPB_Buffer_Dev* GetInterface();
// Resource overrides.
Buffer* AsBuffer() { return this; }
diff --git a/webkit/glue/plugins/pepper_device_context_2d.cc b/webkit/glue/plugins/pepper_device_context_2d.cc
deleted file mode 100644
index 45ed9ee..0000000
--- a/webkit/glue/plugins/pepper_device_context_2d.cc
+++ /dev/null
@@ -1,553 +0,0 @@
-// Copyright (c) 2010 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 "webkit/glue/plugins/pepper_device_context_2d.h"
-
-#include <iterator>
-
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/task.h"
-#include "gfx/blit.h"
-#include "gfx/point.h"
-#include "gfx/rect.h"
-#include "skia/ext/platform_canvas.h"
-#include "third_party/ppapi/c/pp_errors.h"
-#include "third_party/ppapi/c/pp_module.h"
-#include "third_party/ppapi/c/pp_rect.h"
-#include "third_party/ppapi/c/pp_resource.h"
-#include "third_party/ppapi/c/ppb_device_context_2d.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "webkit/glue/plugins/pepper_image_data.h"
-#include "webkit/glue/plugins/pepper_plugin_instance.h"
-#include "webkit/glue/plugins/pepper_plugin_module.h"
-
-#if defined(OS_MACOSX)
-#include "base/mac_util.h"
-#include "base/scoped_cftyperef.h"
-#endif
-
-namespace pepper {
-
-namespace {
-
-// Converts a rect inside an image of the given dimensions. The rect may be
-// NULL to indicate it should be the entire image. If the rect is outside of
-// the image, this will do nothing and return false.
-bool ValidateAndConvertRect(const PP_Rect* rect,
- int image_width, int image_height,
- gfx::Rect* dest) {
- if (!rect) {
- // Use the entire image area.
- *dest = gfx::Rect(0, 0, image_width, image_height);
- } else {
- // Validate the passed-in area.
- if (rect->point.x < 0 || rect->point.y < 0 ||
- rect->size.width <= 0 || rect->size.height <= 0)
- return false;
-
- // Check the max bounds, being careful of overflow.
- if (static_cast<int64>(rect->point.x) +
- static_cast<int64>(rect->size.width) >
- static_cast<int64>(image_width))
- return false;
- if (static_cast<int64>(rect->point.y) +
- static_cast<int64>(rect->size.height) >
- static_cast<int64>(image_height))
- return false;
-
- *dest = gfx::Rect(rect->point.x, rect->point.y,
- rect->size.width, rect->size.height);
- }
- return true;
-}
-
-PP_Resource Create(PP_Module module_id,
- const PP_Size* size,
- bool is_always_opaque) {
- PluginModule* module = PluginModule::FromPPModule(module_id);
- if (!module)
- return NULL;
-
- scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module));
- if (!context->Init(size->width, size->height, is_always_opaque))
- return NULL;
- return context->GetReference();
-}
-
-bool IsDeviceContext2D(PP_Resource resource) {
- return !!Resource::GetAs<DeviceContext2D>(resource);
-}
-
-bool Describe(PP_Resource device_context,
- PP_Size* size,
- bool* is_always_opaque) {
- scoped_refptr<DeviceContext2D> context(
- Resource::GetAs<DeviceContext2D>(device_context));
- if (!context)
- return false;
- return context->Describe(size, is_always_opaque);
-}
-
-bool PaintImageData(PP_Resource device_context,
- PP_Resource image,
- const PP_Point* top_left,
- const PP_Rect* src_rect) {
- scoped_refptr<DeviceContext2D> context(
- Resource::GetAs<DeviceContext2D>(device_context));
- if (!context)
- return false;
- return context->PaintImageData(image, top_left, src_rect);
-}
-
-bool Scroll(PP_Resource device_context,
- const PP_Rect* clip_rect,
- const PP_Point* amount) {
- scoped_refptr<DeviceContext2D> context(
- Resource::GetAs<DeviceContext2D>(device_context));
- if (!context)
- return false;
- return context->Scroll(clip_rect, amount);
-}
-
-bool ReplaceContents(PP_Resource device_context, PP_Resource image) {
- scoped_refptr<DeviceContext2D> context(
- Resource::GetAs<DeviceContext2D>(device_context));
- if (!context)
- return false;
- return context->ReplaceContents(image);
-}
-
-int32_t Flush(PP_Resource device_context,
- PP_CompletionCallback callback) {
- scoped_refptr<DeviceContext2D> context(
- Resource::GetAs<DeviceContext2D>(device_context));
- if (!context)
- return PP_ERROR_BADRESOURCE;
- return context->Flush(callback);
-}
-
-const PPB_DeviceContext2D ppb_devicecontext2d = {
- &Create,
- &IsDeviceContext2D,
- &Describe,
- &PaintImageData,
- &Scroll,
- &ReplaceContents,
- &Flush
-};
-
-} // namespace
-
-struct DeviceContext2D::QueuedOperation {
- enum Type {
- PAINT,
- SCROLL,
- REPLACE
- };
-
- QueuedOperation(Type t)
- : type(t),
- paint_x(0),
- paint_y(0),
- scroll_dx(0),
- scroll_dy(0) {
- }
-
- Type type;
-
- // Valid when type == PAINT.
- scoped_refptr<ImageData> paint_image;
- int paint_x, paint_y;
- gfx::Rect paint_src_rect;
-
- // Valid when type == SCROLL.
- gfx::Rect scroll_clip_rect;
- int scroll_dx, scroll_dy;
-
- // Valid when type == REPLACE.
- scoped_refptr<ImageData> replace_image;
-};
-
-DeviceContext2D::DeviceContext2D(PluginModule* module)
- : Resource(module),
- bound_instance_(NULL),
- flushed_any_data_(false),
- offscreen_flush_pending_(false) {
-}
-
-DeviceContext2D::~DeviceContext2D() {
-}
-
-// static
-const PPB_DeviceContext2D* DeviceContext2D::GetInterface() {
- return &ppb_devicecontext2d;
-}
-
-bool DeviceContext2D::Init(int width, int height, bool is_always_opaque) {
- // The underlying ImageData will validate the dimensions.
- image_data_ = new ImageData(module());
- if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height, true) ||
- !image_data_->Map()) {
- image_data_ = NULL;
- return false;
- }
-
- return true;
-}
-
-bool DeviceContext2D::Describe(PP_Size* size, bool* is_always_opaque) {
- size->width = image_data_->width();
- size->height = image_data_->height();
- *is_always_opaque = false; // TODO(brettw) implement this.
- return true;
-}
-
-bool DeviceContext2D::PaintImageData(PP_Resource image,
- const PP_Point* top_left,
- const PP_Rect* src_rect) {
- if (!top_left)
- return false;
-
- scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image));
- if (!image_resource)
- return false;
-
- QueuedOperation operation(QueuedOperation::PAINT);
- operation.paint_image = image_resource;
- if (!ValidateAndConvertRect(src_rect, image_resource->width(),
- image_resource->height(),
- &operation.paint_src_rect))
- return false;
-
- // Validate the bitmap position using the previously-validated rect, there
- // should be no painted area outside of the image.
- int64 x64 = static_cast<int64>(top_left->x);
- int64 y64 = static_cast<int64>(top_left->y);
- if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 ||
- x64 + static_cast<int64>(operation.paint_src_rect.right()) >
- image_data_->width())
- return false;
- if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 ||
- y64 + static_cast<int64>(operation.paint_src_rect.bottom()) >
- image_data_->height())
- return false;
- operation.paint_x = top_left->x;
- operation.paint_y = top_left->y;
-
- queued_operations_.push_back(operation);
- return true;
-}
-
-bool DeviceContext2D::Scroll(const PP_Rect* clip_rect,
- const PP_Point* amount) {
- QueuedOperation operation(QueuedOperation::SCROLL);
- if (!ValidateAndConvertRect(clip_rect,
- image_data_->width(),
- image_data_->height(),
- &operation.scroll_clip_rect))
- return false;
-
- // If we're being asked to scroll by more than the clip rect size, just
- // ignore this scroll command and say it worked.
- int32 dx = amount->x;
- int32 dy = amount->y;
- if (dx <= -image_data_->width() || dx >= image_data_->width() ||
- dx <= -image_data_->height() || dy >= image_data_->height())
- return true;
-
- operation.scroll_dx = dx;
- operation.scroll_dy = dy;
-
- queued_operations_.push_back(operation);
- return false;
-}
-
-bool DeviceContext2D::ReplaceContents(PP_Resource image) {
- scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image));
- if (!image_resource)
- return false;
- if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL)
- return false;
-
- if (image_resource->width() != image_data_->width() ||
- image_resource->height() != image_data_->height())
- return false;
-
- QueuedOperation operation(QueuedOperation::REPLACE);
- operation.replace_image = image_resource;
- queued_operations_.push_back(operation);
-
- return true;
-}
-
-int32_t DeviceContext2D::Flush(const PP_CompletionCallback& callback) {
- // Don't allow more than one pending flush at a time.
- if (HasPendingFlush())
- return PP_ERROR_INPROGRESS;
-
- // TODO(brettw) check that the current thread is not the main one and
- // implement blocking flushes in this case.
- if (!callback.func)
- return PP_ERROR_BADARGUMENT;
-
- gfx::Rect changed_rect;
- for (size_t i = 0; i < queued_operations_.size(); i++) {
- QueuedOperation& operation = queued_operations_[i];
- gfx::Rect op_rect;
- switch (operation.type) {
- case QueuedOperation::PAINT:
- ExecutePaintImageData(operation.paint_image,
- operation.paint_x, operation.paint_y,
- operation.paint_src_rect,
- &op_rect);
- break;
- case QueuedOperation::SCROLL:
- ExecuteScroll(operation.scroll_clip_rect,
- operation.scroll_dx, operation.scroll_dy,
- &op_rect);
- break;
- case QueuedOperation::REPLACE:
- ExecuteReplaceContents(operation.replace_image, &op_rect);
- break;
- }
- changed_rect = changed_rect.Union(op_rect);
- }
- queued_operations_.clear();
- flushed_any_data_ = true;
-
- // We need the rect to be in terms of the current clip rect of the plugin
- // since that's what will actually be painted. If we issue an invalidate
- // for a clipped-out region, WebKit will do nothing and we won't get any
- // ViewInitiatedPaint/ViewFlushedPaint calls, leaving our callback stranded.
- gfx::Rect visible_changed_rect;
- if (bound_instance_ && !changed_rect.IsEmpty())
- visible_changed_rect = bound_instance_->clip().Intersect(changed_rect);
-
- if (bound_instance_ && !visible_changed_rect.IsEmpty()) {
- unpainted_flush_callback_.Set(callback);
- bound_instance_->InvalidateRect(visible_changed_rect);
- } else {
- // There's nothing visible to invalidate so just schedule the callback to
- // execute in the next round of the message loop.
- ScheduleOffscreenCallback(FlushCallbackData(callback));
- }
- return PP_ERROR_WOULDBLOCK;
-}
-
-bool DeviceContext2D::ReadImageData(PP_Resource image,
- const PP_Point* top_left) {
- // Get and validate the image object to paint into.
- scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image));
- if (!image_resource)
- return false;
- if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL)
- return false; // Must be in the right format.
-
- // Validate the bitmap position.
- int x = top_left->x;
- if (x < 0 ||
- static_cast<int64>(x) + static_cast<int64>(image_resource->width()) >
- image_data_->width())
- return false;
- int y = top_left->y;
- if (y < 0 ||
- static_cast<int64>(y) + static_cast<int64>(image_resource->height()) >
- image_data_->height())
- return false;
-
- ImageDataAutoMapper auto_mapper(image_resource);
- if (!auto_mapper.is_valid())
- return false;
- skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas();
-
- SkIRect src_irect = { x, y,
- x + image_resource->width(),
- y + image_resource->height() };
- SkRect dest_rect = { SkIntToScalar(0),
- SkIntToScalar(0),
- SkIntToScalar(image_resource->width()),
- SkIntToScalar(image_resource->height()) };
-
- // We want to replace the contents of the bitmap rather than blend.
- SkPaint paint;
- paint.setXfermodeMode(SkXfermode::kSrc_Mode);
- dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(),
- &src_irect, dest_rect, &paint);
- return true;
-}
-
-bool DeviceContext2D::BindToInstance(PluginInstance* new_instance) {
- if (bound_instance_ == new_instance)
- return true; // Rebinding the same device, nothing to do.
- if (bound_instance_ && new_instance)
- return false; // Can't change a bound device.
-
- if (!new_instance) {
- // When the device is detached, we'll not get any more paint callbacks so
- // we need to clear the list, but we still want to issue any pending
- // callbacks to the plugin.
- if (!unpainted_flush_callback_.is_null()) {
- ScheduleOffscreenCallback(unpainted_flush_callback_);
- unpainted_flush_callback_.Clear();
- }
- if (!painted_flush_callback_.is_null()) {
- ScheduleOffscreenCallback(painted_flush_callback_);
- painted_flush_callback_.Clear();
- }
- } else if (flushed_any_data_) {
- // Only schedule a paint if this backing store has had any data flushed to
- // it. This is an optimization. A "normal" plugin will first allocated a
- // backing store, bind it, and then execute their normal painting and
- // update loop. If binding a device always invalidated, it would mean we
- // would get one paint for the bind, and one for the first time the plugin
- // actually painted something. By not bothering to schedule an invalidate
- // when an empty device is initially bound, we can save an extra paint for
- // many plugins during the critical page initialization phase.
- new_instance->InvalidateRect(gfx::Rect());
- }
-
- bound_instance_ = new_instance;
- return true;
-}
-
-void DeviceContext2D::Paint(WebKit::WebCanvas* canvas,
- const gfx::Rect& plugin_rect,
- const gfx::Rect& paint_rect) {
- // We're guaranteed to have a mapped canvas since we mapped it in Init().
- const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap();
-
-#if defined(OS_MACOSX)
- SkAutoLockPixels lock(backing_bitmap);
-
- scoped_cftyperef<CGDataProviderRef> data_provider(
- CGDataProviderCreateWithData(
- NULL, backing_bitmap.getAddr32(0, 0),
- backing_bitmap.rowBytes() * backing_bitmap.height(), NULL));
- scoped_cftyperef<CGImageRef> image(
- CGImageCreate(
- backing_bitmap.width(), backing_bitmap.height(),
- 8, 32, backing_bitmap.rowBytes(),
- mac_util::GetSystemColorSpace(),
- kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
- data_provider, NULL, false, kCGRenderingIntentDefault));
-
- // Flip the transform
- CGContextSaveGState(canvas);
- float window_height = static_cast<float>(CGBitmapContextGetHeight(canvas));
- CGContextTranslateCTM(canvas, 0, window_height);
- CGContextScaleCTM(canvas, 1.0, -1.0);
-
- CGRect bounds;
- bounds.origin.x = plugin_rect.origin().x();
- bounds.origin.y = window_height - plugin_rect.origin().y() -
- backing_bitmap.height();
- bounds.size.width = backing_bitmap.width();
- bounds.size.height = backing_bitmap.height();
-
- CGContextDrawImage(canvas, bounds, image);
- CGContextRestoreGState(canvas);
-#else
- gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y());
- canvas->drawBitmap(backing_bitmap,
- SkIntToScalar(plugin_rect.origin().x()),
- SkIntToScalar(plugin_rect.origin().y()));
-#endif
-}
-
-void DeviceContext2D::ViewInitiatedPaint() {
- // Move any "unpainted" callback to the painted state. See
- // |unpainted_flush_callback_| in the header for more.
- if (!unpainted_flush_callback_.is_null()) {
- DCHECK(painted_flush_callback_.is_null());
- std::swap(painted_flush_callback_, unpainted_flush_callback_);
- }
-}
-
-void DeviceContext2D::ViewFlushedPaint() {
- // Notify any "painted" callback. See |unpainted_flush_callback_| in the
- // header for more.
- if (!painted_flush_callback_.is_null()) {
- // We must clear this variable before issuing the callback. It will be
- // common for the plugin to issue another invalidate in response to a flush
- // callback, and we don't want to think that a callback is already pending.
- FlushCallbackData callback;
- std::swap(callback, painted_flush_callback_);
- callback.Execute(PP_OK);
- }
-}
-
-void DeviceContext2D::ExecutePaintImageData(ImageData* image,
- int x, int y,
- const gfx::Rect& src_rect,
- gfx::Rect* invalidated_rect) {
- // Ensure the source image is mapped to read from it.
- ImageDataAutoMapper auto_mapper(image);
- if (!auto_mapper.is_valid())
- return;
-
- // Portion within the source image to cut out.
- SkIRect src_irect = { src_rect.x(), src_rect.y(),
- src_rect.right(), src_rect.bottom() };
-
- // Location within the backing store to copy to.
- *invalidated_rect = src_rect;
- invalidated_rect->Offset(x, y);
- SkRect dest_rect = { SkIntToScalar(invalidated_rect->x()),
- SkIntToScalar(invalidated_rect->y()),
- SkIntToScalar(invalidated_rect->right()),
- SkIntToScalar(invalidated_rect->bottom()) };
-
- // We're guaranteed to have a mapped canvas since we mapped it in Init().
- skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas();
-
- // We want to replace the contents of the bitmap rather than blend.
- SkPaint paint;
- paint.setXfermodeMode(SkXfermode::kSrc_Mode);
- backing_canvas->drawBitmapRect(*image->GetMappedBitmap(),
- &src_irect, dest_rect, &paint);
-}
-
-void DeviceContext2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy,
- gfx::Rect* invalidated_rect) {
- gfx::ScrollCanvas(image_data_->mapped_canvas(),
- clip, gfx::Point(dx, dy));
- *invalidated_rect = clip;
-}
-
-void DeviceContext2D::ExecuteReplaceContents(ImageData* image,
- gfx::Rect* invalidated_rect) {
- image_data_->Swap(image);
- *invalidated_rect = gfx::Rect(0, 0,
- image_data_->width(), image_data_->height());
-}
-
-void DeviceContext2D::ScheduleOffscreenCallback(
- const FlushCallbackData& callback) {
- DCHECK(!HasPendingFlush());
- offscreen_flush_pending_ = true;
- MessageLoop::current()->PostTask(
- FROM_HERE,
- NewRunnableMethod(this,
- &DeviceContext2D::ExecuteOffscreenCallback,
- callback));
-}
-
-void DeviceContext2D::ExecuteOffscreenCallback(FlushCallbackData data) {
- DCHECK(offscreen_flush_pending_);
-
- // We must clear this flag before issuing the callback. It will be
- // common for the plugin to issue another invalidate in response to a flush
- // callback, and we don't want to think that a callback is already pending.
- offscreen_flush_pending_ = false;
- data.Execute(PP_OK);
-}
-
-bool DeviceContext2D::HasPendingFlush() const {
- return !unpainted_flush_callback_.is_null() ||
- !painted_flush_callback_.is_null() ||
- offscreen_flush_pending_;
-}
-
-} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_device_context_2d.h b/webkit/glue/plugins/pepper_device_context_2d.h
deleted file mode 100644
index 603bd52..0000000
--- a/webkit/glue/plugins/pepper_device_context_2d.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright (c) 2010 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 WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_2D_H_
-#define WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_2D_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "third_party/ppapi/c/pp_completion_callback.h"
-#include "third_party/ppapi/c/ppb_device_context_2d.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebCanvas.h"
-#include "webkit/glue/plugins/pepper_resource.h"
-
-typedef struct _ppb_DeviceContext2D PPB_DeviceContext2D;
-
-namespace gfx {
-class Rect;
-}
-
-namespace pepper {
-
-class ImageData;
-class PluginInstance;
-class PluginModule;
-
-class DeviceContext2D : public Resource {
- public:
- DeviceContext2D(PluginModule* module);
- virtual ~DeviceContext2D();
-
- // Returns a pointer to the interface implementing PPB_ImageData that is
- // exposed to the plugin.
- static const PPB_DeviceContext2D* GetInterface();
-
- bool Init(int width, int height, bool is_always_opaque);
-
- // Resource override.
- virtual DeviceContext2D* AsDeviceContext2D() { return this; }
-
- // PPB_DeviceContext2D functions.
- bool Describe(PP_Size* size, bool* is_always_opaque);
- bool PaintImageData(PP_Resource image,
- const PP_Point* top_left,
- const PP_Rect* src_rect);
- bool Scroll(const PP_Rect* clip_rect, const PP_Point* amount);
- bool ReplaceContents(PP_Resource image);
- int32_t Flush(const PP_CompletionCallback& callback);
-
- bool ReadImageData(PP_Resource image, const PP_Point* top_left);
-
- // Assciates this device with the given plugin instance. You can pass NULL to
- // clear the existing device. Returns true on success. In this case, a
- // repaint of the page will also be scheduled. Failure means that the device
- // is already bound to a different instance, and nothing will happen.
- bool BindToInstance(PluginInstance* new_instance);
-
- // Paints the current backing store to the web page.
- void Paint(WebKit::WebCanvas* canvas,
- const gfx::Rect& plugin_rect,
- const gfx::Rect& paint_rect);
-
- // Notifications that the view has rendered the page and that it has been
- // flushed to the screen. These messages are used to send Flush callbacks to
- // the plugin. See
- void ViewInitiatedPaint();
- void ViewFlushedPaint();
-
- ImageData* image_data() { return image_data_.get(); }
-
- private:
- // Tracks a call to flush that requires a callback.
- class FlushCallbackData {
- public:
- FlushCallbackData() {
- Clear();
- }
-
- FlushCallbackData(const PP_CompletionCallback& callback) {
- Set(callback);
- }
-
- bool is_null() const { return !callback_.func; }
-
- void Set(const PP_CompletionCallback& callback) {
- callback_ = callback;
- }
-
- void Clear() {
- callback_ = PP_MakeCompletionCallback(NULL, 0);
- }
-
- void Execute(int32_t result) {
- PP_RunCompletionCallback(&callback_, result);
- }
-
- private:
- PP_CompletionCallback callback_;
- };
-
- // Called internally to execute the different queued commands. The
- // parameters to these functions will have already been validated. The last
- // rect argument will be filled by each function with the area affected by
- // the update that requires invalidation. If there were no pixels changed,
- // this rect can be untouched.
- void ExecutePaintImageData(ImageData* image,
- int x, int y,
- const gfx::Rect& src_rect,
- gfx::Rect* invalidated_rect);
- void ExecuteScroll(const gfx::Rect& clip, int dx, int dy,
- gfx::Rect* invalidated_rect);
- void ExecuteReplaceContents(ImageData* image,
- gfx::Rect* invalidated_rect);
-
- // Schedules the offscreen callback to be fired at a future time. This
- // will add the given item to the offscreen_flush_callbacks_ vector.
- void ScheduleOffscreenCallback(const FlushCallbackData& callback);
-
- // Function scheduled to execute by ScheduleOffscreenCallback that actually
- // issues the offscreen callbacks.
- void ExecuteOffscreenCallback(FlushCallbackData data);
-
- // Returns true if there is any type of flush callback pending.
- bool HasPendingFlush() const;
-
- scoped_refptr<ImageData> image_data_;
-
- // Non-owning pointer to the plugin instance this device context is currently
- // bound to, if any. If the device context is currently unbound, this will
- // be NULL.
- PluginInstance* bound_instance_;
-
- // Keeps track of all drawing commands queued before a Flush call.
- struct QueuedOperation;
- typedef std::vector<QueuedOperation> OperationQueue;
- OperationQueue queued_operations_;
-
- // Indicates whether any changes have been flushed to the backing store.
- // This is initially false and is set to true at the first Flush() call.
- bool flushed_any_data_;
-
- // The plugin can give us one "Flush" at a time. This flush will either be in
- // the "unpainted" state (in which case unpainted_flush_callback_ will be
- // non-NULL) or painted, in which case painted_flush_callback_ will be
- // non-NULL). There can also be an offscreen callback which is handled
- // separately (see offscreen_callback_pending_). Only one of these three
- // things may be set at a time to enforce the "only one pending flush at a
- // time" constraint.
- //
- // "Unpainted" ones are flush requests which have never been painted. These
- // could have been done while the RenderView was already waiting for an ACK
- // from a previous paint, so won't generate a new one yet.
- //
- // "Painted" ones are those flushes that have been painted by RenderView, but
- // for which the ACK from the browser has not yet been received.
- //
- // When we get updates from a plugin with a callback, it is first added to
- // the unpainted callbacks. When the renderer has initiated a paint, we'll
- // move it to the painted callbacks list. When the renderer receives a flush,
- // we'll execute the callback and remove it from the list.
- FlushCallbackData unpainted_flush_callback_;
- FlushCallbackData painted_flush_callback_;
-
- // When doing offscreen flushes, we issue a task that issues the callback
- // later. This is set when one of those tasks is pending so that we can
- // enforce the "only one pending flush at a time" constraint in the API.
- bool offscreen_flush_pending_;
-
- DISALLOW_COPY_AND_ASSIGN(DeviceContext2D);
-};
-
-} // namespace pepper
-
-#endif // WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_2D_H_
diff --git a/webkit/glue/plugins/pepper_directory_reader.cc b/webkit/glue/plugins/pepper_directory_reader.cc
index 93f19ee..bcf2533 100644
--- a/webkit/glue/plugins/pepper_directory_reader.cc
+++ b/webkit/glue/plugins/pepper_directory_reader.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "third_party/ppapi/c/pp_completion_callback.h"
+#include "third_party/ppapi/c/dev/ppb_directory_reader_dev.h"
#include "third_party/ppapi/c/pp_errors.h"
#include "webkit/glue/plugins/pepper_file_ref.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"
@@ -29,7 +30,7 @@ bool IsDirectoryReader(PP_Resource resource) {
}
int32_t GetNextEntry(PP_Resource reader_id,
- PP_DirectoryEntry* entry,
+ PP_DirectoryEntry_Dev* entry,
PP_CompletionCallback callback) {
scoped_refptr<DirectoryReader> reader(
Resource::GetAs<DirectoryReader>(reader_id));
@@ -39,7 +40,7 @@ int32_t GetNextEntry(PP_Resource reader_id,
return reader->GetNextEntry(entry, callback);
}
-const PPB_DirectoryReader ppb_directoryreader = {
+const PPB_DirectoryReader_Dev ppb_directoryreader = {
&Create,
&IsDirectoryReader,
&GetNextEntry
@@ -55,11 +56,11 @@ DirectoryReader::DirectoryReader(FileRef* directory_ref)
DirectoryReader::~DirectoryReader() {
}
-const PPB_DirectoryReader* DirectoryReader::GetInterface() {
+const PPB_DirectoryReader_Dev* DirectoryReader::GetInterface() {
return &ppb_directoryreader;
}
-int32_t DirectoryReader::GetNextEntry(PP_DirectoryEntry* entry,
+int32_t DirectoryReader::GetNextEntry(PP_DirectoryEntry_Dev* entry,
PP_CompletionCallback callback) {
NOTIMPLEMENTED(); // TODO(darin): Implement me!
return PP_ERROR_FAILED;
diff --git a/webkit/glue/plugins/pepper_directory_reader.h b/webkit/glue/plugins/pepper_directory_reader.h
index c477a3e..a56d546 100644
--- a/webkit/glue/plugins/pepper_directory_reader.h
+++ b/webkit/glue/plugins/pepper_directory_reader.h
@@ -5,9 +5,12 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_DIRECTORY_READER_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_DIRECTORY_READER_H_
-#include "third_party/ppapi/c/ppb_directory_reader.h"
#include "webkit/glue/plugins/pepper_resource.h"
+struct PP_CompletionCallback;
+struct PP_DirectoryEntry_Dev;
+struct PPB_DirectoryReader_Dev;
+
namespace pepper {
class FileRef;
@@ -19,13 +22,13 @@ class DirectoryReader : public Resource {
// Returns a pointer to the interface implementing PPB_DirectoryReader that
// is exposed to the plugin.
- static const PPB_DirectoryReader* GetInterface();
+ static const PPB_DirectoryReader_Dev* GetInterface();
// Resource overrides.
DirectoryReader* AsDirectoryReader() { return this; }
// PPB_DirectoryReader implementation.
- int32_t GetNextEntry(PP_DirectoryEntry* entry,
+ int32_t GetNextEntry(PP_DirectoryEntry_Dev* entry,
PP_CompletionCallback callback);
private:
diff --git a/webkit/glue/plugins/pepper_event_conversion.cc b/webkit/glue/plugins/pepper_event_conversion.cc
index 033ac93..b88041e 100644
--- a/webkit/glue/plugins/pepper_event_conversion.cc
+++ b/webkit/glue/plugins/pepper_event_conversion.cc
@@ -4,9 +4,13 @@
#include "webkit/glue/plugins/pepper_event_conversion.h"
+#include "base/i18n/char_iterator.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
-#include "third_party/ppapi/c/pp_event.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "base/utf_string_conversion_utils.h"
+#include "third_party/ppapi/c/pp_input_event.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
using WebKit::WebInputEvent;
@@ -15,153 +19,216 @@ using WebKit::WebMouseEvent;
using WebKit::WebMouseWheelEvent;
namespace {
-// Anonymous namespace for functions converting WebInputEvent to PP_Event and
-// back.
-PP_Event_Type ConvertEventTypes(WebInputEvent::Type wetype) {
+
+PP_InputEvent_Type ConvertEventTypes(WebInputEvent::Type wetype) {
switch (wetype) {
case WebInputEvent::MouseDown:
- return PP_EVENT_TYPE_MOUSEDOWN;
+ return PP_INPUTEVENT_TYPE_MOUSEDOWN;
case WebInputEvent::MouseUp:
- return PP_EVENT_TYPE_MOUSEUP;
+ return PP_INPUTEVENT_TYPE_MOUSEUP;
case WebInputEvent::MouseMove:
- return PP_EVENT_TYPE_MOUSEMOVE;
+ return PP_INPUTEVENT_TYPE_MOUSEMOVE;
case WebInputEvent::MouseEnter:
- return PP_EVENT_TYPE_MOUSEENTER;
+ return PP_INPUTEVENT_TYPE_MOUSEENTER;
case WebInputEvent::MouseLeave:
- return PP_EVENT_TYPE_MOUSELEAVE;
+ return PP_INPUTEVENT_TYPE_MOUSELEAVE;
case WebInputEvent::MouseWheel:
- return PP_EVENT_TYPE_MOUSEWHEEL;
+ return PP_INPUTEVENT_TYPE_MOUSEWHEEL;
case WebInputEvent::RawKeyDown:
- return PP_EVENT_TYPE_RAWKEYDOWN;
+ return PP_INPUTEVENT_TYPE_RAWKEYDOWN;
case WebInputEvent::KeyDown:
- return PP_EVENT_TYPE_KEYDOWN;
+ return PP_INPUTEVENT_TYPE_KEYDOWN;
case WebInputEvent::KeyUp:
- return PP_EVENT_TYPE_KEYUP;
+ return PP_INPUTEVENT_TYPE_KEYUP;
case WebInputEvent::Char:
- return PP_EVENT_TYPE_CHAR;
+ return PP_INPUTEVENT_TYPE_CHAR;
case WebInputEvent::Undefined:
default:
- return PP_EVENT_TYPE_UNDEFINED;
+ return PP_INPUTEVENT_TYPE_UNDEFINED;
}
}
-void BuildKeyEvent(const WebInputEvent* event, PP_Event* pp_event) {
- const WebKeyboardEvent* key_event =
- reinterpret_cast<const WebKeyboardEvent*>(event);
- pp_event->u.key.modifier = key_event->modifiers;
- pp_event->u.key.normalizedKeyCode = key_event->windowsKeyCode;
+// Generates a PP_InputEvent with the fields common to all events, as well as
+// the event type from the given web event. Event-specific fields will be zero
+// initialized.
+PP_InputEvent GetPPEventWithCommonFieldsAndType(
+ const WebInputEvent& web_event) {
+ PP_InputEvent result;
+ memset(&result, 0, sizeof(PP_InputEvent));
+ result.type = ConvertEventTypes(web_event.type);
+ result.time_stamp_seconds = web_event.timeStampSeconds;
+ return result;
+}
+
+void AppendKeyEvent(const WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events) {
+ const WebKeyboardEvent& key_event =
+ reinterpret_cast<const WebKeyboardEvent&>(event);
+ PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event);
+ result.u.key.modifier = key_event.modifiers;
+ result.u.key.key_code = key_event.windowsKeyCode;
+ pp_events->push_back(result);
}
-void BuildCharEvent(const WebInputEvent* event, PP_Event* pp_event) {
- const WebKeyboardEvent* key_event =
- reinterpret_cast<const WebKeyboardEvent*>(event);
- pp_event->u.character.modifier = key_event->modifiers;
- // For consistency, check that the sizes of the texts agree.
- DCHECK(sizeof(pp_event->u.character.text) == sizeof(key_event->text));
- DCHECK(sizeof(pp_event->u.character.unmodifiedText) ==
- sizeof(key_event->unmodifiedText));
- for (size_t i = 0; i < WebKeyboardEvent::textLengthCap; ++i) {
- pp_event->u.character.text[i] = key_event->text[i];
- pp_event->u.character.unmodifiedText[i] = key_event->unmodifiedText[i];
+void AppendCharEvent(const WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events) {
+ const WebKeyboardEvent& key_event =
+ reinterpret_cast<const WebKeyboardEvent&>(event);
+
+ // This is a bit complex, the input event will normally just have one 16-bit
+ // character in it, but may be zero or more than one. The text array is
+ // just padded with 0 values for the unused ones, but is not necessarily
+ // null-terminated.
+ //
+ // Here we see how many UTF-16 characters we have.
+ size_t utf16_char_count = 0;
+ while (utf16_char_count < WebKeyboardEvent::textLengthCap &&
+ key_event.text[utf16_char_count])
+ utf16_char_count++;
+
+ // Make a separate PP_InputEvent for each Unicode character in the input.
+ base::UTF16CharIterator iter(key_event.text, utf16_char_count);
+ while (!iter.end()) {
+ PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event);
+ result.u.character.modifier = key_event.modifiers;
+
+ std::string utf8_char;
+ base::WriteUnicodeCharacter(iter.get(), &utf8_char);
+ base::strlcpy(result.u.character.text, utf8_char.c_str(),
+ sizeof(result.u.character.text));
+
+ pp_events->push_back(result);
+ iter.Advance();
}
}
-void BuildMouseEvent(const WebInputEvent* event, PP_Event* pp_event) {
- const WebMouseEvent* mouse_event =
- reinterpret_cast<const WebMouseEvent*>(event);
- pp_event->u.mouse.modifier = mouse_event->modifiers;
- pp_event->u.mouse.button = mouse_event->button;
- pp_event->u.mouse.x = mouse_event->x;
- pp_event->u.mouse.y = mouse_event->y;
- pp_event->u.mouse.clickCount = mouse_event->clickCount;
+void AppendMouseEvent(const WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events) {
+ COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonNone) ==
+ static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE),
+ MouseNone);
+ COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonLeft) ==
+ static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_LEFT),
+ MouseLeft);
+ COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonRight) ==
+ static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_RIGHT),
+ MouseRight);
+ COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonMiddle) ==
+ static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_MIDDLE),
+ MouseMiddle);
+
+ const WebMouseEvent& mouse_event =
+ reinterpret_cast<const WebMouseEvent&>(event);
+ PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event);
+ result.u.mouse.modifier = mouse_event.modifiers;
+ result.u.mouse.button =
+ static_cast<PP_InputEvent_MouseButton>(mouse_event.button);
+ result.u.mouse.x = static_cast<float>(mouse_event.x);
+ result.u.mouse.y = static_cast<float>(mouse_event.y);
+ result.u.mouse.click_count = mouse_event.clickCount;
+ pp_events->push_back(result);
}
-void BuildMouseWheelEvent(const WebInputEvent* event, PP_Event* pp_event) {
- const WebMouseWheelEvent* mouse_wheel_event =
- reinterpret_cast<const WebMouseWheelEvent*>(event);
- pp_event->u.wheel.modifier = mouse_wheel_event->modifiers;
- pp_event->u.wheel.deltaX = mouse_wheel_event->deltaX;
- pp_event->u.wheel.deltaY = mouse_wheel_event->deltaY;
- pp_event->u.wheel.wheelTicksX = mouse_wheel_event->wheelTicksX;
- pp_event->u.wheel.wheelTicksY = mouse_wheel_event->wheelTicksY;
- pp_event->u.wheel.scrollByPage = mouse_wheel_event->scrollByPage;
+void AppendMouseWheelEvent(const WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events) {
+ const WebMouseWheelEvent& mouse_wheel_event =
+ reinterpret_cast<const WebMouseWheelEvent&>(event);
+ PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event);
+ result.u.wheel.modifier = mouse_wheel_event.modifiers;
+ result.u.wheel.delta_x = mouse_wheel_event.deltaX;
+ result.u.wheel.delta_y = mouse_wheel_event.deltaY;
+ result.u.wheel.wheel_ticks_x = mouse_wheel_event.wheelTicksX;
+ result.u.wheel.wheel_ticks_y = mouse_wheel_event.wheelTicksY;
+ result.u.wheel.scroll_by_page = !!mouse_wheel_event.scrollByPage;
+ pp_events->push_back(result);
}
-WebKeyboardEvent* BuildKeyEvent(const PP_Event& event) {
+WebKeyboardEvent* BuildKeyEvent(const PP_InputEvent& event) {
WebKeyboardEvent* key_event = new WebKeyboardEvent();
switch (event.type) {
- case PP_EVENT_TYPE_RAWKEYDOWN:
+ case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
key_event->type = WebInputEvent::RawKeyDown;
break;
- case PP_EVENT_TYPE_KEYDOWN:
+ case PP_INPUTEVENT_TYPE_KEYDOWN:
key_event->type = WebInputEvent::KeyDown;
break;
- case PP_EVENT_TYPE_KEYUP:
+ case PP_INPUTEVENT_TYPE_KEYUP:
key_event->type = WebInputEvent::KeyUp;
break;
+ default:
+ NOTREACHED();
}
key_event->timeStampSeconds = event.time_stamp_seconds;
key_event->modifiers = event.u.key.modifier;
- key_event->windowsKeyCode = event.u.key.normalizedKeyCode;
+ key_event->windowsKeyCode = event.u.key.key_code;
return key_event;
}
-WebKeyboardEvent* BuildCharEvent(const PP_Event& event) {
+WebKeyboardEvent* BuildCharEvent(const PP_InputEvent& event) {
WebKeyboardEvent* key_event = new WebKeyboardEvent();
key_event->type = WebInputEvent::Char;
key_event->timeStampSeconds = event.time_stamp_seconds;
key_event->modifiers = event.u.character.modifier;
- // For consistency, check that the sizes of the texts agree.
- DCHECK(sizeof(event.u.character.text) == sizeof(key_event->text));
- DCHECK(sizeof(event.u.character.unmodifiedText) ==
- sizeof(key_event->unmodifiedText));
- for (size_t i = 0; i < WebKeyboardEvent::textLengthCap; ++i) {
- key_event->text[i] = event.u.character.text[i];
- key_event->unmodifiedText[i] = event.u.character.unmodifiedText[i];
- }
+
+ // Make sure to not read beyond the buffer in case some bad code doesn't
+ // NULL-terminate it (this is called from plugins).
+ size_t text_length_cap = WebKeyboardEvent::textLengthCap;
+ size_t text_len = 0;
+ while (text_len < text_length_cap && event.u.character.text[text_len])
+ text_len++;
+ string16 text16 = UTF8ToUTF16(std::string(event.u.character.text, text_len));
+
+ memset(key_event->text, 0, text_length_cap);
+ memset(key_event->unmodifiedText, 0, text_length_cap);
+ for (size_t i = 0;
+ i < std::min(text_length_cap, text16.size());
+ ++i)
+ key_event->text[i] = text16[i];
return key_event;
}
-WebMouseEvent* BuildMouseEvent(const PP_Event& event) {
+WebMouseEvent* BuildMouseEvent(const PP_InputEvent& event) {
WebMouseEvent* mouse_event = new WebMouseEvent();
switch (event.type) {
- case PP_EVENT_TYPE_MOUSEDOWN:
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
mouse_event->type = WebInputEvent::MouseDown;
break;
- case PP_EVENT_TYPE_MOUSEUP:
+ case PP_INPUTEVENT_TYPE_MOUSEUP:
mouse_event->type = WebInputEvent::MouseUp;
break;
- case PP_EVENT_TYPE_MOUSEMOVE:
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
mouse_event->type = WebInputEvent::MouseMove;
break;
- case PP_EVENT_TYPE_MOUSEENTER:
+ case PP_INPUTEVENT_TYPE_MOUSEENTER:
mouse_event->type = WebInputEvent::MouseEnter;
break;
- case PP_EVENT_TYPE_MOUSELEAVE:
+ case PP_INPUTEVENT_TYPE_MOUSELEAVE:
mouse_event->type = WebInputEvent::MouseLeave;
break;
+ default:
+ NOTREACHED();
}
mouse_event->timeStampSeconds = event.time_stamp_seconds;
mouse_event->modifiers = event.u.mouse.modifier;
mouse_event->button =
static_cast<WebMouseEvent::Button>(event.u.mouse.button);
- mouse_event->x = event.u.mouse.x;
- mouse_event->y = event.u.mouse.y;
- mouse_event->clickCount = event.u.mouse.clickCount;
+ mouse_event->x = static_cast<int>(event.u.mouse.x);
+ mouse_event->y = static_cast<int>(event.u.mouse.y);
+ mouse_event->clickCount = event.u.mouse.click_count;
return mouse_event;
}
-WebMouseWheelEvent* BuildMouseWheelEvent(const PP_Event& event) {
+WebMouseWheelEvent* BuildMouseWheelEvent(const PP_InputEvent& event) {
WebMouseWheelEvent* mouse_wheel_event = new WebMouseWheelEvent();
mouse_wheel_event->type = WebInputEvent::MouseWheel;
mouse_wheel_event->timeStampSeconds = event.time_stamp_seconds;
mouse_wheel_event->modifiers = event.u.wheel.modifier;
- mouse_wheel_event->deltaX = event.u.wheel.deltaX;
- mouse_wheel_event->deltaY = event.u.wheel.deltaY;
- mouse_wheel_event->wheelTicksX = event.u.wheel.wheelTicksX;
- mouse_wheel_event->wheelTicksY = event.u.wheel.wheelTicksY;
- mouse_wheel_event->scrollByPage = event.u.wheel.scrollByPage;
+ mouse_wheel_event->deltaX = event.u.wheel.delta_x;
+ mouse_wheel_event->deltaY = event.u.wheel.delta_y;
+ mouse_wheel_event->wheelTicksX = event.u.wheel.wheel_ticks_x;
+ mouse_wheel_event->wheelTicksY = event.u.wheel.wheel_ticks_y;
+ mouse_wheel_event->scrollByPage = event.u.wheel.scroll_by_page;
return mouse_wheel_event;
}
@@ -169,64 +236,58 @@ WebMouseWheelEvent* BuildMouseWheelEvent(const PP_Event& event) {
namespace pepper {
-PP_Event* CreatePP_Event(const WebInputEvent& event) {
- scoped_ptr<PP_Event> pp_event(new PP_Event);
+void CreatePPEvent(const WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events) {
+ pp_events->clear();
- pp_event->type = ConvertEventTypes(event.type);
- pp_event->size = sizeof(pp_event);
- pp_event->time_stamp_seconds = event.timeStampSeconds;
- switch (pp_event->type) {
- case PP_EVENT_TYPE_UNDEFINED:
- return NULL;
- case PP_EVENT_TYPE_MOUSEDOWN:
- case PP_EVENT_TYPE_MOUSEUP:
- case PP_EVENT_TYPE_MOUSEMOVE:
- case PP_EVENT_TYPE_MOUSEENTER:
- case PP_EVENT_TYPE_MOUSELEAVE:
- BuildMouseEvent(&event, pp_event.get());
+ switch (event.type) {
+ case WebInputEvent::MouseDown:
+ case WebInputEvent::MouseUp:
+ case WebInputEvent::MouseMove:
+ case WebInputEvent::MouseEnter:
+ case WebInputEvent::MouseLeave:
+ AppendMouseEvent(event, pp_events);
break;
- case PP_EVENT_TYPE_MOUSEWHEEL:
- BuildMouseWheelEvent(&event, pp_event.get());
+ case WebInputEvent::MouseWheel:
+ AppendMouseWheelEvent(event, pp_events);
break;
- case PP_EVENT_TYPE_RAWKEYDOWN:
- case PP_EVENT_TYPE_KEYDOWN:
- case PP_EVENT_TYPE_KEYUP:
- BuildKeyEvent(&event, pp_event.get());
+ case WebInputEvent::RawKeyDown:
+ case WebInputEvent::KeyDown:
+ case WebInputEvent::KeyUp:
+ AppendKeyEvent(event, pp_events);
break;
- case PP_EVENT_TYPE_CHAR:
- BuildCharEvent(&event, pp_event.get());
+ case WebInputEvent::Char:
+ AppendCharEvent(event, pp_events);
+ break;
+ case WebInputEvent::Undefined:
+ default:
break;
}
-
- return pp_event.release();
}
-WebInputEvent* CreateWebInputEvent(const PP_Event& event) {
+WebInputEvent* CreateWebInputEvent(const PP_InputEvent& event) {
scoped_ptr<WebInputEvent> web_input_event;
switch (event.type) {
- case PP_EVENT_TYPE_UNDEFINED:
+ case PP_INPUTEVENT_TYPE_UNDEFINED:
return NULL;
- case PP_EVENT_TYPE_MOUSEDOWN:
- case PP_EVENT_TYPE_MOUSEUP:
- case PP_EVENT_TYPE_MOUSEMOVE:
- case PP_EVENT_TYPE_MOUSEENTER:
- case PP_EVENT_TYPE_MOUSELEAVE:
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ case PP_INPUTEVENT_TYPE_MOUSEUP:
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ case PP_INPUTEVENT_TYPE_MOUSEENTER:
+ case PP_INPUTEVENT_TYPE_MOUSELEAVE:
web_input_event.reset(BuildMouseEvent(event));
break;
- case PP_EVENT_TYPE_MOUSEWHEEL:
+ case PP_INPUTEVENT_TYPE_MOUSEWHEEL:
web_input_event.reset(BuildMouseWheelEvent(event));
break;
- case PP_EVENT_TYPE_RAWKEYDOWN:
- case PP_EVENT_TYPE_KEYDOWN:
- case PP_EVENT_TYPE_KEYUP:
+ case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
+ case PP_INPUTEVENT_TYPE_KEYDOWN:
+ case PP_INPUTEVENT_TYPE_KEYUP:
web_input_event.reset(BuildKeyEvent(event));
break;
- case PP_EVENT_TYPE_CHAR:
+ case PP_INPUTEVENT_TYPE_CHAR:
web_input_event.reset(BuildCharEvent(event));
break;
- case PP_EVENT_TYPE_FOCUS:
- // NOTIMPLEMENTED();
- return NULL;
}
return web_input_event.release();
diff --git a/webkit/glue/plugins/pepper_event_conversion.h b/webkit/glue/plugins/pepper_event_conversion.h
index 2d699cd..9eab3e4 100644
--- a/webkit/glue/plugins/pepper_event_conversion.h
+++ b/webkit/glue/plugins/pepper_event_conversion.h
@@ -5,7 +5,9 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_EVENT_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_EVENT_H_
-typedef struct _pp_Event PP_Event;
+#include <vector>
+
+struct PP_InputEvent;
namespace WebKit {
class WebInputEvent;
@@ -13,13 +15,15 @@ class WebInputEvent;
namespace pepper {
-// Creates a PP_Event from the given WebInputEvent. If it fails, returns NULL.
-// The caller owns the created object on success.
-PP_Event* CreatePP_Event(const WebKit::WebInputEvent& event);
+// Converts the given WebKit event to one or possibly multiple PP_InputEvents.
+// The generated events will be filled into the given vector. On failure, no
+// events will ge generated and the vector will be empty.
+void CreatePPEvent(const WebKit::WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events);
-// Creates a WebInputEvent from the given PP_Event. If it fails, returns NULL.
-// The caller owns the created object on success.
-WebKit::WebInputEvent* CreateWebInputEvent(const PP_Event& event);
+// Creates a WebInputEvent from the given PP_InputEvent. If it fails, returns
+// NULL. The caller owns the created object on success.
+WebKit::WebInputEvent* CreateWebInputEvent(const PP_InputEvent& event);
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_file_chooser.cc b/webkit/glue/plugins/pepper_file_chooser.cc
index 5e45600..138efd7 100644
--- a/webkit/glue/plugins/pepper_file_chooser.cc
+++ b/webkit/glue/plugins/pepper_file_chooser.cc
@@ -4,19 +4,35 @@
#include "webkit/glue/plugins/pepper_file_chooser.h"
+#include <string>
+#include <vector>
+
#include "base/logging.h"
#include "third_party/ppapi/c/pp_completion_callback.h"
#include "third_party/ppapi/c/pp_errors.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebCString.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFileChooserCompletion.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFileChooserParams.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
#include "webkit/glue/plugins/pepper_file_ref.h"
+#include "webkit/glue/plugins/pepper_plugin_delegate.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"
+#include "webkit/glue/webkit_glue.h"
+
+using WebKit::WebCString;
+using WebKit::WebFileChooserCompletion;
+using WebKit::WebFileChooserParams;
+using WebKit::WebString;
+using WebKit::WebVector;
namespace pepper {
namespace {
PP_Resource Create(PP_Instance instance_id,
- const PP_FileChooserOptions* options) {
+ const PP_FileChooserOptions_Dev* options) {
PluginInstance* instance = PluginInstance::FromPPInstance(instance_id);
if (!instance)
return 0;
@@ -51,38 +67,89 @@ PP_Resource GetNextChosenFile(PP_Resource chooser_id) {
return file_ref->GetReference();
}
-const PPB_FileChooser ppb_filechooser = {
+const PPB_FileChooser_Dev ppb_filechooser = {
&Create,
&IsFileChooser,
&Show,
&GetNextChosenFile
};
+class FileChooserCompletionImpl : public WebFileChooserCompletion {
+ public:
+ FileChooserCompletionImpl(pepper::FileChooser* file_chooser)
+ : file_chooser_(file_chooser) {
+ DCHECK(file_chooser_);
+ }
+
+ virtual ~FileChooserCompletionImpl() {}
+
+ virtual void didChooseFile(const WebVector<WebString>& file_names) {
+ std::vector<std::string> files;
+ for (size_t i = 0; i < file_names.size(); i++)
+ files.push_back(file_names[i].utf8().data());
+
+ file_chooser_->StoreChosenFiles(files);
+ }
+
+ private:
+ FileChooser* file_chooser_;
+};
+
} // namespace
FileChooser::FileChooser(PluginInstance* instance,
- const PP_FileChooserOptions* options)
+ const PP_FileChooserOptions_Dev* options)
: Resource(instance->module()),
+ delegate_(instance->delegate()),
mode_(options->mode),
- accept_mime_types_(options->accept_mime_types) {
+ accept_mime_types_(options->accept_mime_types),
+ completion_callback_() {
}
FileChooser::~FileChooser() {
}
// static
-const PPB_FileChooser* FileChooser::GetInterface() {
+const PPB_FileChooser_Dev* FileChooser::GetInterface() {
return &ppb_filechooser;
}
+void FileChooser::StoreChosenFiles(const std::vector<std::string>& files) {
+ next_chosen_file_index_ = 0;
+ std::vector<std::string>::const_iterator end_it = files.end();
+ for (std::vector<std::string>::const_iterator it = files.begin();
+ it != end_it; it++)
+ chosen_files_.push_back(
+ new FileRef(module(), PP_FILESYSTEMTYPE_LOCALPERSISTENT, *it, ""));
+
+ if (!completion_callback_.func)
+ return;
+
+ PP_CompletionCallback callback = {0};
+ std::swap(callback, completion_callback_);
+ PP_RunCompletionCallback(&callback, 0);
+}
+
int32_t FileChooser::Show(PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+ DCHECK((mode_ == PP_FILECHOOSERMODE_OPEN) ||
+ (mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE));
+ DCHECK(!completion_callback_.func);
+ completion_callback_ = callback;
+
+ WebFileChooserParams params;
+ params.multiSelect = (mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE);
+ params.acceptTypes = WebString::fromUTF8(accept_mime_types_);
+ params.directory = false;
+
+ return delegate_->RunFileChooser(
+ params, new FileChooserCompletionImpl(this));
}
scoped_refptr<FileRef> FileChooser::GetNextChosenFile() {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return NULL;
+ if (next_chosen_file_index_ >= chosen_files_.size())
+ return NULL;
+
+ return chosen_files_[next_chosen_file_index_++];
}
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_file_chooser.h b/webkit/glue/plugins/pepper_file_chooser.h
index 8474188..eafdd0e 100644
--- a/webkit/glue/plugins/pepper_file_chooser.h
+++ b/webkit/glue/plugins/pepper_file_chooser.h
@@ -6,33 +6,45 @@
#define WEBKIT_GLUE_PLUGINS_PEPPER_FILE_CHOOSER_H_
#include <string>
+#include <vector>
-#include "third_party/ppapi/c/ppb_file_chooser.h"
+#include "base/scoped_ptr.h"
+#include "third_party/ppapi/c/dev/ppb_file_chooser_dev.h"
+#include "third_party/ppapi/c/pp_completion_callback.h"
#include "webkit/glue/plugins/pepper_resource.h"
namespace pepper {
+class PluginDelegate;
class PluginInstance;
class FileChooser : public Resource {
public:
- FileChooser(PluginInstance* instance, const PP_FileChooserOptions* options);
+ FileChooser(PluginInstance* instance,
+ const PP_FileChooserOptions_Dev* options);
virtual ~FileChooser();
// Returns a pointer to the interface implementing PPB_FileChooser that is
// exposed to the plugin.
- static const PPB_FileChooser* GetInterface();
+ static const PPB_FileChooser_Dev* GetInterface();
// Resource overrides.
FileChooser* AsFileChooser() { return this; }
+ // Stores the list of selected files.
+ void StoreChosenFiles(const std::vector<std::string>& files);
+
// PPB_FileChooser implementation.
int32_t Show(PP_CompletionCallback callback);
scoped_refptr<FileRef> GetNextChosenFile();
private:
- PP_FileChooserMode mode_;
+ PluginDelegate* delegate_;
+ PP_FileChooserMode_Dev mode_;
std::string accept_mime_types_;
+ PP_CompletionCallback completion_callback_;
+ std::vector< scoped_refptr<FileRef> > chosen_files_;
+ size_t next_chosen_file_index_;
};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_file_io.cc b/webkit/glue/plugins/pepper_file_io.cc
index 46f7276..9090f88 100644
--- a/webkit/glue/plugins/pepper_file_io.cc
+++ b/webkit/glue/plugins/pepper_file_io.cc
@@ -4,12 +4,19 @@
#include "webkit/glue/plugins/pepper_file_io.h"
+#include "base/callback.h"
+#include "base/file_util.h"
+#include "base/file_util_proxy.h"
+#include "base/message_loop_proxy.h"
+#include "base/platform_file.h"
#include "base/logging.h"
+#include "base/time.h"
+#include "third_party/ppapi/c/dev/ppb_file_io_dev.h"
+#include "third_party/ppapi/c/dev/ppb_file_io_trusted_dev.h"
#include "third_party/ppapi/c/pp_completion_callback.h"
#include "third_party/ppapi/c/pp_errors.h"
-#include "third_party/ppapi/c/ppb_file_io.h"
-#include "third_party/ppapi/c/ppb_file_io_trusted.h"
#include "webkit/glue/plugins/pepper_file_ref.h"
+#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"
@@ -46,12 +53,11 @@ int32_t Open(PP_Resource file_io_id,
}
int32_t Query(PP_Resource file_io_id,
- PP_FileInfo* info,
+ PP_FileInfo_Dev* info,
PP_CompletionCallback callback) {
scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
if (!file_io)
return PP_ERROR_BADRESOURCE;
-
return file_io->Query(info, callback);
}
@@ -62,7 +68,6 @@ int32_t Touch(PP_Resource file_io_id,
scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
if (!file_io)
return PP_ERROR_BADRESOURCE;
-
return file_io->Touch(last_access_time, last_modified_time, callback);
}
@@ -74,7 +79,6 @@ int32_t Read(PP_Resource file_io_id,
scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
if (!file_io)
return PP_ERROR_BADRESOURCE;
-
return file_io->Read(offset, buffer, bytes_to_read, callback);
}
@@ -86,7 +90,6 @@ int32_t Write(PP_Resource file_io_id,
scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
if (!file_io)
return PP_ERROR_BADRESOURCE;
-
return file_io->Write(offset, buffer, bytes_to_write, callback);
}
@@ -96,7 +99,6 @@ int32_t SetLength(PP_Resource file_io_id,
scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
if (!file_io)
return PP_ERROR_BADRESOURCE;
-
return file_io->SetLength(length, callback);
}
@@ -105,7 +107,6 @@ int32_t Flush(PP_Resource file_io_id,
scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
if (!file_io)
return PP_ERROR_BADRESOURCE;
-
return file_io->Flush(callback);
}
@@ -113,11 +114,10 @@ void Close(PP_Resource file_io_id) {
scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
if (!file_io)
return;
-
file_io->Close();
}
-const PPB_FileIO ppb_fileio = {
+const PPB_FileIO_Dev ppb_fileio = {
&Create,
&IsFileIO,
&Open,
@@ -134,7 +134,6 @@ int32_t GetOSFileDescriptor(PP_Resource file_io_id) {
scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
if (!file_io)
return PP_ERROR_BADRESOURCE;
-
return file_io->GetOSFileDescriptor();
}
@@ -145,7 +144,6 @@ int32_t WillWrite(PP_Resource file_io_id,
scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
if (!file_io)
return PP_ERROR_BADRESOURCE;
-
return file_io->WillWrite(offset, bytes_to_write, callback);
}
@@ -155,101 +153,281 @@ int32_t WillSetLength(PP_Resource file_io_id,
scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
if (!file_io)
return PP_ERROR_BADRESOURCE;
-
return file_io->WillSetLength(length, callback);
}
-const PPB_FileIOTrusted ppb_fileiotrusted = {
+const PPB_FileIOTrusted_Dev ppb_fileiotrusted = {
&GetOSFileDescriptor,
&WillWrite,
&WillSetLength
};
+int PlatformFileErrorToPepperError(base::PlatformFileError error_code) {
+ switch (error_code) {
+ case base::PLATFORM_FILE_OK:
+ return PP_OK;
+ case base::PLATFORM_FILE_ERROR_EXISTS:
+ return PP_ERROR_FILEEXISTS;
+ case base::PLATFORM_FILE_ERROR_NOT_FOUND:
+ return PP_ERROR_FILENOTFOUND;
+ case base::PLATFORM_FILE_ERROR_ACCESS_DENIED:
+ return PP_ERROR_NOACCESS;
+ case base::PLATFORM_FILE_ERROR_NO_MEMORY:
+ return PP_ERROR_NOMEMORY;
+ case base::PLATFORM_FILE_ERROR_NO_SPACE:
+ return PP_ERROR_NOSPACE;
+ case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
+ NOTREACHED();
+ return PP_ERROR_FAILED;
+ default:
+ return PP_ERROR_FAILED;
+ }
+}
+
} // namespace
-FileIO::FileIO(PluginModule* module) : Resource(module) {
+FileIO::FileIO(PluginModule* module)
+ : Resource(module),
+ delegate_(module->GetSomeInstance()->delegate()),
+ ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)),
+ file_(base::kInvalidPlatformFileValue),
+ callback_(),
+ info_(NULL) {
}
FileIO::~FileIO() {
+ Close();
}
// static
-const PPB_FileIO* FileIO::GetInterface() {
+const PPB_FileIO_Dev* FileIO::GetInterface() {
return &ppb_fileio;
}
// static
-const PPB_FileIOTrusted* FileIO::GetTrustedInterface() {
+const PPB_FileIOTrusted_Dev* FileIO::GetTrustedInterface() {
return &ppb_fileiotrusted;
}
int32_t FileIO::Open(FileRef* file_ref,
int32_t open_flags,
PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+ if (file_ != base::kInvalidPlatformFileValue)
+ return PP_ERROR_FAILED;
+
+ DCHECK(!callback_.func);
+ callback_ = callback;
+
+ int flags = 0;
+ if (open_flags & PP_FILEOPENFLAG_READ)
+ flags |= base::PLATFORM_FILE_READ;
+ if (open_flags & PP_FILEOPENFLAG_WRITE) {
+ flags |= base::PLATFORM_FILE_WRITE;
+ flags |= base::PLATFORM_FILE_WRITE_ATTRIBUTES;
+ }
+ if (open_flags & PP_FILEOPENFLAG_TRUNCATE) {
+ DCHECK(flags & PP_FILEOPENFLAG_WRITE);
+ flags |= base::PLATFORM_FILE_TRUNCATE;
+ }
+
+ if (open_flags & PP_FILEOPENFLAG_CREATE) {
+ if (open_flags & PP_FILEOPENFLAG_EXCLUSIVE)
+ flags |= base::PLATFORM_FILE_CREATE;
+ else
+ flags |= base::PLATFORM_FILE_OPEN_ALWAYS;
+ } else
+ flags |= base::PLATFORM_FILE_OPEN;
+
+ file_system_type_ = file_ref->file_system_type();
+ if (!delegate_->AsyncOpenFile(
+ file_ref->system_path(), flags,
+ callback_factory_.NewCallback(&FileIO::AsyncOpenFileCallback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
-int32_t FileIO::Query(PP_FileInfo* info,
+int32_t FileIO::Query(PP_FileInfo_Dev* info,
PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+ if (file_ == base::kInvalidPlatformFileValue)
+ return PP_ERROR_FAILED;
+
+ DCHECK(!callback_.func);
+ callback_ = callback;
+
+ DCHECK(!info_);
+ DCHECK(info);
+ info_ = info;
+
+ if (!base::FileUtilProxy::GetFileInfoFromPlatformFile(
+ delegate_->GetFileThreadMessageLoopProxy(), file_,
+ callback_factory_.NewCallback(&FileIO::QueryInfoCallback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
int32_t FileIO::Touch(PP_Time last_access_time,
PP_Time last_modified_time,
PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+ if (file_ == base::kInvalidPlatformFileValue)
+ return PP_ERROR_FAILED;
+
+ DCHECK(!callback_.func);
+ callback_ = callback;
+
+ if (!base::FileUtilProxy::Touch(
+ delegate_->GetFileThreadMessageLoopProxy(),
+ file_, base::Time::FromDoubleT(last_access_time),
+ base::Time::FromDoubleT(last_modified_time),
+ callback_factory_.NewCallback(&FileIO::StatusCallback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
int32_t FileIO::Read(int64_t offset,
char* buffer,
int32_t bytes_to_read,
PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+ if (file_ == base::kInvalidPlatformFileValue)
+ return PP_ERROR_FAILED;
+
+ DCHECK(!callback_.func);
+ callback_ = callback;
+
+ if (!base::FileUtilProxy::Read(
+ delegate_->GetFileThreadMessageLoopProxy(),
+ file_, offset, buffer, bytes_to_read,
+ callback_factory_.NewCallback(&FileIO::ReadWriteCallback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
int32_t FileIO::Write(int64_t offset,
const char* buffer,
int32_t bytes_to_write,
PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+ if (file_ == base::kInvalidPlatformFileValue)
+ return PP_ERROR_FAILED;
+
+ DCHECK(!callback_.func);
+ callback_ = callback;
+
+ if (!base::FileUtilProxy::Write(
+ delegate_->GetFileThreadMessageLoopProxy(),
+ file_, offset, buffer, bytes_to_write,
+ callback_factory_.NewCallback(&FileIO::ReadWriteCallback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
int32_t FileIO::SetLength(int64_t length,
PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+ if (file_ == base::kInvalidPlatformFileValue)
+ return PP_ERROR_FAILED;
+
+ DCHECK(!callback_.func);
+ callback_ = callback;
+
+ if (!base::FileUtilProxy::Truncate(
+ delegate_->GetFileThreadMessageLoopProxy(),
+ file_, length,
+ callback_factory_.NewCallback(&FileIO::StatusCallback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
int32_t FileIO::Flush(PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+ if (file_ == base::kInvalidPlatformFileValue)
+ return PP_ERROR_FAILED;
+
+ DCHECK(!callback_.func);
+ callback_ = callback;
+
+ if (!base::FileUtilProxy::Flush(
+ delegate_->GetFileThreadMessageLoopProxy(), file_,
+ callback_factory_.NewCallback(&FileIO::StatusCallback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
void FileIO::Close() {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
+ if (file_ != base::kInvalidPlatformFileValue)
+ base::FileUtilProxy::Close(
+ delegate_->GetFileThreadMessageLoopProxy(), file_, NULL);
}
int32_t FileIO::GetOSFileDescriptor() {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+#if defined(OS_POSIX)
+ return file_;
+#elif defined(OS_WIN)
+ return reinterpret_cast<uintptr_t>(file_);
+#else
+#error "Platform not supported."
+#endif
}
int32_t FileIO::WillWrite(int64_t offset,
int32_t bytes_to_write,
PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+ // TODO(dumi): implement me
+ return PP_OK;
}
int32_t FileIO::WillSetLength(int64_t length,
PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_ERROR_FAILED;
+ // TODO(dumi): implement me
+ return PP_OK;
+}
+
+void FileIO::RunPendingCallback(int result) {
+ if (!callback_.func)
+ return;
+
+ PP_CompletionCallback callback = {0};
+ std::swap(callback, callback_);
+ PP_RunCompletionCallback(&callback, result);
+}
+
+void FileIO::StatusCallback(base::PlatformFileError error_code) {
+ RunPendingCallback(PlatformFileErrorToPepperError(error_code));
+}
+
+void FileIO::AsyncOpenFileCallback(base::PlatformFileError error_code,
+ base::PlatformFile file) {
+ DCHECK(file_ == base::kInvalidPlatformFileValue);
+ file_ = file;
+ RunPendingCallback(PlatformFileErrorToPepperError(error_code));
+}
+
+void FileIO::QueryInfoCallback(base::PlatformFileError error_code,
+ const base::PlatformFileInfo& file_info) {
+ DCHECK(info_);
+ if (error_code == base::PLATFORM_FILE_OK) {
+ info_->size = file_info.size;
+ info_->creation_time = file_info.creation_time.ToDoubleT();
+ info_->last_access_time = file_info.last_accessed.ToDoubleT();
+ info_->last_modified_time = file_info.last_modified.ToDoubleT();
+ info_->system_type = file_system_type_;
+ if (file_info.is_directory)
+ info_->type = PP_FILETYPE_DIRECTORY;
+ else
+ info_->type = PP_FILETYPE_REGULAR;
+ }
+ RunPendingCallback(PlatformFileErrorToPepperError(error_code));
+}
+
+void FileIO::ReadWriteCallback(base::PlatformFileError error_code,
+ int bytes_read_or_written) {
+ if (error_code != base::PLATFORM_FILE_OK)
+ RunPendingCallback(PlatformFileErrorToPepperError(error_code));
+ else
+ RunPendingCallback(bytes_read_or_written);
}
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_file_io.h b/webkit/glue/plugins/pepper_file_io.h
index 4af6f2b..bda8ed6 100644
--- a/webkit/glue/plugins/pepper_file_io.h
+++ b/webkit/glue/plugins/pepper_file_io.h
@@ -5,13 +5,20 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_FILE_IO_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_FILE_IO_H_
+#include "base/file_path.h"
+#include "base/platform_file.h"
+#include "base/scoped_callback_factory.h"
+#include "base/scoped_ptr.h"
+#include "third_party/ppapi/c/dev/pp_file_info_dev.h"
+#include "third_party/ppapi/c/pp_completion_callback.h"
#include "third_party/ppapi/c/pp_time.h"
+#include "webkit/glue/plugins/pepper_plugin_delegate.h"
#include "webkit/glue/plugins/pepper_resource.h"
-typedef struct _pp_CompletionCallback PP_CompletionCallback;
-typedef struct _pp_FileInfo PP_FileInfo;
-typedef struct _ppb_FileIO PPB_FileIO;
-typedef struct _ppb_FileIOTrusted PPB_FileIOTrusted;
+struct PP_CompletionCallback;
+struct PP_FileInfo_Dev;
+struct PPB_FileIO_Dev;
+struct PPB_FileIOTrusted_Dev;
namespace pepper {
@@ -24,11 +31,11 @@ class FileIO : public Resource {
// Returns a pointer to the interface implementing PPB_FileIO that is exposed
// to the plugin.
- static const PPB_FileIO* GetInterface();
+ static const PPB_FileIO_Dev* GetInterface();
// Returns a pointer to the interface implementing PPB_FileIOTrusted that is
// exposed to the plugin.
- static const PPB_FileIOTrusted* GetTrustedInterface();
+ static const PPB_FileIOTrusted_Dev* GetTrustedInterface();
// Resource overrides.
FileIO* AsFileIO() { return this; }
@@ -37,7 +44,7 @@ class FileIO : public Resource {
int32_t Open(FileRef* file_ref,
int32_t open_flags,
PP_CompletionCallback callback);
- int32_t Query(PP_FileInfo* info,
+ int32_t Query(PP_FileInfo_Dev* info,
PP_CompletionCallback callback);
int32_t Touch(PP_Time last_access_time,
PP_Time last_modified_time,
@@ -62,6 +69,25 @@ class FileIO : public Resource {
PP_CompletionCallback callback);
int32_t WillSetLength(int64_t length,
PP_CompletionCallback callback);
+
+ void RunPendingCallback(int result);
+ void StatusCallback(base::PlatformFileError error_code);
+ void AsyncOpenFileCallback(base::PlatformFileError error_code,
+ base::PlatformFile file);
+ void QueryInfoCallback(base::PlatformFileError error_code,
+ const base::PlatformFileInfo& file_info);
+ void ReadWriteCallback(base::PlatformFileError error_code,
+ int bytes_read_or_written);
+
+ private:
+ PluginDelegate* delegate_;
+ base::ScopedCallbackFactory<FileIO> callback_factory_;
+
+ base::PlatformFile file_;
+ PP_FileSystemType_Dev file_system_type_;
+
+ PP_CompletionCallback callback_;
+ PP_FileInfo_Dev* info_;
};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_file_ref.cc b/webkit/glue/plugins/pepper_file_ref.cc
index 9b42cff..7cb65a4 100644
--- a/webkit/glue/plugins/pepper_file_ref.cc
+++ b/webkit/glue/plugins/pepper_file_ref.cc
@@ -4,6 +4,8 @@
#include "webkit/glue/plugins/pepper_file_ref.h"
+#include "base/base_paths.h"
+#include "base/path_service.h"
#include "base/string_util.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_var.h"
@@ -33,7 +35,7 @@ void TrimTrailingSlash(std::string* path) {
}
PP_Resource CreateFileRef(PP_Instance instance_id,
- PP_FileSystemType fs_type,
+ PP_FileSystemType_Dev fs_type,
const char* path) {
PluginInstance* instance = PluginInstance::FromPPInstance(instance_id);
if (!instance)
@@ -65,11 +67,10 @@ bool IsFileRef(PP_Resource resource) {
return !!Resource::GetAs<FileRef>(resource);
}
-PP_FileSystemType GetFileSystemType(PP_Resource file_ref_id) {
+PP_FileSystemType_Dev GetFileSystemType(PP_Resource file_ref_id) {
scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id));
if (!file_ref)
return PP_FILESYSTEMTYPE_EXTERNAL;
-
return file_ref->file_system_type();
}
@@ -77,8 +78,7 @@ PP_Var GetName(PP_Resource file_ref_id) {
scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id));
if (!file_ref)
return PP_MakeVoid();
-
- return StringToPPVar(file_ref->GetName());
+ return StringVar::StringToPPVar(file_ref->module(), file_ref->GetName());
}
PP_Var GetPath(PP_Resource file_ref_id) {
@@ -89,7 +89,7 @@ PP_Var GetPath(PP_Resource file_ref_id) {
if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL)
return PP_MakeVoid();
- return StringToPPVar(file_ref->path());
+ return StringVar::StringToPPVar(file_ref->module(), file_ref->path());
}
PP_Resource GetParent(PP_Resource file_ref_id) {
@@ -107,7 +107,7 @@ PP_Resource GetParent(PP_Resource file_ref_id) {
return parent_ref->GetReference();
}
-const PPB_FileRef ppb_fileref = {
+const PPB_FileRef_Dev ppb_fileref = {
&CreatePersistentFileRef,
&CreateTemporaryFileRef,
&IsFileRef,
@@ -120,7 +120,7 @@ const PPB_FileRef ppb_fileref = {
} // namespace
FileRef::FileRef(PluginModule* module,
- PP_FileSystemType file_system_type,
+ PP_FileSystemType_Dev file_system_type,
const std::string& validated_path,
const std::string& origin)
: Resource(module),
@@ -130,11 +130,18 @@ FileRef::FileRef(PluginModule* module,
// TODO(darin): Need to initialize system_path_.
}
+FileRef::FileRef(PluginModule* module,
+ const FilePath& external_file_path)
+ : Resource(module),
+ system_path_(external_file_path),
+ fs_type_(PP_FILESYSTEMTYPE_EXTERNAL) {
+}
+
FileRef::~FileRef() {
}
// static
-const PPB_FileRef* FileRef::GetInterface() {
+const PPB_FileRef_Dev* FileRef::GetInterface() {
return &ppb_fileref;
}
@@ -166,4 +173,21 @@ scoped_refptr<FileRef> FileRef::GetParent() {
return parent_ref;
}
+// static
+FileRef* FileRef::GetInaccessibleFileRef(PluginModule* module) {
+ FilePath inaccessible_path;
+ if (!PathService::Get(base::FILE_MODULE, &inaccessible_path))
+ return NULL;
+ return new FileRef(module, inaccessible_path);
+}
+
+// static
+FileRef* FileRef::GetNonexistentFileRef(PluginModule* module) {
+ FilePath dir_module_path;
+ if (!PathService::Get(base::DIR_MODULE, &dir_module_path))
+ return NULL;
+ return new FileRef(module, dir_module_path.Append(
+ FILE_PATH_LITERAL("nonexistent_file")));
+}
+
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_file_ref.h b/webkit/glue/plugins/pepper_file_ref.h
index 34e4c3e..0ab0e65 100644
--- a/webkit/glue/plugins/pepper_file_ref.h
+++ b/webkit/glue/plugins/pepper_file_ref.h
@@ -8,7 +8,7 @@
#include <string>
#include "base/file_path.h"
-#include "third_party/ppapi/c/ppb_file_ref.h"
+#include "third_party/ppapi/c/dev/ppb_file_ref_dev.h"
#include "webkit/glue/plugins/pepper_resource.h"
namespace pepper {
@@ -18,14 +18,16 @@ class PluginModule;
class FileRef : public Resource {
public:
FileRef(PluginModule* module,
- PP_FileSystemType file_system_type,
+ PP_FileSystemType_Dev file_system_type,
const std::string& validated_path,
const std::string& origin);
+ FileRef(PluginModule* module,
+ const FilePath& external_file_path);
virtual ~FileRef();
// Returns a pointer to the interface implementing PPB_FileRef that is
// exposed to the plugin.
- static const PPB_FileRef* GetInterface();
+ static const PPB_FileRef_Dev* GetInterface();
// Resource overrides.
FileRef* AsFileRef() { return this; }
@@ -34,7 +36,7 @@ class FileRef : public Resource {
std::string GetName() const;
scoped_refptr<FileRef> GetParent();
- PP_FileSystemType file_system_type() const { return fs_type_; }
+ PP_FileSystemType_Dev file_system_type() const { return fs_type_; }
// Returns the virtual path (i.e., the path that the pepper plugin sees)
// corresponding to this file.
@@ -43,9 +45,17 @@ class FileRef : public Resource {
// Returns the system path corresponding to this file.
const FilePath& system_path() const { return system_path_; }
+ // Returns a FileRef instance pointing to a file that should not be
+ // accessible by the plugin. Should be used for testing only.
+ static FileRef* GetInaccessibleFileRef(PluginModule* module);
+
+ // Returns a FileRef instance pointing to a nonexistent file.
+ // Should be used for testing only.
+ static FileRef* GetNonexistentFileRef(PluginModule* module);
+
private:
FilePath system_path_;
- PP_FileSystemType fs_type_;
+ PP_FileSystemType_Dev fs_type_;
std::string path_; // UTF-8 encoded.
std::string origin_;
};
diff --git a/webkit/glue/plugins/pepper_file_system.cc b/webkit/glue/plugins/pepper_file_system.cc
index 678399e..82a2fc8 100644
--- a/webkit/glue/plugins/pepper_file_system.cc
+++ b/webkit/glue/plugins/pepper_file_system.cc
@@ -4,45 +4,235 @@
#include "webkit/glue/plugins/pepper_file_system.h"
+#include "base/logging.h"
+#include "base/ref_counted.h"
+#include "base/weak_ptr.h"
+#include "third_party/ppapi/c/dev/ppb_file_system_dev.h"
#include "third_party/ppapi/c/pp_completion_callback.h"
-#include "third_party/ppapi/c/pp_errors.h"
-#include "third_party/ppapi/c/ppb_file_system.h"
+#include "third_party/ppapi/c/pp_time.h"
+#include "webkit/fileapi/file_system_callback_dispatcher.h"
+#include "webkit/glue/plugins/pepper_resource.h"
+#include "webkit/glue/plugins/pepper_error_util.h"
+#include "webkit/glue/plugins/pepper_file_ref.h"
+#include "webkit/glue/plugins/pepper_plugin_delegate.h"
+#include "webkit/glue/plugins/pepper_plugin_instance.h"
+#include "webkit/glue/plugins/pepper_plugin_module.h"
+#include "webkit/glue/plugins/pepper_resource.h"
namespace pepper {
namespace {
-int32_t MakeDirectory(PP_Resource directory_ref,
+// Instances of this class are deleted when RunCallback() is called.
+class StatusCallback : public fileapi::FileSystemCallbackDispatcher {
+ public:
+ StatusCallback(base::WeakPtr<pepper::PluginModule> module,
+ PP_CompletionCallback callback)
+ : module_(module),
+ callback_(callback) {
+ }
+
+ // FileSystemCallbackDispatcher implementation.
+ virtual void DidSucceed() {
+ RunCallback(base::PLATFORM_FILE_OK);
+ }
+
+ virtual void DidReadMetadata(const base::PlatformFileInfo&) {
+ NOTREACHED();
+ }
+
+ virtual void DidReadDirectory(
+ const std::vector<base::file_util_proxy::Entry>&, bool) {
+ NOTREACHED();
+ }
+
+ virtual void DidOpenFileSystem(const std::string&, const FilePath&) {
+ NOTREACHED();
+ }
+
+ virtual void DidFail(base::PlatformFileError error_code) {
+ RunCallback(error_code);
+ }
+
+ private:
+ void RunCallback(base::PlatformFileError error_code) {
+ if (!module_.get() || !callback_.func)
+ return;
+
+ PP_RunCompletionCallback(
+ &callback_, pepper::PlatformFileErrorToPepperError(error_code));
+
+ delete this;
+ }
+
+ base::WeakPtr<pepper::PluginModule> module_;
+ PP_CompletionCallback callback_;
+};
+
+// Instances of this class are deleted when RunCallback() is called.
+class QueryInfoCallback : public fileapi::FileSystemCallbackDispatcher {
+ public:
+ QueryInfoCallback(base::WeakPtr<pepper::PluginModule> module,
+ PP_CompletionCallback callback,
+ PP_FileInfo_Dev* info,
+ PP_FileSystemType_Dev file_system_type)
+ : module_(module),
+ callback_(callback),
+ info_(info),
+ file_system_type_(file_system_type) {
+ DCHECK(info_);
+ }
+
+ // FileSystemCallbackDispatcher implementation.
+ virtual void DidSucceed() {
+ NOTREACHED();
+ }
+
+ virtual void DidReadMetadata(const base::PlatformFileInfo& file_info) {
+ RunCallback(base::PLATFORM_FILE_OK, file_info);
+ }
+
+ virtual void DidReadDirectory(
+ const std::vector<base::file_util_proxy::Entry>&, bool) {
+ NOTREACHED();
+ }
+
+ virtual void DidOpenFileSystem(const std::string&, const FilePath&) {
+ NOTREACHED();
+ }
+
+ virtual void DidFail(base::PlatformFileError error_code) {
+ RunCallback(error_code, base::PlatformFileInfo());
+ }
+
+ private:
+ void RunCallback(base::PlatformFileError error_code,
+ const base::PlatformFileInfo& file_info) {
+ if (!module_.get() || !callback_.func)
+ return;
+
+ if (error_code == base::PLATFORM_FILE_OK) {
+ info_->size = file_info.size;
+ info_->creation_time = file_info.creation_time.ToDoubleT();
+ info_->last_access_time = file_info.last_accessed.ToDoubleT();
+ info_->last_modified_time = file_info.last_modified.ToDoubleT();
+ info_->system_type = file_system_type_;
+ if (file_info.is_directory)
+ info_->type = PP_FILETYPE_DIRECTORY;
+ else
+ info_->type = PP_FILETYPE_REGULAR;
+ }
+ PP_RunCompletionCallback(
+ &callback_, pepper::PlatformFileErrorToPepperError(error_code));
+
+ delete this;
+ }
+
+ base::WeakPtr<pepper::PluginModule> module_;
+ PP_CompletionCallback callback_;
+ PP_FileInfo_Dev* info_;
+ PP_FileSystemType_Dev file_system_type_;
+};
+
+int32_t MakeDirectory(PP_Resource directory_ref_id,
bool make_ancestors,
PP_CompletionCallback callback) {
- return PP_ERROR_FAILED; // TODO(darin): Implement me!
+ scoped_refptr<FileRef> directory_ref(
+ Resource::GetAs<FileRef>(directory_ref_id));
+ if (!directory_ref)
+ return PP_ERROR_BADRESOURCE;
+
+ if (directory_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL)
+ return PP_ERROR_FAILED;
+
+ PluginModule* module = directory_ref->module();
+ if (!module->GetSomeInstance()->delegate()->MakeDirectory(
+ directory_ref->system_path(), make_ancestors,
+ new StatusCallback(module->AsWeakPtr(), callback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
-int32_t Query(PP_Resource file_ref,
- PP_FileInfo* info,
+int32_t Query(PP_Resource file_ref_id,
+ PP_FileInfo_Dev* info,
PP_CompletionCallback callback) {
- return PP_ERROR_FAILED; // TODO(darin): Implement me!
+ scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id));
+ if (!file_ref)
+ return PP_ERROR_BADRESOURCE;
+
+ PluginModule* module = file_ref->module();
+ if (!module->GetSomeInstance()->delegate()->Query(
+ file_ref->system_path(),
+ new QueryInfoCallback(module->AsWeakPtr(), callback,
+ info, file_ref->file_system_type())))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
-int32_t Touch(PP_Resource file_ref,
+int32_t Touch(PP_Resource file_ref_id,
PP_Time last_access_time,
PP_Time last_modified_time,
PP_CompletionCallback callback) {
- return PP_ERROR_FAILED; // TODO(darin): Implement me!
+ scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id));
+ if (!file_ref)
+ return PP_ERROR_BADRESOURCE;
+
+ PluginModule* module = file_ref->module();
+ if (!module->GetSomeInstance()->delegate()->Touch(
+ file_ref->system_path(), base::Time::FromDoubleT(last_access_time),
+ base::Time::FromDoubleT(last_modified_time),
+ new StatusCallback(module->AsWeakPtr(), callback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
-int32_t Delete(PP_Resource file_ref,
+int32_t Delete(PP_Resource file_ref_id,
PP_CompletionCallback callback) {
- return PP_ERROR_FAILED; // TODO(darin): Implement me!
+ scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id));
+ if (!file_ref)
+ return PP_ERROR_BADRESOURCE;
+
+ if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL)
+ return PP_ERROR_FAILED;
+
+ PluginModule* module = file_ref->module();
+ if (!module->GetSomeInstance()->delegate()->Delete(
+ file_ref->system_path(),
+ new StatusCallback(module->AsWeakPtr(), callback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
-int32_t Rename(PP_Resource file_ref,
- PP_Resource new_file_ref,
+int32_t Rename(PP_Resource file_ref_id,
+ PP_Resource new_file_ref_id,
PP_CompletionCallback callback) {
- return PP_ERROR_FAILED; // TODO(darin): Implement me!
+ scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id));
+ if (!file_ref)
+ return PP_ERROR_BADRESOURCE;
+
+ scoped_refptr<FileRef> new_file_ref(
+ Resource::GetAs<FileRef>(new_file_ref_id));
+ if (!new_file_ref)
+ return PP_ERROR_BADRESOURCE;
+
+ if ((file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) ||
+ (file_ref->file_system_type() != new_file_ref->file_system_type()))
+ return PP_ERROR_FAILED;
+
+ PluginModule* module = file_ref->module();
+ if (!module->GetSomeInstance()->delegate()->Rename(
+ file_ref->system_path(), new_file_ref->system_path(),
+ new StatusCallback(module->AsWeakPtr(), callback)))
+ return PP_ERROR_FAILED;
+
+ return PP_ERROR_WOULDBLOCK;
}
-const PPB_FileSystem ppb_filesystem = {
+const PPB_FileSystem_Dev ppb_filesystem = {
&MakeDirectory,
&Query,
&Touch,
@@ -52,7 +242,7 @@ const PPB_FileSystem ppb_filesystem = {
} // namespace
-const PPB_FileSystem* FileSystem::GetInterface() {
+const PPB_FileSystem_Dev* FileSystem::GetInterface() {
return &ppb_filesystem;
}
diff --git a/webkit/glue/plugins/pepper_file_system.h b/webkit/glue/plugins/pepper_file_system.h
index b8ad01a..1abfc52 100644
--- a/webkit/glue/plugins/pepper_file_system.h
+++ b/webkit/glue/plugins/pepper_file_system.h
@@ -5,7 +5,9 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_FILE_SYSTEM_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_FILE_SYSTEM_H_
-typedef struct _ppb_FileSystem PPB_FileSystem;
+#include "base/basictypes.h"
+
+struct PPB_FileSystem_Dev;
namespace pepper {
@@ -13,7 +15,10 @@ class FileSystem {
public:
// Returns a pointer to the interface implementing PPB_FileSystem that is
// exposed to the plugin.
- static const PPB_FileSystem* GetInterface();
+ static const PPB_FileSystem_Dev* GetInterface();
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystem);
};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_font.cc b/webkit/glue/plugins/pepper_font.cc
index af4cb81..82bf369 100644
--- a/webkit/glue/plugins/pepper_font.cc
+++ b/webkit/glue/plugins/pepper_font.cc
@@ -2,98 +2,290 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "build/build_config.h"
-
#include "webkit/glue/plugins/pepper_font.h"
-#if defined(OS_LINUX)
-#include <unistd.h>
-#endif
-
#include "base/logging.h"
-#include "third_party/ppapi/c/ppb_font.h"
+#include "base/utf_string_conversions.h"
+#include "third_party/ppapi/c/dev/ppb_font_dev.h"
+#include "third_party/ppapi/c/pp_rect.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFont.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFontDescription.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFloatPoint.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFloatRect.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebTextRun.h"
+#include "webkit/glue/plugins/pepper_image_data.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
+#include "webkit/glue/plugins/pepper_string.h"
+#include "webkit/glue/plugins/pepper_var.h"
#include "webkit/glue/webkit_glue.h"
+using WebKit::WebFloatPoint;
+using WebKit::WebFloatRect;
+using WebKit::WebFont;
+using WebKit::WebFontDescription;
+using WebKit::WebRect;
+using WebKit::WebTextRun;
+
namespace pepper {
namespace {
-PP_Resource MatchFontWithFallback(PP_Module module_id,
- const PP_FontDescription* description) {
-#if defined(OS_LINUX)
+bool IsPPFontDescriptionValid(const PP_FontDescription_Dev& desc) {
+ // Check validity of UTF-8.
+ if (desc.face.type != PP_VARTYPE_STRING && desc.face.type != PP_VARTYPE_VOID)
+ return false;
+
+ // Check enum ranges.
+ if (static_cast<int>(desc.family) < PP_FONTFAMILY_DEFAULT ||
+ static_cast<int>(desc.family) > PP_FONTFAMILY_MONOSPACE)
+ return false;
+ if (static_cast<int>(desc.weight) < PP_FONTWEIGHT_100 ||
+ static_cast<int>(desc.weight) > PP_FONTWEIGHT_900)
+ return false;
+
+ // Check for excessive sizes which may cause layout to get confused.
+ if (desc.size > 200)
+ return false;
+
+ return true;
+}
+
+// The PP_* version lacks "None", so is just one value shifted from the
+// WebFontDescription version. These values are checked in
+// PPFontDescToWebFontDesc to make sure the conversion is correct. This is a
+// macro so it can also be used in the COMPILE_ASSERTS.
+#define PP_FONTFAMILY_TO_WEB_FONTFAMILY(f) \
+ static_cast<WebFontDescription::GenericFamily>(f + 1)
+
+// Assumes the given PP_FontDescription has been validated.
+WebFontDescription PPFontDescToWebFontDesc(const PP_FontDescription_Dev& font) {
+ // Verify that the enums match so we can just static cast.
+ COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight100) ==
+ static_cast<int>(PP_FONTWEIGHT_100),
+ FontWeight100);
+ COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight900) ==
+ static_cast<int>(PP_FONTWEIGHT_900),
+ FontWeight900);
+ COMPILE_ASSERT(WebFontDescription::GenericFamilyStandard ==
+ PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_DEFAULT),
+ StandardFamily);
+ COMPILE_ASSERT(WebFontDescription::GenericFamilySerif ==
+ PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SERIF),
+ SerifFamily);
+ COMPILE_ASSERT(WebFontDescription::GenericFamilySansSerif ==
+ PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SANSSERIF),
+ SansSerifFamily);
+ COMPILE_ASSERT(WebFontDescription::GenericFamilyMonospace ==
+ PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_MONOSPACE),
+ MonospaceFamily);
+
+ WebFontDescription result;
+ scoped_refptr<StringVar> face_name(StringVar::FromPPVar(font.face));
+ if (face_name)
+ result.family = UTF8ToUTF16(face_name->value());
+ result.genericFamily = PP_FONTFAMILY_TO_WEB_FONTFAMILY(font.family);
+ result.size = static_cast<float>(font.size);
+ result.italic = font.italic;
+ result.smallCaps = font.small_caps;
+ result.weight = static_cast<WebFontDescription::Weight>(font.weight);
+ result.letterSpacing = static_cast<short>(font.letter_spacing);
+ result.wordSpacing = static_cast<short>(font.word_spacing);
+ return result;
+}
+
+// Converts the given PP_TextRun to a WebTextRun, returning true on success.
+// False means the input was invalid.
+bool PPTextRunToWebTextRun(const PP_TextRun_Dev* run, WebTextRun* output) {
+ scoped_refptr<StringVar> text_string(StringVar::FromPPVar(run->text));
+ if (!text_string)
+ return false;
+ *output = WebTextRun(UTF8ToUTF16(text_string->value()),
+ run->rtl, run->override_direction);
+ return true;
+}
+
+PP_Resource Create(PP_Module module_id,
+ const PP_FontDescription_Dev* description) {
PluginModule* module = PluginModule::FromPPModule(module_id);
if (!module)
- return NULL;
+ return 0;
- int fd = webkit_glue::MatchFontWithFallback(description->face,
- description->weight >= 700,
- description->italic,
- description->charset);
- if (fd == -1)
- return NULL;
-
- scoped_refptr<Font> font(new Font(module, fd));
+ if (!IsPPFontDescriptionValid(*description))
+ return 0;
+ scoped_refptr<Font> font(new Font(module, *description));
return font->GetReference();
-#else
- // For trusted pepper plugins, this is only needed in Linux since font loading
- // on Windows and Mac works through the renderer sandbox.
- return false;
-#endif
}
bool IsFont(PP_Resource resource) {
- return !!Resource::GetAs<Font>(resource);
+ return !!Resource::GetAs<Font>(resource).get();
}
-bool GetFontTable(PP_Resource font_id,
- uint32_t table,
- void* output,
- uint32_t* output_length) {
+bool Describe(PP_Resource font_id,
+ PP_FontDescription_Dev* description,
+ PP_FontMetrics_Dev* metrics) {
scoped_refptr<Font> font(Resource::GetAs<Font>(font_id));
if (!font.get())
return false;
+ return font->Describe(description, metrics);
+}
- return font->GetFontTable(table, output, output_length);
+bool DrawTextAt(PP_Resource font_id,
+ PP_Resource image_data,
+ const PP_TextRun_Dev* text,
+ const PP_Point* position,
+ uint32_t color,
+ const PP_Rect* clip,
+ bool image_data_is_opaque) {
+ scoped_refptr<Font> font(Resource::GetAs<Font>(font_id));
+ if (!font.get())
+ return false;
+ return font->DrawTextAt(image_data, text, position, color, clip,
+ image_data_is_opaque);
}
-const PPB_Font ppb_font = {
- &MatchFontWithFallback,
+int32_t MeasureText(PP_Resource font_id, const PP_TextRun_Dev* text) {
+ scoped_refptr<Font> font(Resource::GetAs<Font>(font_id));
+ if (!font.get())
+ return -1;
+ return font->MeasureText(text);
+}
+
+uint32_t CharacterOffsetForPixel(PP_Resource font_id,
+ const PP_TextRun_Dev* text,
+ int32_t pixel_position) {
+ scoped_refptr<Font> font(Resource::GetAs<Font>(font_id));
+ if (!font.get())
+ return false;
+ return font->CharacterOffsetForPixel(text, pixel_position);
+}
+
+int32_t PixelOffsetForCharacter(PP_Resource font_id,
+ const PP_TextRun_Dev* text,
+ uint32_t char_offset) {
+ scoped_refptr<Font> font(Resource::GetAs<Font>(font_id));
+ if (!font.get())
+ return false;
+ return font->PixelOffsetForCharacter(text, char_offset);
+}
+
+const PPB_Font_Dev ppb_font = {
+ &Create,
&IsFont,
- &GetFontTable,
+ &Describe,
+ &DrawTextAt,
+ &MeasureText,
+ &CharacterOffsetForPixel,
+ &PixelOffsetForCharacter
};
} // namespace
-Font::Font(PluginModule* module, int fd)
- : Resource(module),
- fd_(fd) {
+Font::Font(PluginModule* module, const PP_FontDescription_Dev& desc)
+ : Resource(module) {
+ WebFontDescription web_font_desc = PPFontDescToWebFontDesc(desc);
+ font_.reset(WebFont::create(web_font_desc));
}
Font::~Font() {
-#if defined (OS_LINUX)
- close(fd_);
-#endif
}
// static
-const PPB_Font* Font::GetInterface() {
+const PPB_Font_Dev* Font::GetInterface() {
return &ppb_font;
}
-bool Font::GetFontTable(uint32_t table,
- void* output,
- uint32_t* output_length) {
-#if defined(OS_LINUX)
- size_t temp_size = static_cast<size_t>(*output_length);
- bool rv = webkit_glue::GetFontTable(
- fd_, table, static_cast<uint8_t*>(output), &temp_size);
- *output_length = static_cast<uint32_t>(temp_size);
- return rv;
-#else
- return false;
-#endif
+bool Font::Describe(PP_FontDescription_Dev* description,
+ PP_FontMetrics_Dev* metrics) {
+ if (description->face.type != PP_VARTYPE_VOID)
+ return false;
+
+ WebFontDescription web_desc = font_->fontDescription();
+
+ // While converting the other way in PPFontDescToWebFontDesc we validated
+ // that the enums can be casted.
+ description->face = StringVar::StringToPPVar(module(),
+ UTF16ToUTF8(web_desc.family));
+ description->family = static_cast<PP_FontFamily_Dev>(web_desc.genericFamily);
+ description->size = static_cast<uint32_t>(web_desc.size);
+ description->weight = static_cast<PP_FontWeight_Dev>(web_desc.weight);
+ description->italic = web_desc.italic;
+ description->small_caps = web_desc.smallCaps;
+
+ metrics->height = font_->height();
+ metrics->ascent = font_->ascent();
+ metrics->descent = font_->descent();
+ metrics->line_spacing = font_->lineSpacing();
+ metrics->x_height = static_cast<int32_t>(font_->xHeight());
+
+ return true;
+}
+
+bool Font::DrawTextAt(PP_Resource image_data,
+ const PP_TextRun_Dev* text,
+ const PP_Point* position,
+ uint32_t color,
+ const PP_Rect* clip,
+ bool image_data_is_opaque) {
+ WebTextRun run;
+ if (!PPTextRunToWebTextRun(text, &run))
+ return false;
+
+ // Get and map the image data we're painting to.
+ scoped_refptr<ImageData> image_resource(
+ Resource::GetAs<ImageData>(image_data));
+ if (!image_resource.get())
+ return false;
+ ImageDataAutoMapper mapper(image_resource);
+ if (!mapper.is_valid())
+ return false;
+
+ // Convert position and clip.
+ WebFloatPoint web_position(static_cast<float>(position->x),
+ static_cast<float>(position->y));
+ WebRect web_clip;
+ if (!clip) {
+ // Use entire canvas.
+ web_clip = WebRect(0, 0, image_resource->width(), image_resource->height());
+ } else {
+ web_clip = WebRect(clip->point.x, clip->point.y,
+ clip->size.width, clip->size.height);
+ }
+
+ font_->drawText(webkit_glue::ToWebCanvas(image_resource->mapped_canvas()),
+ run, web_position, color, web_clip, image_data_is_opaque);
+ return true;
+}
+
+int32_t Font::MeasureText(const PP_TextRun_Dev* text) {
+ WebTextRun run;
+ if (!PPTextRunToWebTextRun(text, &run))
+ return -1;
+ return font_->calculateWidth(run);
+}
+
+uint32_t Font::CharacterOffsetForPixel(const PP_TextRun_Dev* text,
+ int32_t pixel_position) {
+ WebTextRun run;
+ if (!PPTextRunToWebTextRun(text, &run))
+ return -1;
+
+ return static_cast<uint32_t>(font_->offsetForPosition(
+ run, static_cast<float>(pixel_position)));
+}
+
+int32_t Font::PixelOffsetForCharacter(const PP_TextRun_Dev* text,
+ uint32_t char_offset) {
+ WebTextRun run;
+ if (!PPTextRunToWebTextRun(text, &run))
+ return -1;
+ if (char_offset >= run.text.length())
+ return -1;
+
+ WebFloatRect rect = font_->selectionRectForText(
+ run, WebFloatPoint(0.0f, 0.0f), font_->height(), 0, char_offset);
+ return static_cast<int>(rect.width);
}
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_font.h b/webkit/glue/plugins/pepper_font.h
index ad1abba..34fe521 100644
--- a/webkit/glue/plugins/pepper_font.h
+++ b/webkit/glue/plugins/pepper_font.h
@@ -5,9 +5,13 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_FONT_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_FONT_H_
+#include "base/scoped_ptr.h"
+#include "third_party/ppapi/c/dev/ppb_font_dev.h"
#include "webkit/glue/plugins/pepper_resource.h"
-typedef struct _ppb_Font PPB_Font;
+namespace WebKit {
+class WebFont;
+}
namespace pepper {
@@ -15,23 +19,33 @@ class PluginInstance;
class Font : public Resource {
public:
- Font(PluginModule* module, int fd);
+ Font(PluginModule* module, const PP_FontDescription_Dev& desc);
virtual ~Font();
// Returns a pointer to the interface implementing PPB_Font that is exposed to
// the plugin.
- static const PPB_Font* GetInterface();
+ static const PPB_Font_Dev* GetInterface();
// Resource overrides.
Font* AsFont() { return this; }
// PPB_Font implementation.
- bool GetFontTable(uint32_t table,
- void* output,
- uint32_t* output_length);
+ bool Describe(PP_FontDescription_Dev* description,
+ PP_FontMetrics_Dev* metrics);
+ bool DrawTextAt(PP_Resource image_data,
+ const PP_TextRun_Dev* text,
+ const PP_Point* position,
+ uint32_t color,
+ const PP_Rect* clip,
+ bool image_data_is_opaque);
+ int32_t MeasureText(const PP_TextRun_Dev* text);
+ uint32_t CharacterOffsetForPixel(const PP_TextRun_Dev* text,
+ int32_t pixel_position);
+ int32_t PixelOffsetForCharacter(const PP_TextRun_Dev* text,
+ uint32_t char_offset);
private:
- int fd_;
+ scoped_ptr<WebKit::WebFont> font_;
};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_image_data.cc b/webkit/glue/plugins/pepper_image_data.cc
index 8288fe2..aeb2c88 100644
--- a/webkit/glue/plugins/pepper_image_data.cc
+++ b/webkit/glue/plugins/pepper_image_data.cc
@@ -14,6 +14,7 @@
#include "third_party/ppapi/c/pp_module.h"
#include "third_party/ppapi/c/pp_resource.h"
#include "third_party/ppapi/c/ppb_image_data.h"
+#include "third_party/ppapi/c/trusted/ppb_image_data_trusted.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
@@ -31,11 +32,11 @@ PP_Resource Create(PP_Module module_id,
bool init_to_zero) {
PluginModule* module = PluginModule::FromPPModule(module_id);
if (!module)
- return NULL;
+ return 0;
scoped_refptr<ImageData> data(new ImageData(module));
if (!data->Init(format, size->width, size->height, init_to_zero))
- return NULL;
+ return 0;
return data->GetReference();
}
@@ -68,6 +69,13 @@ void Unmap(PP_Resource resource) {
image_data->Unmap();
}
+uint64_t GetNativeMemoryHandle2(PP_Resource resource) {
+ scoped_refptr<ImageData> image_data(Resource::GetAs<ImageData>(resource));
+ if (image_data)
+ return image_data->GetNativeMemoryHandle();
+ return 0;
+}
+
const PPB_ImageData ppb_imagedata = {
&GetNativeImageDataFormat,
&Create,
@@ -77,6 +85,10 @@ const PPB_ImageData ppb_imagedata = {
&Unmap,
};
+const PPB_ImageDataTrusted ppb_imagedata_trusted = {
+ &GetNativeMemoryHandle2,
+};
+
} // namespace
ImageData::ImageData(PluginModule* module)
@@ -93,6 +105,11 @@ const PPB_ImageData* ImageData::GetInterface() {
return &ppb_imagedata;
}
+// static
+const PPB_ImageDataTrusted* ImageData::GetTrustedInterface() {
+ return &ppb_imagedata_trusted;
+}
+
bool ImageData::Init(PP_ImageDataFormat format,
int width, int height,
bool init_to_zero) {
@@ -143,6 +160,10 @@ void ImageData::Unmap() {
// in the future to save some memory.
}
+uint64 ImageData::GetNativeMemoryHandle() const {
+ return platform_image_->GetSharedMemoryHandle();
+}
+
const SkBitmap* ImageData::GetMappedBitmap() const {
if (!mapped_canvas_.get())
return NULL;
diff --git a/webkit/glue/plugins/pepper_image_data.h b/webkit/glue/plugins/pepper_image_data.h
index 7652b80..f2a110b 100644
--- a/webkit/glue/plugins/pepper_image_data.h
+++ b/webkit/glue/plugins/pepper_image_data.h
@@ -15,6 +15,7 @@ namespace skia {
class PlatformCanvas;
}
+struct PPB_ImageDataTrusted;
class SkBitmap;
namespace pepper {
@@ -37,12 +38,17 @@ class ImageData : public Resource {
// invalid or not mapped. See ImageDataAutoMapper below.
bool is_mapped() const { return !!mapped_canvas_.get(); }
+ PluginDelegate::PlatformImage2D* platform_image() const {
+ return platform_image_.get();
+ }
+
// Returns a pointer to the interface implementing PPB_ImageData that is
// exposed to the plugin.
static const PPB_ImageData* GetInterface();
+ static const PPB_ImageDataTrusted* GetTrustedInterface();
// Resource overrides.
- ImageData* AsImageData() { return this; }
+ virtual ImageData* AsImageData() { return this; }
// PPB_ImageData implementation.
bool Init(PP_ImageDataFormat format,
@@ -52,6 +58,9 @@ class ImageData : public Resource {
void* Map();
void Unmap();
+ // PPB_ImageDataTrusted implementation.
+ uint64 GetNativeMemoryHandle() const;
+
// The mapped bitmap and canvas will be NULL if the image is not mapped.
skia::PlatformCanvas* mapped_canvas() const { return mapped_canvas_.get(); }
const SkBitmap* GetMappedBitmap() const;
diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h
index ffc9d52..1bb4bed 100644
--- a/webkit/glue/plugins/pepper_plugin_delegate.h
+++ b/webkit/glue/plugins/pepper_plugin_delegate.h
@@ -5,15 +5,57 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_DELEGATE_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_DELEGATE_H_
+#include <string>
+
+#include "base/callback.h"
+#include "base/platform_file.h"
+#include "base/ref_counted.h"
+#include "base/shared_memory.h"
+#include "base/sync_socket.h"
+#include "base/task.h"
+#include "third_party/ppapi/c/pp_completion_callback.h"
+#include "third_party/ppapi/c/pp_errors.h"
#include "third_party/ppapi/c/pp_stdint.h"
+class AudioMessageFilter;
+
+namespace base {
+class MessageLoopProxy;
+class Time;
+}
+
+namespace fileapi {
+class FileSystemCallbackDispatcher;
+}
+
+namespace gfx {
+class Rect;
+}
+
+namespace gpu {
+class CommandBuffer;
+}
+
namespace skia {
class PlatformCanvas;
}
+namespace WebKit {
+class WebFileChooserCompletion;
+struct WebFileChooserParams;
+}
+
+struct PP_VideoCompressedDataBuffer_Dev;
+struct PP_VideoDecoderConfig_Dev;
+struct PP_VideoUncompressedDataBuffer_Dev;
+
+class TransportDIB;
+
namespace pepper {
+class FileIO;
class PluginInstance;
+class FullscreenContainer;
// Virtual interface that the browser implements to implement features for
// Pepper plugins.
@@ -32,6 +74,62 @@ class PluginDelegate {
// this image. This is used by NativeClient to send the image to the
// out-of-process plugin. Returns 0 on failure.
virtual intptr_t GetSharedMemoryHandle() const = 0;
+
+ virtual TransportDIB* GetTransportDIB() const = 0;
+ };
+
+ class PlatformContext3D {
+ public:
+ virtual ~PlatformContext3D() {}
+
+ // Initialize the context.
+ virtual bool Init(const gfx::Rect& position, const gfx::Rect& clip) = 0;
+
+ // This call will return the address of the command buffer object that is
+ // constructed in Initialize() and is valid until this context is destroyed.
+ virtual gpu::CommandBuffer* GetCommandBuffer() = 0;
+
+ // Sets the function to be called on repaint.
+ virtual void SetNotifyRepaintTask(Task* task) = 0;
+ };
+
+ class PlatformAudio {
+ public:
+ class Client {
+ protected:
+ virtual ~Client() {}
+
+ public:
+ // Called when the stream is created.
+ virtual void StreamCreated(base::SharedMemoryHandle shared_memory_handle,
+ size_t shared_memory_size,
+ base::SyncSocket::Handle socket) = 0;
+ };
+
+ virtual ~PlatformAudio() {}
+
+ // Starts the playback. Returns false on error or if called before the
+ // stream is created or after the stream is closed.
+ virtual bool StartPlayback() = 0;
+
+ // Stops the playback. Returns false on error or if called before the stream
+ // is created or after the stream is closed.
+ virtual bool StopPlayback() = 0;
+
+ // Closes the stream. Make sure to call this before the object is
+ // destructed.
+ virtual void ShutDown() = 0;
+ };
+
+ class PlatformVideoDecoder {
+ public:
+ virtual ~PlatformVideoDecoder() {}
+
+ // Returns false on failure.
+ virtual bool Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer) = 0;
+ virtual int32_t Flush(PP_CompletionCallback& callback) = 0;
+ virtual bool ReturnUncompressedDataBuffer(
+ PP_VideoUncompressedDataBuffer_Dev& buffer) = 0;
};
// Indicates that the given instance has been created.
@@ -45,13 +143,65 @@ class PluginDelegate {
// The caller will own the pointer returned from this.
virtual PlatformImage2D* CreateImage2D(int width, int height) = 0;
+ // The caller will own the pointer returned from this.
+ virtual PlatformContext3D* CreateContext3D() = 0;
+
+ // The caller will own the pointer returned from this.
+ virtual PlatformVideoDecoder* CreateVideoDecoder(
+ const PP_VideoDecoderConfig_Dev& decoder_config) = 0;
+
+ // The caller will own the pointer returned from this.
+ virtual PlatformAudio* CreateAudio(uint32_t sample_rate,
+ uint32_t sample_count,
+ PlatformAudio::Client* client) = 0;
+
// Notifies that the number of find results has changed.
virtual void DidChangeNumberOfFindResults(int identifier,
- int total,
- bool final_result) = 0;
+ int total,
+ bool final_result) = 0;
// Notifies that the index of the currently selected item has been updated.
virtual void DidChangeSelectedFindResult(int identifier, int index) = 0;
+
+ // Runs a file chooser.
+ virtual bool RunFileChooser(
+ const WebKit::WebFileChooserParams& params,
+ WebKit::WebFileChooserCompletion* chooser_completion) = 0;
+
+ // Sends an async IPC to open a file.
+ typedef Callback2<base::PlatformFileError, base::PlatformFile
+ >::Type AsyncOpenFileCallback;
+ virtual bool AsyncOpenFile(const FilePath& path,
+ int flags,
+ AsyncOpenFileCallback* callback) = 0;
+ virtual bool MakeDirectory(
+ const FilePath& path,
+ bool recursive,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) = 0;
+ virtual bool Query(const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) = 0;
+ virtual bool Touch(const FilePath& path,
+ const base::Time& last_access_time,
+ const base::Time& last_modified_time,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) = 0;
+ virtual bool Delete(const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) = 0;
+ virtual bool Rename(const FilePath& file_path,
+ const FilePath& new_file_path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) = 0;
+
+ // Returns a MessageLoopProxy instance associated with the message loop
+ // of the file thread in this renderer.
+ virtual scoped_refptr<base::MessageLoopProxy>
+ GetFileThreadMessageLoopProxy() = 0;
+
+ // Create a fullscreen container for a plugin instance. This effectively
+ // switches the plugin to fullscreen.
+ virtual FullscreenContainer* CreateFullscreenContainer(
+ PluginInstance* instance) = 0;
+
+ // Returns a string with the name of the default 8-bit char encoding.
+ virtual std::string GetDefaultEncoding() = 0;
};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc
index 6a7bf54..b4ccd89 100644
--- a/webkit/glue/plugins/pepper_plugin_instance.cc
+++ b/webkit/glue/plugins/pepper_plugin_instance.cc
@@ -22,17 +22,19 @@
#include "printing/units.h"
#include "skia/ext/vector_platform_device.h"
#include "skia/ext/platform_canvas.h"
+#include "third_party/ppapi/c/dev/ppb_find_dev.h"
+#include "third_party/ppapi/c/dev/ppb_fullscreen_dev.h"
+#include "third_party/ppapi/c/dev/ppp_find_dev.h"
+#include "third_party/ppapi/c/dev/ppp_zoom_dev.h"
+#include "third_party/ppapi/c/pp_input_event.h"
#include "third_party/ppapi/c/pp_instance.h"
-#include "third_party/ppapi/c/pp_event.h"
#include "third_party/ppapi/c/pp_rect.h"
#include "third_party/ppapi/c/pp_resource.h"
#include "third_party/ppapi/c/pp_var.h"
#include "third_party/ppapi/c/ppb_core.h"
-#include "third_party/ppapi/c/ppb_find.h"
#include "third_party/ppapi/c/ppb_instance.h"
-#include "third_party/ppapi/c/ppp_find.h"
#include "third_party/ppapi/c/ppp_instance.h"
-#include "third_party/ppapi/c/ppp_zoom.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/WebKit/chromium/public/WebElement.h"
@@ -41,8 +43,9 @@
#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
#include "webkit/glue/plugins/pepper_buffer.h"
-#include "webkit/glue/plugins/pepper_device_context_2d.h"
+#include "webkit/glue/plugins/pepper_graphics_2d.h"
#include "webkit/glue/plugins/pepper_event_conversion.h"
+#include "webkit/glue/plugins/pepper_fullscreen_container.h"
#include "webkit/glue/plugins/pepper_image_data.h"
#include "webkit/glue/plugins/pepper_plugin_delegate.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
@@ -50,6 +53,7 @@
#include "webkit/glue/plugins/pepper_url_loader.h"
#include "webkit/glue/plugins/pepper_var.h"
+using WebKit::WebBindings;
using WebKit::WebCanvas;
using WebKit::WebCursorInfo;
using WebKit::WebFrame;
@@ -146,11 +150,11 @@ PP_Var GetOwnerElementObject(PP_Instance instance_id) {
return instance->GetOwnerElementObject();
}
-bool BindGraphicsDeviceContext(PP_Instance instance_id, PP_Resource device_id) {
+bool BindGraphics(PP_Instance instance_id, PP_Resource device_id) {
PluginInstance* instance = PluginInstance::FromPPInstance(instance_id);
if (!instance)
return false;
- return instance->BindGraphicsDeviceContext(device_id);
+ return instance->BindGraphics(device_id);
}
bool IsFullFrame(PP_Instance instance_id) {
@@ -160,31 +164,21 @@ bool IsFullFrame(PP_Instance instance_id) {
return instance->full_frame();
}
-bool SetCursor(PP_Instance instance_id,
- PP_CursorType type,
- PP_Resource custom_image_id,
- const PP_Point* hot_spot) {
+PP_Var ExecuteScript(PP_Instance instance_id,
+ PP_Var script,
+ PP_Var* exception) {
PluginInstance* instance = PluginInstance::FromPPInstance(instance_id);
if (!instance)
- return false;
-
- scoped_refptr<ImageData> custom_image(
- Resource::GetAs<ImageData>(custom_image_id));
- if (custom_image.get()) {
- // TODO: implement custom cursors.
- NOTIMPLEMENTED();
- return false;
- }
-
- return instance->SetCursor(type);
+ return PP_MakeVoid();
+ return instance->ExecuteScript(script, exception);
}
const PPB_Instance ppb_instance = {
&GetWindowObject,
&GetOwnerElementObject,
- &BindGraphicsDeviceContext,
+ &BindGraphics,
&IsFullFrame,
- &SetCursor,
+ &ExecuteScript,
};
void NumberOfFindResultsChanged(PP_Instance instance_id,
@@ -210,11 +204,30 @@ void SelectedFindResultChanged(PP_Instance instance_id,
instance->find_identifier(), index);
}
-const PPB_Find ppb_find = {
+const PPB_Find_Dev ppb_find = {
&NumberOfFindResultsChanged,
&SelectedFindResultChanged,
};
+bool IsFullscreen(PP_Instance instance_id) {
+ PluginInstance* instance = PluginInstance::FromPPInstance(instance_id);
+ if (!instance)
+ return false;
+ return instance->IsFullscreen();
+}
+
+bool SetFullscreen(PP_Instance instance_id, bool fullscreen) {
+ PluginInstance* instance = PluginInstance::FromPPInstance(instance_id);
+ if (!instance)
+ return false;
+ return instance->SetFullscreen(fullscreen);
+}
+
+const PPB_Fullscreen_Dev ppb_fullscreen = {
+ &IsFullscreen,
+ &SetFullscreen,
+};
+
} // namespace
PluginInstance::PluginInstance(PluginDelegate* delegate,
@@ -225,6 +238,8 @@ PluginInstance::PluginInstance(PluginDelegate* delegate,
instance_interface_(instance_interface),
container_(NULL),
full_frame_(false),
+ has_webkit_focus_(false),
+ has_content_area_focus_(false),
find_identifier_(-1),
plugin_find_interface_(NULL),
plugin_zoom_interface_(NULL),
@@ -232,7 +247,10 @@ PluginInstance::PluginInstance(PluginDelegate* delegate,
num_pages_(0),
pdf_output_done_(false),
#endif // defined (OS_LINUX)
- plugin_print_interface_(NULL) {
+ plugin_print_interface_(NULL),
+ plugin_graphics_3d_interface_(NULL),
+ always_on_top_(false),
+ fullscreen_container_(NULL) {
memset(&current_print_settings_, 0, sizeof(current_print_settings_));
DCHECK(delegate);
module_->InstanceCreated(this);
@@ -255,10 +273,15 @@ PluginInstance* PluginInstance::FromPPInstance(PP_Instance instance) {
}
// static
-const PPB_Find* PluginInstance::GetFindInterface() {
+const PPB_Find_Dev* PluginInstance::GetFindInterface() {
return &ppb_find;
}
+// static
+const PPB_Fullscreen_Dev* PluginInstance::GetFullscreenInterface() {
+ return &ppb_fullscreen;
+}
+
PP_Instance PluginInstance::GetPPInstance() {
return reinterpret_cast<intptr_t>(this);
}
@@ -266,17 +289,24 @@ PP_Instance PluginInstance::GetPPInstance() {
void PluginInstance::Paint(WebCanvas* canvas,
const gfx::Rect& plugin_rect,
const gfx::Rect& paint_rect) {
- if (device_context_2d_)
- device_context_2d_->Paint(canvas, plugin_rect, paint_rect);
+ if (bound_graphics_2d_)
+ bound_graphics_2d_->Paint(canvas, plugin_rect, paint_rect);
}
void PluginInstance::InvalidateRect(const gfx::Rect& rect) {
- if (!container_ || position_.IsEmpty())
- return; // Nothing to do.
- if (rect.IsEmpty())
- container_->invalidate();
- else
- container_->invalidateRect(rect);
+ if (fullscreen_container_) {
+ if (rect.IsEmpty())
+ fullscreen_container_->Invalidate();
+ else
+ fullscreen_container_->InvalidateRect(rect);
+ } else {
+ if (!container_ || position_.IsEmpty())
+ return; // Nothing to do.
+ if (rect.IsEmpty())
+ container_->invalidate();
+ else
+ container_->invalidateRect(rect);
+ }
}
PP_Var PluginInstance::GetWindowObject() {
@@ -287,29 +317,28 @@ PP_Var PluginInstance::GetWindowObject() {
if (!frame)
return PP_MakeVoid();
- return NPObjectToPPVar(frame->windowObject());
+ return ObjectVar::NPObjectToPPVar(module(), frame->windowObject());
}
PP_Var PluginInstance::GetOwnerElementObject() {
if (!container_)
return PP_MakeVoid();
-
- return NPObjectToPPVar(container_->scriptableObjectForElement());
+ return ObjectVar::NPObjectToPPVar(module(),
+ container_->scriptableObjectForElement());
}
-bool PluginInstance::BindGraphicsDeviceContext(PP_Resource device_id) {
+bool PluginInstance::BindGraphics(PP_Resource device_id) {
if (!device_id) {
// Special-case clearing the current device.
- if (device_context_2d_) {
- device_context_2d_->BindToInstance(NULL);
- device_context_2d_ = NULL;
+ if (bound_graphics_2d_) {
+ bound_graphics_2d_->BindToInstance(NULL);
+ bound_graphics_2d_ = NULL;
InvalidateRect(gfx::Rect());
}
return true;
}
- scoped_refptr<DeviceContext2D> device_2d =
- Resource::GetAs<DeviceContext2D>(device_id);
+ scoped_refptr<Graphics2D> device_2d = Resource::GetAs<Graphics2D>(device_id);
if (device_2d) {
if (!device_2d->BindToInstance(this))
@@ -317,11 +346,11 @@ bool PluginInstance::BindGraphicsDeviceContext(PP_Resource device_id) {
// See http://crbug.com/49403: this can be further optimized by keeping the
// old device around and painting from it.
- if (device_context_2d_.get()) {
+ if (bound_graphics_2d_.get()) {
// Start the new image with the content of the old image until the plugin
// repaints.
const SkBitmap* old_backing_bitmap =
- device_context_2d_->image_data()->GetMappedBitmap();
+ bound_graphics_2d_->image_data()->GetMappedBitmap();
SkRect old_size = SkRect::MakeWH(
SkScalar(static_cast<float>(old_backing_bitmap->width())),
SkScalar(static_cast<float>(old_backing_bitmap->height())));
@@ -334,21 +363,63 @@ bool PluginInstance::BindGraphicsDeviceContext(PP_Resource device_id) {
canvas.drawARGB(255, 255, 255, 255);
}
- device_context_2d_ = device_2d;
+ bound_graphics_2d_ = device_2d;
// BindToInstance will have invalidated the plugin if necessary.
}
return true;
}
-bool PluginInstance::SetCursor(PP_CursorType type) {
+bool PluginInstance::SetCursor(PP_CursorType_Dev type) {
cursor_.reset(new WebCursorInfo(static_cast<WebCursorInfo::Type>(type)));
return true;
}
+PP_Var PluginInstance::ExecuteScript(PP_Var script, PP_Var* exception) {
+ TryCatch try_catch(module(), exception);
+ if (try_catch.has_exception())
+ return PP_MakeVoid();
+
+ // Convert the script into an inconvenient NPString object.
+ scoped_refptr<StringVar> script_string(StringVar::FromPPVar(script));
+ if (!script_string) {
+ try_catch.SetException("Script param to ExecuteScript must be a string.");
+ return PP_MakeVoid();
+ }
+ NPString np_script;
+ np_script.UTF8Characters = script_string->value().c_str();
+ np_script.UTF8Length = script_string->value().length();
+
+ // Get the current frame to pass to the evaluate function.
+ WebFrame* frame = container_->element().document().frame();
+ if (!frame) {
+ try_catch.SetException("No frame to execute script in.");
+ return PP_MakeVoid();
+ }
+
+ NPVariant result;
+ bool ok = WebBindings::evaluate(NULL, frame->windowObject(), &np_script,
+ &result);
+ if (!ok) {
+ // TODO(brettw) bug 54011: The TryCatch isn't working properly and
+ // doesn't actually catch this exception.
+ try_catch.SetException("Exception caught");
+ WebBindings::releaseVariantValue(&result);
+ return PP_MakeVoid();
+ }
+
+ PP_Var ret = Var::NPVariantToPPVar(module_, &result);
+ WebBindings::releaseVariantValue(&result);
+ return ret;
+}
+
void PluginInstance::Delete() {
instance_interface_->Delete(GetPPInstance());
+ if (fullscreen_container_) {
+ fullscreen_container_->Destroy();
+ fullscreen_container_ = NULL;
+ }
container_ = NULL;
}
@@ -382,11 +453,14 @@ bool PluginInstance::HandleDocumentLoad(URLLoader* loader) {
bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event,
WebCursorInfo* cursor_info) {
- scoped_ptr<PP_Event> pp_event(CreatePP_Event(event));
- if (!pp_event.get())
- return false;
+ std::vector<PP_InputEvent> pp_events;
+ CreatePPEvent(event, &pp_events);
+
+ // Each input event may generate more than one PP_InputEvent.
+ bool rv = false;
+ for (size_t i = 0; i < pp_events.size(); i++)
+ rv |= instance_interface_->HandleInputEvent(GetPPInstance(), &pp_events[i]);
- bool rv = instance_interface_->HandleEvent(GetPPInstance(), pp_event.get());
if (cursor_.get())
*cursor_info = *cursor_;
return rv;
@@ -415,19 +489,67 @@ void PluginInstance::ViewChanged(const gfx::Rect& position,
instance_interface_->ViewChanged(GetPPInstance(), &pp_position, &pp_clip);
}
+void PluginInstance::SetWebKitFocus(bool has_focus) {
+ if (has_webkit_focus_ == has_focus)
+ return;
+
+ bool old_plugin_focus = PluginHasFocus();
+ has_webkit_focus_ = has_focus;
+ if (PluginHasFocus() != old_plugin_focus)
+ instance_interface_->FocusChanged(GetPPInstance(), PluginHasFocus());
+}
+
+void PluginInstance::SetContentAreaFocus(bool has_focus) {
+ if (has_content_area_focus_ == has_focus)
+ return;
+
+ bool old_plugin_focus = PluginHasFocus();
+ has_content_area_focus_ = has_focus;
+ if (PluginHasFocus() != old_plugin_focus)
+ instance_interface_->FocusChanged(GetPPInstance(), PluginHasFocus());
+}
+
void PluginInstance::ViewInitiatedPaint() {
- if (device_context_2d_)
- device_context_2d_->ViewInitiatedPaint();
+ if (bound_graphics_2d_)
+ bound_graphics_2d_->ViewInitiatedPaint();
}
void PluginInstance::ViewFlushedPaint() {
- if (device_context_2d_)
- device_context_2d_->ViewFlushedPaint();
+ if (bound_graphics_2d_)
+ bound_graphics_2d_->ViewFlushedPaint();
+}
+
+bool PluginInstance::GetBitmapForOptimizedPluginPaint(
+ const gfx::Rect& paint_bounds,
+ TransportDIB** dib,
+ gfx::Rect* location,
+ gfx::Rect* clip) {
+ if (!always_on_top_)
+ return false;
+ if (!bound_graphics_2d_ || !bound_graphics_2d_->is_always_opaque())
+ return false;
+
+ // We specifically want to compare against the area covered by the backing
+ // store when seeing if we cover the given paint bounds, since the backing
+ // store could be smaller than the declared plugin area.
+ ImageData* image_data = bound_graphics_2d_->image_data();
+ gfx::Rect plugin_backing_store_rect(position_.origin(),
+ gfx::Size(image_data->width(),
+ image_data->height()));
+ gfx::Rect plugin_paint_rect = plugin_backing_store_rect.Intersect(clip_);
+ if (!plugin_paint_rect.Contains(paint_bounds))
+ return false;
+
+ *dib = image_data->platform_image()->GetTransportDIB();
+ *location = plugin_backing_store_rect;
+ *clip = clip_;
+ return true;
}
string16 PluginInstance::GetSelectedText(bool html) {
PP_Var rv = instance_interface_->GetSelectedText(GetPPInstance(), html);
- String* string = GetString(rv);
+ scoped_refptr<StringVar> string(StringVar::FromPPVar(rv));
+ Var::PluginReleasePPVar(rv); // Release the ref the plugin transfered to us.
if (!string)
return string16();
return UTF8ToUTF16(string->value());
@@ -466,8 +588,8 @@ void PluginInstance::StopFind() {
bool PluginInstance::LoadFindInterface() {
if (!plugin_find_interface_) {
plugin_find_interface_ =
- reinterpret_cast<const PPP_Find*>(module_->GetPluginInterface(
- PPP_FIND_INTERFACE));
+ reinterpret_cast<const PPP_Find_Dev*>(module_->GetPluginInterface(
+ PPP_FIND_DEV_INTERFACE));
}
return !!plugin_find_interface_;
@@ -476,24 +598,28 @@ bool PluginInstance::LoadFindInterface() {
bool PluginInstance::LoadZoomInterface() {
if (!plugin_zoom_interface_) {
plugin_zoom_interface_ =
- reinterpret_cast<const PPP_Zoom*>(module_->GetPluginInterface(
- PPP_ZOOM_INTERFACE));
+ reinterpret_cast<const PPP_Zoom_Dev*>(module_->GetPluginInterface(
+ PPP_ZOOM_DEV_INTERFACE));
}
return !!plugin_zoom_interface_;
}
+bool PluginInstance::PluginHasFocus() const {
+ return has_webkit_focus_ && has_content_area_focus_;
+}
+
bool PluginInstance::GetPreferredPrintOutputFormat(
- PP_PrintOutputFormat* format) {
+ PP_PrintOutputFormat_Dev* format) {
if (!plugin_print_interface_) {
plugin_print_interface_ =
- reinterpret_cast<const PPP_Printing*>(module_->GetPluginInterface(
- PPP_PRINTING_INTERFACE));
+ reinterpret_cast<const PPP_Printing_Dev*>(module_->GetPluginInterface(
+ PPP_PRINTING_DEV_INTERFACE));
}
if (!plugin_print_interface_)
return false;
uint32_t format_count = 0;
- PP_PrintOutputFormat* supported_formats =
+ PP_PrintOutputFormat_Dev* supported_formats =
plugin_print_interface_->QuerySupportedFormats(GetPPInstance(),
&format_count);
if (!supported_formats)
@@ -517,13 +643,13 @@ bool PluginInstance::GetPreferredPrintOutputFormat(
}
bool PluginInstance::SupportsPrintInterface() {
- PP_PrintOutputFormat format;
+ PP_PrintOutputFormat_Dev format;
return GetPreferredPrintOutputFormat(&format);
}
int PluginInstance::PrintBegin(const gfx::Rect& printable_area,
int printer_dpi) {
- PP_PrintOutputFormat format;
+ PP_PrintOutputFormat_Dev format;
if (!GetPreferredPrintOutputFormat(&format)) {
// PrintBegin should not have been called since SupportsPrintInterface
// would have returned false;
@@ -531,7 +657,7 @@ int PluginInstance::PrintBegin(const gfx::Rect& printable_area,
return 0;
}
- PP_PrintSettings print_settings;
+ PP_PrintSettings_Dev print_settings;
RectToPPRect(printable_area, &print_settings.printable_area);
print_settings.dpi = printer_dpi;
print_settings.orientation = PP_PRINTORIENTATION_NORMAL;
@@ -551,7 +677,7 @@ int PluginInstance::PrintBegin(const gfx::Rect& printable_area,
bool PluginInstance::PrintPage(int page_number, WebKit::WebCanvas* canvas) {
DCHECK(plugin_print_interface_);
- PP_PrintPageNumberRange page_range;
+ PP_PrintPageNumberRange_Dev page_range;
#if defined(OS_LINUX)
if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF) {
// On Linux we will try and output all pages as PDF in the first call to
@@ -592,13 +718,48 @@ void PluginInstance::PrintEnd() {
plugin_print_interface_->End(GetPPInstance());
memset(&current_print_settings_, 0, sizeof(current_print_settings_));
#if defined(OS_MACOSX)
- last_printed_page_ = SkBitmap();
+ last_printed_page_ = NULL;
#elif defined(OS_LINUX)
num_pages_ = 0;
pdf_output_done_ = false;
#endif // defined(OS_LINUX)
}
+void PluginInstance::Graphics3DContextLost() {
+ if (!plugin_graphics_3d_interface_) {
+ plugin_graphics_3d_interface_ =
+ reinterpret_cast<const PPP_Graphics3D_Dev*>(module_->GetPluginInterface(
+ PPP_GRAPHICS_3D_DEV_INTERFACE));
+ }
+ if (plugin_graphics_3d_interface_)
+ plugin_graphics_3d_interface_->Graphics3DContextLost(GetPPInstance());
+}
+
+bool PluginInstance::IsFullscreen() {
+ return fullscreen_container_ != NULL;
+}
+
+bool PluginInstance::SetFullscreen(bool fullscreen) {
+ bool is_fullscreen = (fullscreen_container_ != NULL);
+ if (fullscreen == is_fullscreen)
+ return true;
+ LOG(INFO) << "Setting fullscreen to " << (fullscreen ? "on" : "off");
+ if (fullscreen) {
+ fullscreen_container_ = delegate_->CreateFullscreenContainer(this);
+ } else {
+ fullscreen_container_->Destroy();
+ fullscreen_container_ = NULL;
+ // TODO(piman): currently the fullscreen container resizes the plugin to the
+ // fullscreen size so we need to reset the size here. Eventually it will
+ // transparently scale and this won't be necessary.
+ if (container_) {
+ container_->reportGeometry();
+ container_->invalidate();
+ }
+ }
+ return true;
+}
+
bool PluginInstance::PrintPDFOutput(PP_Resource print_output,
WebKit::WebCanvas* canvas) {
scoped_refptr<Buffer> buffer(Resource::GetAs<Buffer>(print_output));
@@ -730,7 +891,7 @@ bool PluginInstance::PrintRasterOutput(PP_Resource print_output,
DrawSkBitmapToCanvas(*bitmap, canvas, dest_rect_gfx,
current_print_settings_.printable_area.size.height);
// See comments in the header file.
- last_printed_page_ = *bitmap;
+ last_printed_page_ = image;
#else // defined(OS_MACOSX)
if (draw_to_canvas)
canvas->drawBitmapRect(*bitmap, &src_rect, dest_rect);
diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h
index 4528a99..4eb956f 100644
--- a/webkit/glue/plugins/pepper_plugin_instance.h
+++ b/webkit/glue/plugins/pepper_plugin_instance.h
@@ -13,21 +13,24 @@
#include "base/scoped_ptr.h"
#include "base/string16.h"
#include "gfx/rect.h"
-#include "third_party/ppapi/c/pp_cursor_type.h"
+#include "third_party/ppapi/c/dev/pp_cursor_type_dev.h"
+#include "third_party/ppapi/c/dev/ppp_graphics_3d_dev.h"
+#include "third_party/ppapi/c/dev/ppp_printing_dev.h"
#include "third_party/ppapi/c/pp_instance.h"
#include "third_party/ppapi/c/pp_resource.h"
-#include "third_party/ppapi/c/ppp_printing.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCanvas.h"
-typedef struct _pp_Var PP_Var;
-typedef struct _ppb_Instance PPB_Instance;
-typedef struct _ppb_Find PPB_Find;
-typedef struct _ppp_Find PPP_Find;
-typedef struct _ppp_Instance PPP_Instance;
-typedef struct _ppp_Zoom PPP_Zoom;
+struct PP_Var;
+struct PPB_Instance;
+struct PPB_Find_Dev;
+struct PPB_Fullscreen_Dev;
+struct PPP_Find_Dev;
+struct PPP_Instance;
+struct PPP_Zoom_Dev;
class SkBitmap;
+class TransportDIB;
namespace gfx {
class Rect;
@@ -41,10 +44,12 @@ class WebPluginContainer;
namespace pepper {
-class DeviceContext2D;
+class Graphics2D;
+class ImageData;
class PluginDelegate;
class PluginModule;
class URLLoader;
+class FullscreenContainer;
class PluginInstance : public base::RefCounted<PluginInstance> {
public:
@@ -60,7 +65,8 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
// Returns a pointer to the interface implementing PPB_Find that is
// exposed to the plugin.
- static const PPB_Find* GetFindInterface();
+ static const PPB_Find_Dev* GetFindInterface();
+ static const PPB_Fullscreen_Dev* GetFullscreenInterface();
PluginDelegate* delegate() const { return delegate_; }
PluginModule* module() const { return module_.get(); }
@@ -72,6 +78,8 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
int find_identifier() const { return find_identifier_; }
+ void set_always_on_top(bool on_top) { always_on_top_ = on_top; }
+
PP_Instance GetPPInstance();
// Paints the current backing store to the web page.
@@ -88,9 +96,10 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
// PPB_Instance implementation.
PP_Var GetWindowObject();
PP_Var GetOwnerElementObject();
- bool BindGraphicsDeviceContext(PP_Resource device_id);
+ bool BindGraphics(PP_Resource device_id);
bool full_frame() const { return full_frame_; }
- bool SetCursor(PP_CursorType type);
+ bool SetCursor(PP_CursorType_Dev type);
+ PP_Var ExecuteScript(PP_Var script, PP_Var* exception);
// PPP_Instance pass-through.
void Delete();
@@ -104,12 +113,26 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
PP_Var GetInstanceObject();
void ViewChanged(const gfx::Rect& position, const gfx::Rect& clip);
+ // Notifications about focus changes, see has_webkit_focus_ below.
+ void SetWebKitFocus(bool has_focus);
+ void SetContentAreaFocus(bool has_focus);
+
// Notifications that the view has rendered the page and that it has been
// flushed to the screen. These messages are used to send Flush callbacks to
// the plugin for DeviceContext2D.
void ViewInitiatedPaint();
void ViewFlushedPaint();
+ // If this plugin can be painted merely by copying the backing store to the
+ // screen, and the plugin bounds encloses the given paint bounds, returns
+ // true. In this case, the location, clipping, and ID of the backing store
+ // will be filled into the given output parameters.
+ bool GetBitmapForOptimizedPluginPaint(
+ const gfx::Rect& paint_bounds,
+ TransportDIB** dib,
+ gfx::Rect* dib_bounds,
+ gfx::Rect* clip);
+
string16 GetSelectedText(bool html);
void Zoom(float factor, bool text_only);
bool StartFind(const string16& search_text,
@@ -123,14 +146,24 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
bool PrintPage(int page_number, WebKit::WebCanvas* canvas);
void PrintEnd();
+ void Graphics3DContextLost();
+
+ // Implementation of PPB_Fullscreen_Dev.
+ bool IsFullscreen();
+ bool SetFullscreen(bool fullscreen);
+
private:
bool LoadFindInterface();
bool LoadZoomInterface();
+ // Determines if we think the plugin has focus, both content area and webkit
+ // (see has_webkit_focus_ below).
+ bool PluginHasFocus() const;
+
// Queries the plugin for supported print formats and sets |format| to the
// best format to use. Returns false if the plugin does not support any
// print format that we can handle (we can handle raster and PDF).
- bool GetPreferredPrintOutputFormat(PP_PrintOutputFormat* format);
+ bool GetPreferredPrintOutputFormat(PP_PrintOutputFormat_Dev* format);
bool PrintPDFOutput(PP_Resource print_output, WebKit::WebCanvas* canvas);
bool PrintRasterOutput(PP_Resource print_output, WebKit::WebCanvas* canvas);
#if defined(OS_WIN)
@@ -165,24 +198,31 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
// be (0, 0, w, h) regardless of scroll position.
gfx::Rect clip_;
+ // We track two types of focus, one from WebKit, which is the focus among
+ // all elements of the page, one one from the browser, which is whether the
+ // tab/window has focus. We tell the plugin it has focus only when both of
+ // these values are set to true.
+ bool has_webkit_focus_;
+ bool has_content_area_focus_;
+
// The current device context for painting in 2D.
- scoped_refptr<DeviceContext2D> device_context_2d_;
+ scoped_refptr<Graphics2D> bound_graphics_2d_;
// The id of the current find operation, or -1 if none is in process.
int find_identifier_;
// The plugin find and zoom interfaces.
- const PPP_Find* plugin_find_interface_;
- const PPP_Zoom* plugin_zoom_interface_;
+ const PPP_Find_Dev* plugin_find_interface_;
+ const PPP_Zoom_Dev* plugin_zoom_interface_;
// This is only valid between a successful PrintBegin call and a PrintEnd
// call.
- PP_PrintSettings current_print_settings_;
+ PP_PrintSettings_Dev current_print_settings_;
#if defined(OS_MACOSX)
// On the Mac, when we draw the bitmap to the PDFContext, it seems necessary
// to keep the pixels valid until CGContextEndPage is called. We use this
// variable to hold on to the pixels.
- SkBitmap last_printed_page_;
+ scoped_refptr<ImageData> last_printed_page_;
#elif defined(OS_LINUX)
// On Linux, we always send all pages from the renderer to the browser.
// So, if the plugin supports printPagesAsPDF we print the entire output
@@ -197,11 +237,21 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
#endif // defined(OS_LINUX)
// The plugin print interface.
- const PPP_Printing* plugin_print_interface_;
+ const PPP_Printing_Dev* plugin_print_interface_;
+
+ // The plugin 3D interface.
+ const PPP_Graphics3D_Dev* plugin_graphics_3d_interface_;
// Containes the cursor if it's set by the plugin.
scoped_ptr<WebKit::WebCursorInfo> cursor_;
+ // Set to true if this plugin thinks it will always be on top. This allows us
+ // to use a more optimized painting path in some cases.
+ bool always_on_top_;
+
+ // Plugin container for fullscreen mode. NULL if not in fullscreen mode.
+ FullscreenContainer* fullscreen_container_;
+
DISALLOW_COPY_AND_ASSIGN(PluginInstance);
};
diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc
index 8ffd78b..251023f 100644
--- a/webkit/glue/plugins/pepper_plugin_module.cc
+++ b/webkit/glue/plugins/pepper_plugin_module.cc
@@ -12,46 +12,71 @@
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "base/time.h"
-#include "third_party/ppapi/c/ppb_buffer.h"
+#include "third_party/ppapi/c/dev/ppb_buffer_dev.h"
+#include "third_party/ppapi/c/dev/ppb_char_set_dev.h"
+#include "third_party/ppapi/c/dev/ppb_cursor_control_dev.h"
+#include "third_party/ppapi/c/dev/ppb_directory_reader_dev.h"
+#include "third_party/ppapi/c/dev/ppb_file_io_dev.h"
+#include "third_party/ppapi/c/dev/ppb_file_io_trusted_dev.h"
+#include "third_party/ppapi/c/dev/ppb_file_system_dev.h"
+#include "third_party/ppapi/c/dev/ppb_find_dev.h"
+#include "third_party/ppapi/c/dev/ppb_font_dev.h"
+#include "third_party/ppapi/c/dev/ppb_fullscreen_dev.h"
+#include "third_party/ppapi/c/dev/ppb_graphics_3d_dev.h"
+#include "third_party/ppapi/c/dev/ppb_opengles_dev.h"
+#include "third_party/ppapi/c/dev/ppb_scrollbar_dev.h"
+#include "third_party/ppapi/c/dev/ppb_testing_dev.h"
+#include "third_party/ppapi/c/dev/ppb_transport_dev.h"
+#include "third_party/ppapi/c/dev/ppb_url_loader_dev.h"
+#include "third_party/ppapi/c/dev/ppb_url_loader_trusted_dev.h"
+#include "third_party/ppapi/c/dev/ppb_url_request_info_dev.h"
+#include "third_party/ppapi/c/dev/ppb_url_response_info_dev.h"
+#include "third_party/ppapi/c/dev/ppb_url_util_dev.h"
+#include "third_party/ppapi/c/dev/ppb_video_decoder_dev.h"
+#include "third_party/ppapi/c/dev/ppb_widget_dev.h"
+#include "third_party/ppapi/c/trusted/ppb_image_data_trusted.h"
+#include "third_party/ppapi/c/pp_module.h"
+#include "third_party/ppapi/c/pp_resource.h"
+#include "third_party/ppapi/c/pp_var.h"
#include "third_party/ppapi/c/ppb_core.h"
-#include "third_party/ppapi/c/ppb_device_context_2d.h"
-#include "third_party/ppapi/c/ppb_file_io.h"
-#include "third_party/ppapi/c/ppb_file_io_trusted.h"
-#include "third_party/ppapi/c/ppb_file_system.h"
+#include "third_party/ppapi/c/ppb_graphics_2d.h"
#include "third_party/ppapi/c/ppb_image_data.h"
#include "third_party/ppapi/c/ppb_instance.h"
-#include "third_party/ppapi/c/ppb_find.h"
-#include "third_party/ppapi/c/ppb_font.h"
-#include "third_party/ppapi/c/ppb_scrollbar.h"
-#include "third_party/ppapi/c/ppb_testing.h"
-#include "third_party/ppapi/c/ppb_url_loader.h"
-#include "third_party/ppapi/c/ppb_url_request_info.h"
-#include "third_party/ppapi/c/ppb_url_response_info.h"
#include "third_party/ppapi/c/ppb_var.h"
-#include "third_party/ppapi/c/ppb_widget.h"
#include "third_party/ppapi/c/ppp.h"
#include "third_party/ppapi/c/ppp_instance.h"
-#include "third_party/ppapi/c/pp_module.h"
-#include "third_party/ppapi/c/pp_resource.h"
-#include "third_party/ppapi/c/pp_var.h"
+#include "webkit/glue/plugins/pepper_audio.h"
#include "webkit/glue/plugins/pepper_buffer.h"
-#include "webkit/glue/plugins/pepper_device_context_2d.h"
+#include "webkit/glue/plugins/pepper_char_set.h"
+#include "webkit/glue/plugins/pepper_cursor_control.h"
#include "webkit/glue/plugins/pepper_directory_reader.h"
+#include "webkit/glue/plugins/pepper_file_chooser.h"
#include "webkit/glue/plugins/pepper_file_io.h"
#include "webkit/glue/plugins/pepper_file_ref.h"
#include "webkit/glue/plugins/pepper_file_system.h"
#include "webkit/glue/plugins/pepper_font.h"
+#include "webkit/glue/plugins/pepper_graphics_2d.h"
#include "webkit/glue/plugins/pepper_image_data.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
+#include "webkit/glue/plugins/pepper_plugin_object.h"
#include "webkit/glue/plugins/pepper_private.h"
+#include "webkit/glue/plugins/pepper_private2.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"
#include "webkit/glue/plugins/pepper_scrollbar.h"
+#include "webkit/glue/plugins/pepper_transport.h"
#include "webkit/glue/plugins/pepper_url_loader.h"
#include "webkit/glue/plugins/pepper_url_request_info.h"
#include "webkit/glue/plugins/pepper_url_response_info.h"
+#include "webkit/glue/plugins/pepper_url_util.h"
#include "webkit/glue/plugins/pepper_var.h"
+#include "webkit/glue/plugins/pepper_video_decoder.h"
#include "webkit/glue/plugins/pepper_widget.h"
#include "webkit/glue/plugins/ppb_private.h"
+#include "webkit/glue/plugins/ppb_private2.h"
+
+#ifdef ENABLE_GPU
+#include "webkit/glue/plugins/pepper_graphics_3d.h"
+#endif // ENABLE_GPU
namespace pepper {
@@ -107,13 +132,18 @@ void CallOnMainThread(int delay_in_msec,
delay_in_msec);
}
+bool IsMainThread() {
+ return GetMainThreadMessageLoop()->BelongsToCurrentThread();
+}
+
const PPB_Core core_interface = {
&AddRefResource,
&ReleaseResource,
&MemAlloc,
&MemFree,
&GetTime,
- &CallOnMainThread
+ &CallOnMainThread,
+ &IsMainThread
};
// PPB_Testing -----------------------------------------------------------------
@@ -121,8 +151,8 @@ const PPB_Core core_interface = {
bool ReadImageData(PP_Resource device_context_2d,
PP_Resource image,
const PP_Point* top_left) {
- scoped_refptr<DeviceContext2D> context(
- Resource::GetAs<DeviceContext2D>(device_context_2d));
+ scoped_refptr<Graphics2D> context(
+ Resource::GetAs<Graphics2D>(device_context_2d));
if (!context.get())
return false;
return context->ReadImageData(image, top_left);
@@ -136,13 +166,37 @@ void RunMessageLoop() {
}
void QuitMessageLoop() {
- MessageLoop::current()->Quit();
+ MessageLoop::current()->QuitNow();
+}
+
+uint32_t GetLiveObjectCount(PP_Module module_id) {
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return static_cast<uint32_t>(-1);
+ return ResourceTracker::Get()->GetLiveObjectsForModule(module);
+}
+
+PP_Resource GetInaccessibleFileRef(PP_Module module_id) {
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return static_cast<uint32_t>(-1);
+ return FileRef::GetInaccessibleFileRef(module)->GetReference();
+}
+
+PP_Resource GetNonexistentFileRef(PP_Module module_id) {
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return static_cast<uint32_t>(-1);
+ return FileRef::GetNonexistentFileRef(module)->GetReference();
}
-const PPB_Testing testing_interface = {
+const PPB_Testing_Dev testing_interface = {
&ReadImageData,
&RunMessageLoop,
&QuitMessageLoop,
+ &GetLiveObjectCount,
+ &GetInaccessibleFileRef,
+ &GetNonexistentFileRef
};
// GetInterface ----------------------------------------------------------------
@@ -151,46 +205,78 @@ const void* GetInterface(const char* name) {
if (strcmp(name, PPB_CORE_INTERFACE) == 0)
return &core_interface;
if (strcmp(name, PPB_VAR_INTERFACE) == 0)
- return GetVarInterface();
+ return Var::GetInterface();
if (strcmp(name, PPB_INSTANCE_INTERFACE) == 0)
return PluginInstance::GetInterface();
if (strcmp(name, PPB_IMAGEDATA_INTERFACE) == 0)
return ImageData::GetInterface();
- if (strcmp(name, PPB_DEVICECONTEXT2D_INTERFACE) == 0)
- return DeviceContext2D::GetInterface();
- if (strcmp(name, PPB_URLLOADER_INTERFACE) == 0)
+ if (strcmp(name, PPB_IMAGEDATA_TRUSTED_INTERFACE) == 0)
+ return ImageData::GetTrustedInterface();
+ if (strcmp(name, PPB_AUDIO_CONFIG_DEV_INTERFACE) == 0)
+ return AudioConfig::GetInterface();
+ if (strcmp(name, PPB_AUDIO_DEV_INTERFACE) == 0)
+ return Audio::GetInterface();
+ if (strcmp(name, PPB_AUDIO_TRUSTED_DEV_INTERFACE) == 0)
+ return Audio::GetTrustedInterface();
+ if (strcmp(name, PPB_GRAPHICS_2D_INTERFACE) == 0)
+ return Graphics2D::GetInterface();
+#ifdef ENABLE_GPU
+ if (strcmp(name, PPB_GRAPHICS_3D_DEV_INTERFACE) == 0)
+ return Graphics3D::GetInterface();
+ if (strcmp(name, PPB_OPENGLES_DEV_INTERFACE) == 0)
+ return Graphics3D::GetOpenGLESInterface();
+#endif // ENABLE_GPU
+ if (strcmp(name, PPB_TRANSPORT_DEV_INTERFACE) == 0)
+ return Transport::GetInterface();
+ if (strcmp(name, PPB_URLLOADER_DEV_INTERFACE) == 0)
return URLLoader::GetInterface();
- if (strcmp(name, PPB_URLREQUESTINFO_INTERFACE) == 0)
+ if (strcmp(name, PPB_URLLOADERTRUSTED_DEV_INTERFACE) == 0)
+ return URLLoader::GetTrustedInterface();
+ if (strcmp(name, PPB_URLREQUESTINFO_DEV_INTERFACE) == 0)
return URLRequestInfo::GetInterface();
- if (strcmp(name, PPB_URLRESPONSEINFO_INTERFACE) == 0)
+ if (strcmp(name, PPB_URLRESPONSEINFO_DEV_INTERFACE) == 0)
return URLResponseInfo::GetInterface();
- if (strcmp(name, PPB_BUFFER_INTERFACE) == 0)
+ if (strcmp(name, PPB_BUFFER_DEV_INTERFACE) == 0)
return Buffer::GetInterface();
- if (strcmp(name, PPB_FILEREF_INTERFACE) == 0)
+ if (strcmp(name, PPB_FILEREF_DEV_INTERFACE) == 0)
return FileRef::GetInterface();
- if (strcmp(name, PPB_FILEIO_INTERFACE) == 0)
+ if (strcmp(name, PPB_FILEIO_DEV_INTERFACE) == 0)
return FileIO::GetInterface();
- if (strcmp(name, PPB_FILEIOTRUSTED_INTERFACE) == 0)
+ if (strcmp(name, PPB_FILEIOTRUSTED_DEV_INTERFACE) == 0)
return FileIO::GetTrustedInterface();
- if (strcmp(name, PPB_FILESYSTEM_INTERFACE) == 0)
+ if (strcmp(name, PPB_FILESYSTEM_DEV_INTERFACE) == 0)
return FileSystem::GetInterface();
- if (strcmp(name, PPB_DIRECTORYREADER_INTERFACE) == 0)
+ if (strcmp(name, PPB_DIRECTORYREADER_DEV_INTERFACE) == 0)
return DirectoryReader::GetInterface();
- if (strcmp(name, PPB_WIDGET_INTERFACE) == 0)
+ if (strcmp(name, PPB_WIDGET_DEV_INTERFACE) == 0)
return Widget::GetInterface();
- if (strcmp(name, PPB_SCROLLBAR_INTERFACE) == 0)
+ if (strcmp(name, PPB_SCROLLBAR_DEV_INTERFACE) == 0)
return Scrollbar::GetInterface();
- if (strcmp(name, PPB_FONT_INTERFACE) == 0)
+ if (strcmp(name, PPB_FONT_DEV_INTERFACE) == 0)
return Font::GetInterface();
- if (strcmp(name, PPB_FIND_INTERFACE) == 0)
+ if (strcmp(name, PPB_FIND_DEV_INTERFACE) == 0)
return PluginInstance::GetFindInterface();
+ if (strcmp(name, PPB_FULLSCREEN_DEV_INTERFACE) == 0)
+ return PluginInstance::GetFullscreenInterface();
+ if (strcmp(name, PPB_URLUTIL_DEV_INTERFACE) == 0)
+ return UrlUtil::GetInterface();
if (strcmp(name, PPB_PRIVATE_INTERFACE) == 0)
return Private::GetInterface();
+ if (strcmp(name, PPB_PRIVATE2_INTERFACE) == 0)
+ return Private2::GetInterface();
+ if (strcmp(name, PPB_FILECHOOSER_DEV_INTERFACE) == 0)
+ return FileChooser::GetInterface();
+ if (strcmp(name, PPB_VIDEODECODER_DEV_INTERFACE) == 0)
+ return VideoDecoder::GetInterface();
+ if (strcmp(name, PPB_CHAR_SET_DEV_INTERFACE) == 0)
+ return CharSet::GetInterface();
+ if (strcmp(name, PPB_CURSOR_CONTROL_DEV_INTERFACE) == 0)
+ return GetCursorControlInterface();
// Only support the testing interface when the command line switch is
// specified. This allows us to prevent people from (ab)using this interface
// in production code.
- if (strcmp(name, PPB_TESTING_INTERFACE) == 0) {
+ if (strcmp(name, PPB_TESTING_DEV_INTERFACE) == 0) {
if (CommandLine::ForCurrentProcess()->HasSwitch("enable-pepper-testing"))
return &testing_interface;
}
@@ -207,6 +293,17 @@ PluginModule::PluginModule()
}
PluginModule::~PluginModule() {
+ // Free all the plugin objects. This will automatically clear the back-
+ // pointer from the NPObject so WebKit can't call into the plugin any more.
+ //
+ // Swap out the set so we can delete from it (the objects will try to
+ // unregister themselves inside the delete call).
+ PluginObjectSet plugin_object_copy;
+ live_plugin_objects_.swap(plugin_object_copy);
+ for (PluginObjectSet::iterator i = live_plugin_objects_.begin();
+ i != live_plugin_objects_.end(); ++i)
+ delete *i;
+
// When the module is being deleted, there should be no more instances still
// holding a reference to us.
DCHECK(instances_.empty());
@@ -359,4 +456,44 @@ void PluginModule::InstanceDeleted(PluginInstance* instance) {
instances_.erase(instance);
}
+void PluginModule::AddNPObjectVar(ObjectVar* object_var) {
+ DCHECK(np_object_to_object_var_.find(object_var->np_object()) ==
+ np_object_to_object_var_.end()) << "ObjectVar already in map";
+ np_object_to_object_var_[object_var->np_object()] = object_var;
+}
+
+void PluginModule::RemoveNPObjectVar(ObjectVar* object_var) {
+ NPObjectToObjectVarMap::iterator found =
+ np_object_to_object_var_.find(object_var->np_object());
+ if (found == np_object_to_object_var_.end()) {
+ NOTREACHED() << "ObjectVar not registered.";
+ return;
+ }
+ if (found->second != object_var) {
+ NOTREACHED() << "ObjectVar doesn't match.";
+ return;
+ }
+ np_object_to_object_var_.erase(found);
+}
+
+ObjectVar* PluginModule::ObjectVarForNPObject(NPObject* np_object) const {
+ NPObjectToObjectVarMap::const_iterator found =
+ np_object_to_object_var_.find(np_object);
+ if (found == np_object_to_object_var_.end())
+ return NULL;
+ return found->second;
+}
+
+void PluginModule::AddPluginObject(PluginObject* plugin_object) {
+ DCHECK(live_plugin_objects_.find(plugin_object) ==
+ live_plugin_objects_.end());
+ live_plugin_objects_.insert(plugin_object);
+}
+
+void PluginModule::RemovePluginObject(PluginObject* plugin_object) {
+ // Don't actually verify that the object is in the set since during module
+ // deletion we'll be in the process of freeing them.
+ live_plugin_objects_.erase(plugin_object);
+}
+
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_plugin_module.h b/webkit/glue/plugins/pepper_plugin_module.h
index 6bfeccf..a560c56 100644
--- a/webkit/glue/plugins/pepper_plugin_module.h
+++ b/webkit/glue/plugins/pepper_plugin_module.h
@@ -5,23 +5,30 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_MODULE_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_MODULE_H_
+#include <map>
#include <set>
#include "base/basictypes.h"
-#include "base/file_path.h"
#include "base/native_library.h"
#include "base/ref_counted.h"
+#include "base/weak_ptr.h"
#include "third_party/ppapi/c/pp_module.h"
#include "third_party/ppapi/c/ppb.h"
-typedef struct _ppb_Core PPB_Core;
+class FilePath;
+typedef struct NPObject NPObject;
+struct PPB_Core;
+typedef void* NPIdentifier;
namespace pepper {
+class ObjectVar;
class PluginDelegate;
class PluginInstance;
+class PluginObject;
-class PluginModule : public base::RefCounted<PluginModule> {
+class PluginModule : public base::RefCounted<PluginModule>,
+ public base::SupportsWeakPtr<PluginModule> {
public:
typedef const void* (*PPP_GetInterfaceFunc)(const char*);
typedef int (*PPP_InitializeModuleFunc)(PP_Module, PPB_GetInterface);
@@ -69,6 +76,22 @@ class PluginModule : public base::RefCounted<PluginModule> {
void InstanceCreated(PluginInstance* instance);
void InstanceDeleted(PluginInstance* instance);
+ // Tracks all live ObjectVar. This is so we can map between PluginModule +
+ // NPObject and get the ObjectVar corresponding to it. This Add/Remove
+ // function should be called by the ObjectVar when it is created and
+ // destroyed.
+ void AddNPObjectVar(ObjectVar* object_var);
+ void RemoveNPObjectVar(ObjectVar* object_var);
+
+ // Looks up a previously registered ObjectVar for the given NPObject and
+ // module. Returns NULL if there is no ObjectVar corresponding to the given
+ // NPObject for the given module. See AddNPObjectVar above.
+ ObjectVar* ObjectVarForNPObject(NPObject* np_object) const;
+
+ // Tracks all live PluginObjects.
+ void AddPluginObject(PluginObject* plugin_object);
+ void RemovePluginObject(PluginObject* plugin_object);
+
private:
PluginModule();
@@ -94,6 +117,14 @@ class PluginModule : public base::RefCounted<PluginModule> {
typedef std::set<PluginInstance*> PluginInstanceSet;
PluginInstanceSet instances_;
+ // Tracks all live ObjectVars used by this module so we can map NPObjects to
+ // the corresponding object. These are non-owning references.
+ typedef std::map<NPObject*, ObjectVar*> NPObjectToObjectVarMap;;
+ NPObjectToObjectVarMap np_object_to_object_var_;
+
+ typedef std::set<PluginObject*> PluginObjectSet;
+ PluginObjectSet live_plugin_objects_;
+
DISALLOW_COPY_AND_ASSIGN(PluginModule);
};
diff --git a/webkit/glue/plugins/pepper_private.cc b/webkit/glue/plugins/pepper_private.cc
index 8d5182f..e35006b 100644
--- a/webkit/glue/plugins/pepper_private.cc
+++ b/webkit/glue/plugins/pepper_private.cc
@@ -6,26 +6,167 @@
#include "webkit/glue/plugins/pepper_private.h"
+#include "app/resource_bundle.h"
#include "base/utf_string_conversions.h"
+#include "grit/webkit_resources.h"
#include "grit/webkit_strings.h"
+#include "skia/ext/platform_canvas.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "webkit/glue/webkit_glue.h"
+#include "webkit/glue/plugins/pepper_image_data.h"
+#include "webkit/glue/plugins/pepper_plugin_module.h"
#include "webkit/glue/plugins/pepper_var.h"
#include "webkit/glue/plugins/ppb_private.h"
namespace pepper {
+#if defined(OS_LINUX)
+class PrivateFontFile : public Resource {
+ public:
+ PrivateFontFile(PluginModule* module, int fd) : Resource(module), fd_(fd) {}
+ virtual ~PrivateFontFile() {}
+
+ // Resource overrides.
+ PrivateFontFile* AsPrivateFontFile() { return this; }
+
+ bool GetFontTable(uint32_t table,
+ void* output,
+ uint32_t* output_length);
+
+ private:
+ int fd_;
+};
+#endif
+
namespace {
-PP_Var GetLocalizedString(PP_ResourceString string_id) {
+struct ResourceImageInfo {
+ PP_ResourceImage pp_id;
+ int res_id;
+};
+
+static const ResourceImageInfo kResourceImageMap[] = {
+ { PP_RESOURCEIMAGE_PDF_BUTTON_FTH, IDR_PDF_BUTTON_FTH },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_FTH_HOVER, IDR_PDF_BUTTON_FTH_HOVER },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_FTH_PRESSED, IDR_PDF_BUTTON_FTH_PRESSED },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_FTW, IDR_PDF_BUTTON_FTW },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER, IDR_PDF_BUTTON_FTW_HOVER },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED, IDR_PDF_BUTTON_FTW_PRESSED },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN, IDR_PDF_BUTTON_ZOOMIN },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER, IDR_PDF_BUTTON_ZOOMIN_HOVER },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED, IDR_PDF_BUTTON_ZOOMIN_PRESSED },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT, IDR_PDF_BUTTON_ZOOMOUT },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER, IDR_PDF_BUTTON_ZOOMOUT_HOVER },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED,
+ IDR_PDF_BUTTON_ZOOMOUT_PRESSED },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0, IDR_PDF_THUMBNAIL_0 },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1, IDR_PDF_THUMBNAIL_1 },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2, IDR_PDF_THUMBNAIL_2 },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3, IDR_PDF_THUMBNAIL_3 },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4, IDR_PDF_THUMBNAIL_4 },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5, IDR_PDF_THUMBNAIL_5 },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6, IDR_PDF_THUMBNAIL_6 },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7, IDR_PDF_THUMBNAIL_7 },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8, IDR_PDF_THUMBNAIL_8 },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9, IDR_PDF_THUMBNAIL_9 },
+ { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND,
+ IDR_PDF_THUMBNAIL_NUM_BACKGROUND },
+};
+
+PP_Var GetLocalizedString(PP_Module module_id, PP_ResourceString string_id) {
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return PP_MakeVoid();
+
std::string rv;
if (string_id == PP_RESOURCESTRING_PDFGETPASSWORD)
rv = UTF16ToUTF8(webkit_glue::GetLocalizedString(IDS_PDF_NEED_PASSWORD));
- return StringToPPVar(rv);
+ return StringVar::StringToPPVar(module, rv);
+}
+
+PP_Resource GetResourceImage(PP_Module module_id, PP_ResourceImage image_id) {
+ int res_id = 0;
+ for (size_t i = 0; i < arraysize(kResourceImageMap); ++i) {
+ if (kResourceImageMap[i].pp_id == image_id) {
+ res_id = kResourceImageMap[i].res_id;
+ break;
+ }
+ }
+ if (res_id == 0)
+ return 0;
+
+ SkBitmap* res_bitmap =
+ ResourceBundle::GetSharedInstance().GetBitmapNamed(res_id);
+
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return 0;
+ scoped_refptr<pepper::ImageData> image_data(new pepper::ImageData(module));
+ if (!image_data->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ res_bitmap->width(), res_bitmap->height(), false)) {
+ return 0;
+ }
+
+ ImageDataAutoMapper mapper(image_data);
+ if (!mapper.is_valid())
+ return 0;
+
+ skia::PlatformCanvas* canvas = image_data->mapped_canvas();
+ SkBitmap& ret_bitmap =
+ const_cast<SkBitmap&>(canvas->getTopPlatformDevice().accessBitmap(true));
+ if (!res_bitmap->copyTo(&ret_bitmap, SkBitmap::kARGB_8888_Config, NULL)) {
+ return 0;
+ }
+
+ return image_data->GetReference();
+}
+
+PP_Resource GetFontFileWithFallback(
+ PP_Module module_id,
+ const PP_PrivateFontFileDescription* description) {
+#if defined(OS_LINUX)
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return 0;
+
+ int fd = webkit_glue::MatchFontWithFallback(description->face,
+ description->weight >= 700,
+ description->italic,
+ description->charset);
+ if (fd == -1)
+ return 0;
+
+ scoped_refptr<PrivateFontFile> font(new PrivateFontFile(module, fd));
+
+ return font->GetReference();
+#else
+ // For trusted pepper plugins, this is only needed in Linux since font loading
+ // on Windows and Mac works through the renderer sandbox.
+ return 0;
+#endif
+}
+
+bool GetFontTableForPrivateFontFile(PP_Resource font_file,
+ uint32_t table,
+ void* output,
+ uint32_t* output_length) {
+#if defined(OS_LINUX)
+ scoped_refptr<PrivateFontFile> font(
+ Resource::GetAs<PrivateFontFile>(font_file));
+ if (!font.get())
+ return false;
+ return font->GetFontTable(table, output, output_length);
+#else
+ return false;
+#endif
}
const PPB_Private ppb_private = {
&GetLocalizedString,
+ &GetResourceImage,
+ &GetFontFileWithFallback,
+ &GetFontTableForPrivateFontFile,
};
} // namespace
@@ -35,4 +176,16 @@ const PPB_Private* Private::GetInterface() {
return &ppb_private;
}
+#if defined(OS_LINUX)
+bool PrivateFontFile::GetFontTable(uint32_t table,
+ void* output,
+ uint32_t* output_length) {
+ size_t temp_size = static_cast<size_t>(*output_length);
+ bool rv = webkit_glue::GetFontTable(
+ fd_, table, static_cast<uint8_t*>(output), &temp_size);
+ *output_length = static_cast<uint32_t>(temp_size);
+ return rv;
+}
+#endif
+
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_private.h b/webkit/glue/plugins/pepper_private.h
index fda75a7..06016f0 100644
--- a/webkit/glue/plugins/pepper_private.h
+++ b/webkit/glue/plugins/pepper_private.h
@@ -7,7 +7,7 @@
#include "webkit/glue/plugins/pepper_resource.h"
-typedef struct _ppb_Private PPB_Private;
+struct PPB_Private;
namespace pepper {
diff --git a/webkit/glue/plugins/pepper_resource.cc b/webkit/glue/plugins/pepper_resource.cc
index c568183..cf7a7fe 100644
--- a/webkit/glue/plugins/pepper_resource.cc
+++ b/webkit/glue/plugins/pepper_resource.cc
@@ -4,10 +4,18 @@
#include "webkit/glue/plugins/pepper_resource.h"
+#include "base/logging.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"
namespace pepper {
+Resource::Resource(PluginModule* module)
+ : resource_id_(0), module_(module) {
+}
+
+Resource::~Resource() {
+}
+
PP_Resource Resource::GetReference() {
ResourceTracker *tracker = ResourceTracker::Get();
if (resource_id_)
@@ -16,4 +24,10 @@ PP_Resource Resource::GetReference() {
resource_id_ = tracker->AddResource(this);
return resource_id_;
}
+
+void Resource::StoppedTracking() {
+ DCHECK(resource_id_ != 0);
+ resource_id_ = 0;
+}
+
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_resource.h b/webkit/glue/plugins/pepper_resource.h
index 417a06b..cab6f32 100644
--- a/webkit/glue/plugins/pepper_resource.h
+++ b/webkit/glue/plugins/pepper_resource.h
@@ -5,7 +5,6 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_
-#include "base/logging.h"
#include "base/basictypes.h"
#include "base/ref_counted.h"
#include "third_party/ppapi/c/pp_resource.h"
@@ -14,24 +13,33 @@
namespace pepper {
class Buffer;
-class DeviceContext2D;
+class Audio;
+class AudioConfig;
class DirectoryReader;
class FileChooser;
class FileIO;
class FileRef;
class Font;
+class Graphics2D;
+class Graphics3D;
class ImageData;
+class ObjectVar;
class PluginModule;
+class PrivateFontFile;
class Scrollbar;
+class StringVar;
+class Transport;
class URLLoader;
class URLRequestInfo;
class URLResponseInfo;
+class Var;
+class VideoDecoder;
class Widget;
class Resource : public base::RefCountedThreadSafe<Resource> {
public:
- explicit Resource(PluginModule* module) : resource_id_(0), module_(module) {}
- virtual ~Resource() {}
+ explicit Resource(PluginModule* module);
+ virtual ~Resource();
// Returns NULL if the resource is invalid or is a different type.
template<typename T>
@@ -72,18 +80,27 @@ class Resource : public base::RefCountedThreadSafe<Resource> {
// Type-specific getters for individual resource types. These will return
// NULL if the resource does not match the specified type. Used by the Cast()
// function.
+ virtual Audio* AsAudio() { return NULL; }
+ virtual AudioConfig* AsAudioConfig() { return NULL; }
virtual Buffer* AsBuffer() { return NULL; }
- virtual DeviceContext2D* AsDeviceContext2D() { return NULL; }
virtual DirectoryReader* AsDirectoryReader() { return NULL; }
virtual FileChooser* AsFileChooser() { return NULL; }
virtual FileIO* AsFileIO() { return NULL; }
virtual FileRef* AsFileRef() { return NULL; }
virtual Font* AsFont() { return NULL; }
+ virtual Graphics2D* AsGraphics2D() { return NULL; }
+ virtual Graphics3D* AsGraphics3D() { return NULL; }
virtual ImageData* AsImageData() { return NULL; }
+ virtual ObjectVar* AsObjectVar() { return NULL; }
+ virtual PrivateFontFile* AsPrivateFontFile() { return NULL; }
virtual Scrollbar* AsScrollbar() { return NULL; }
+ virtual StringVar* AsStringVar() { return NULL; }
+ virtual Transport* AsTransport() { return NULL; }
virtual URLLoader* AsURLLoader() { return NULL; }
virtual URLRequestInfo* AsURLRequestInfo() { return NULL; }
virtual URLResponseInfo* AsURLResponseInfo() { return NULL; }
+ virtual Var* AsVar() { return NULL; }
+ virtual VideoDecoder* AsVideoDecoder() { return NULL; }
virtual Widget* AsWidget() { return NULL; }
private:
@@ -101,10 +118,7 @@ class Resource : public base::RefCountedThreadSafe<Resource> {
// Called by the resource tracker when the last plugin reference has been
// dropped.
friend class ResourceTracker;
- void StoppedTracking() {
- DCHECK(resource_id_ != 0);
- resource_id_ = 0;
- }
+ void StoppedTracking();
DISALLOW_COPY_AND_ASSIGN(Resource);
};
@@ -115,18 +129,27 @@ class Resource : public base::RefCountedThreadSafe<Resource> {
return As##Type(); \
}
+DEFINE_RESOURCE_CAST(Audio)
+DEFINE_RESOURCE_CAST(AudioConfig)
DEFINE_RESOURCE_CAST(Buffer)
-DEFINE_RESOURCE_CAST(DeviceContext2D)
DEFINE_RESOURCE_CAST(DirectoryReader)
DEFINE_RESOURCE_CAST(FileChooser)
DEFINE_RESOURCE_CAST(FileIO)
DEFINE_RESOURCE_CAST(FileRef)
DEFINE_RESOURCE_CAST(Font)
+DEFINE_RESOURCE_CAST(Graphics2D)
+DEFINE_RESOURCE_CAST(Graphics3D)
DEFINE_RESOURCE_CAST(ImageData)
+DEFINE_RESOURCE_CAST(ObjectVar)
+DEFINE_RESOURCE_CAST(PrivateFontFile)
DEFINE_RESOURCE_CAST(Scrollbar)
+DEFINE_RESOURCE_CAST(StringVar);
+DEFINE_RESOURCE_CAST(Transport)
DEFINE_RESOURCE_CAST(URLLoader)
DEFINE_RESOURCE_CAST(URLRequestInfo)
DEFINE_RESOURCE_CAST(URLResponseInfo)
+DEFINE_RESOURCE_CAST(Var)
+DEFINE_RESOURCE_CAST(VideoDecoder)
DEFINE_RESOURCE_CAST(Widget)
#undef DEFINE_RESOURCE_CAST
diff --git a/webkit/glue/plugins/pepper_resource_tracker.cc b/webkit/glue/plugins/pepper_resource_tracker.cc
index 8aa94d2..9ee54f8 100644
--- a/webkit/glue/plugins/pepper_resource_tracker.cc
+++ b/webkit/glue/plugins/pepper_resource_tracker.cc
@@ -21,6 +21,13 @@ scoped_refptr<Resource> ResourceTracker::GetResource(PP_Resource res) const {
return result->second.first;
}
+ResourceTracker::ResourceTracker()
+ : last_id_(0) {
+}
+
+ResourceTracker::~ResourceTracker() {
+}
+
PP_Resource ResourceTracker::AddResource(Resource* resource) {
// If the plugin manages to create 4B resources...
if (last_id_ == std::numeric_limits<PP_Resource>::max()) {
@@ -58,4 +65,18 @@ bool ResourceTracker::UnrefResource(PP_Resource res) {
}
}
+uint32 ResourceTracker::GetLiveObjectsForModule(PluginModule* module) const {
+ // Since this is for testing only, we'll just go through all of them and
+ // count.
+ //
+ // TODO(brettw) we will eventually need to implement more efficient
+ // module->resource lookup to free resources when a module is unloaded. In
+ // this case, this function can be implemented using that system.
+ uint32 count = 0;
+ for (ResourceMap::const_iterator i = live_resources_.begin();
+ i != live_resources_.end(); ++i)
+ count++;
+ return count;
+}
+
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_resource_tracker.h b/webkit/glue/plugins/pepper_resource_tracker.h
index d06c9ba..59f02d2 100644
--- a/webkit/glue/plugins/pepper_resource_tracker.h
+++ b/webkit/glue/plugins/pepper_resource_tracker.h
@@ -5,17 +5,19 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_
-#include <set>
+#include <utility>
-#include "base/atomic_sequence_num.h"
#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/ref_counted.h"
#include "base/singleton.h"
#include "third_party/ppapi/c/pp_resource.h"
+typedef struct NPObject NPObject;
+
namespace pepper {
+class PluginModule;
class Resource;
// This class maintains a global list of all live pepper resources. It allows
@@ -41,13 +43,18 @@ class ResourceTracker {
bool AddRefResource(PP_Resource res);
bool UnrefResource(PP_Resource res);
+ // Returns the number of resources associated with this module.
+ //
+ // This is slow, use only for testing.
+ uint32 GetLiveObjectsForModule(PluginModule* module) const;
+
private:
friend struct DefaultSingletonTraits<ResourceTracker>;
friend class Resource;
// Prohibit creation other then by the Singleton class.
- ResourceTracker() : last_id_(0) {}
- ~ResourceTracker() {}
+ ResourceTracker();
+ ~ResourceTracker();
// Adds the given resource to the tracker and assigns it a resource ID and
// refcount of 1. The assigned resource ID will be returned. Used only by the
diff --git a/webkit/glue/plugins/pepper_scrollbar.cc b/webkit/glue/plugins/pepper_scrollbar.cc
index 48db8d4..a8943d2 100644
--- a/webkit/glue/plugins/pepper_scrollbar.cc
+++ b/webkit/glue/plugins/pepper_scrollbar.cc
@@ -6,7 +6,8 @@
#include "base/logging.h"
#include "base/message_loop.h"
-#include "third_party/ppapi/c/ppp_scrollbar.h"
+#include "skia/ext/platform_canvas.h"
+#include "third_party/ppapi/c/dev/ppp_scrollbar_dev.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
#include "third_party/WebKit/WebKit/chromium/public/WebScrollbar.h"
@@ -17,6 +18,10 @@
#include "webkit/glue/plugins/pepper_plugin_module.h"
#include "webkit/glue/webkit_glue.h"
+#if defined(OS_WIN)
+#include "base/win_util.h"
+#endif
+
using WebKit::WebInputEvent;
using WebKit::WebRect;
using WebKit::WebScrollbar;
@@ -28,7 +33,7 @@ namespace {
PP_Resource Create(PP_Instance instance_id, bool vertical) {
PluginInstance* instance = PluginInstance::FromPPInstance(instance_id);
if (!instance)
- return NULL;
+ return 0;
scoped_refptr<Scrollbar> scrollbar(new Scrollbar(instance, vertical));
return scrollbar->GetReference();
@@ -69,15 +74,13 @@ void SetTickMarks(PP_Resource resource,
scrollbar->SetTickMarks(tick_marks, count);
}
-void ScrollBy(PP_Resource resource,
- PP_ScrollBy unit,
- int32_t multiplier) {
+void ScrollBy(PP_Resource resource, PP_ScrollBy_Dev unit, int32_t multiplier) {
scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource));
if (scrollbar)
scrollbar->ScrollBy(unit, multiplier);
}
-const PPB_Scrollbar ppb_scrollbar = {
+const PPB_Scrollbar_Dev ppb_scrollbar = {
&Create,
&IsScrollbar,
&GetThickness,
@@ -101,7 +104,7 @@ Scrollbar::~Scrollbar() {
}
// static
-const PPB_Scrollbar* Scrollbar::GetInterface() {
+const PPB_Scrollbar_Dev* Scrollbar::GetInterface() {
return &ppb_scrollbar;
}
@@ -129,7 +132,7 @@ void Scrollbar::SetTickMarks(const PP_Rect* tick_marks, uint32_t count) {
Invalidate(&rect);
}
-void Scrollbar::ScrollBy(PP_ScrollBy unit, int32_t multiplier) {
+void Scrollbar::ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier) {
WebScrollbar::ScrollDirection direction = multiplier >= 0 ?
WebScrollbar::ScrollForward : WebScrollbar::ScrollBackward;
float fmultiplier = 1.0;
@@ -159,10 +162,18 @@ bool Scrollbar::Paint(const PP_Rect* rect, ImageData* image) {
if (!canvas)
return false;
scrollbar_->paint(webkit_glue::ToWebCanvas(canvas), gfx_rect);
+
+#if defined(OS_WIN)
+ if (win_util::GetWinVersion() == win_util::WINVERSION_XP) {
+ canvas->getTopPlatformDevice().makeOpaque(
+ gfx_rect.x(), gfx_rect.y(), gfx_rect.width(), gfx_rect.height());
+ }
+#endif
+
return true;
}
-bool Scrollbar::HandleEvent(const PP_Event* event) {
+bool Scrollbar::HandleEvent(const PP_InputEvent* event) {
scoped_ptr<WebInputEvent> web_input_event(CreateWebInputEvent(*event));
if (!web_input_event.get())
return false;
@@ -178,8 +189,9 @@ void Scrollbar::SetLocationInternal(const PP_Rect* location) {
}
void Scrollbar::valueChanged(WebKit::WebScrollbar* scrollbar) {
- const PPP_Scrollbar* ppp_scrollbar = static_cast<const PPP_Scrollbar*>(
- module()->GetPluginInterface(PPP_SCROLLBAR_INTERFACE));
+ const PPP_Scrollbar_Dev* ppp_scrollbar =
+ static_cast<const PPP_Scrollbar_Dev*>(
+ module()->GetPluginInterface(PPP_SCROLLBAR_DEV_INTERFACE));
if (!ppp_scrollbar)
return;
ScopedResourceId resource(this);
diff --git a/webkit/glue/plugins/pepper_scrollbar.h b/webkit/glue/plugins/pepper_scrollbar.h
index bf25136..e8ac480 100644
--- a/webkit/glue/plugins/pepper_scrollbar.h
+++ b/webkit/glue/plugins/pepper_scrollbar.h
@@ -8,13 +8,11 @@
#include <vector>
#include "gfx/rect.h"
-#include "third_party/ppapi/c/ppb_scrollbar.h"
+#include "third_party/ppapi/c/dev/ppb_scrollbar_dev.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
#include "third_party/WebKit/WebKit/chromium/public/WebScrollbarClient.h"
#include "webkit/glue/plugins/pepper_widget.h"
-typedef struct _ppb_Scrollbar PPB_Scrollbar;
-
namespace pepper {
class PluginInstance;
@@ -26,7 +24,7 @@ class Scrollbar : public Widget, public WebKit::WebScrollbarClient {
// Returns a pointer to the interface implementing PPB_Scrollbar that is
// exposed to the plugin.
- static const PPB_Scrollbar* GetInterface();
+ static const PPB_Scrollbar_Dev* GetInterface();
// Resource overrides.
Scrollbar* AsScrollbar() { return this; }
@@ -36,11 +34,11 @@ class Scrollbar : public Widget, public WebKit::WebScrollbarClient {
void SetValue(uint32_t value);
void SetDocumentSize(uint32_t size);
void SetTickMarks(const PP_Rect* tick_marks, uint32_t count);
- void ScrollBy(PP_ScrollBy unit, int32_t multiplier);
+ void ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier);
// PPB_Widget implementation.
virtual bool Paint(const PP_Rect* rect, ImageData* image);
- virtual bool HandleEvent(const PP_Event* event);
+ virtual bool HandleEvent(const PP_InputEvent* event);
virtual void SetLocationInternal(const PP_Rect* location);
private:
diff --git a/webkit/glue/plugins/pepper_url_loader.cc b/webkit/glue/plugins/pepper_url_loader.cc
index aa09686..4169c00 100644
--- a/webkit/glue/plugins/pepper_url_loader.cc
+++ b/webkit/glue/plugins/pepper_url_loader.cc
@@ -7,14 +7,17 @@
#include "base/logging.h"
#include "third_party/ppapi/c/pp_completion_callback.h"
#include "third_party/ppapi/c/pp_errors.h"
-#include "third_party/ppapi/c/ppb_url_loader.h"
+#include "third_party/ppapi/c/dev/ppb_url_loader_dev.h"
+#include "third_party/ppapi/c/dev/ppb_url_loader_trusted_dev.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/WebKit/chromium/public/WebElement.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebKit.h"
#include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_url_request_info.h"
#include "webkit/glue/plugins/pepper_url_response_info.h"
@@ -121,6 +124,15 @@ int32_t ReadResponseBody(PP_Resource loader_id,
return loader->ReadResponseBody(buffer, bytes_to_read, callback);
}
+int32_t FinishStreamingToFile(PP_Resource loader_id,
+ PP_CompletionCallback callback) {
+ scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id));
+ if (!loader)
+ return PP_ERROR_BADRESOURCE;
+
+ return loader->FinishStreamingToFile(callback);
+}
+
void Close(PP_Resource loader_id) {
scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id));
if (!loader)
@@ -129,7 +141,7 @@ void Close(PP_Resource loader_id) {
loader->Close();
}
-const PPB_URLLoader ppb_urlloader = {
+const PPB_URLLoader_Dev ppb_urlloader = {
&Create,
&IsURLLoader,
&Open,
@@ -138,9 +150,22 @@ const PPB_URLLoader ppb_urlloader = {
&GetDownloadProgress,
&GetResponseInfo,
&ReadResponseBody,
+ &FinishStreamingToFile,
&Close
};
+void GrantUniversalAccess(PP_Resource loader_id) {
+ scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id));
+ if (!loader)
+ return;
+
+ loader->GrantUniversalAccess();
+}
+
+const PPB_URLLoaderTrusted_Dev ppb_urlloadertrusted = {
+ &GrantUniversalAccess
+};
+
} // namespace
URLLoader::URLLoader(PluginInstance* instance)
@@ -148,22 +173,28 @@ URLLoader::URLLoader(PluginInstance* instance)
instance_(instance),
pending_callback_(),
bytes_sent_(0),
- total_bytes_to_be_sent_(0),
+ total_bytes_to_be_sent_(-1),
bytes_received_(0),
- total_bytes_to_be_received_(0),
+ total_bytes_to_be_received_(-1),
user_buffer_(NULL),
user_buffer_size_(0),
- done_(false) {
+ done_status_(PP_ERROR_WOULDBLOCK),
+ has_universal_access_(false) {
}
URLLoader::~URLLoader() {
}
// static
-const PPB_URLLoader* URLLoader::GetInterface() {
+const PPB_URLLoader_Dev* URLLoader::GetInterface() {
return &ppb_urlloader;
}
+// static
+const PPB_URLLoaderTrusted_Dev* URLLoader::GetTrustedInterface() {
+ return &ppb_urlloadertrusted;
+}
+
int32_t URLLoader::Open(URLRequestInfo* request,
PP_CompletionCallback callback) {
if (loader_.get())
@@ -177,6 +208,12 @@ int32_t URLLoader::Open(URLRequestInfo* request,
if (!frame)
return PP_ERROR_FAILED;
WebURLRequest web_request(request->ToWebURLRequest(frame));
+
+ // Check if we are allowed to access this URL.
+ if (!has_universal_access_ &&
+ !frame->securityOrigin().canRequest(web_request.url()))
+ return PP_ERROR_NOACCESS;
+
frame->dispatchWillSendRequest(web_request);
loader_.reset(WebKit::webKitClient()->createURLLoader());
@@ -199,6 +236,8 @@ int32_t URLLoader::FollowRedirect(PP_CompletionCallback callback) {
int32_t URLLoader::ReadResponseBody(char* buffer, int32_t bytes_to_read,
PP_CompletionCallback callback) {
+ if (!response_info_ || response_info_->body())
+ return PP_ERROR_FAILED;
if (bytes_to_read <= 0 || !buffer)
return PP_ERROR_BADARGUMENT;
if (pending_callback_.func)
@@ -214,20 +253,40 @@ int32_t URLLoader::ReadResponseBody(char* buffer, int32_t bytes_to_read,
if (!buffer_.empty())
return FillUserBuffer();
- if (done_) {
+ // We may have already reached EOF.
+ if (done_status_ != PP_ERROR_WOULDBLOCK) {
user_buffer_ = NULL;
user_buffer_size_ = 0;
- return 0;
+ return done_status_;
}
pending_callback_ = callback;
return PP_ERROR_WOULDBLOCK;
}
+int32_t URLLoader::FinishStreamingToFile(PP_CompletionCallback callback) {
+ if (!response_info_ || !response_info_->body())
+ return PP_ERROR_FAILED;
+ if (pending_callback_.func)
+ return PP_ERROR_INPROGRESS;
+
+ // We may have already reached EOF.
+ if (done_status_ != PP_ERROR_WOULDBLOCK)
+ return done_status_;
+
+ // Wait for didFinishLoading / didFail.
+ pending_callback_ = callback;
+ return PP_ERROR_WOULDBLOCK;
+}
+
void URLLoader::Close() {
NOTIMPLEMENTED(); // TODO(darin): Implement me.
}
+void URLLoader::GrantUniversalAccess() {
+ has_universal_access_ = true;
+}
+
void URLLoader::willSendRequest(WebURLLoader* loader,
WebURLRequest& new_request,
const WebURLResponse& redirect_response) {
@@ -248,12 +307,22 @@ void URLLoader::didReceiveResponse(WebURLLoader* loader,
if (response_info->Initialize(response))
response_info_ = response_info;
+ // Sets -1 if the content length is unknown.
+ total_bytes_to_be_received_ = response.expectedContentLength();
+
RunCallback(PP_OK);
}
+void URLLoader::didDownloadData(WebURLLoader* loader,
+ int data_length) {
+ bytes_received_ += data_length;
+}
+
void URLLoader::didReceiveData(WebURLLoader* loader,
const char* data,
int data_length) {
+ bytes_received_ += data_length;
+
buffer_.insert(buffer_.end(), data, data + data_length);
if (user_buffer_) {
RunCallback(FillUserBuffer());
@@ -262,15 +331,15 @@ void URLLoader::didReceiveData(WebURLLoader* loader,
}
}
-void URLLoader::didFinishLoading(WebURLLoader* loader) {
- done_ = true;
- RunCallback(PP_OK);
+void URLLoader::didFinishLoading(WebURLLoader* loader, double finish_time) {
+ done_status_ = PP_OK;
+ RunCallback(done_status_);
}
void URLLoader::didFail(WebURLLoader* loader, const WebURLError& error) {
- done_ = true;
// TODO(darin): Provide more detailed error information.
- RunCallback(PP_ERROR_FAILED);
+ done_status_ = PP_ERROR_FAILED;
+ RunCallback(done_status_);
}
void URLLoader::RunCallback(int32_t result) {
diff --git a/webkit/glue/plugins/pepper_url_loader.h b/webkit/glue/plugins/pepper_url_loader.h
index 088f220..4919de7 100644
--- a/webkit/glue/plugins/pepper_url_loader.h
+++ b/webkit/glue/plugins/pepper_url_loader.h
@@ -13,7 +13,8 @@
#include "third_party/WebKit/WebKit/chromium/public/WebURLLoaderClient.h"
#include "webkit/glue/plugins/pepper_resource.h"
-typedef struct _ppb_URLLoader PPB_URLLoader;
+struct PPB_URLLoader_Dev;
+struct PPB_URLLoaderTrusted_Dev;
namespace pepper {
@@ -28,7 +29,11 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient {
// Returns a pointer to the interface implementing PPB_URLLoader that is
// exposed to the plugin.
- static const PPB_URLLoader* GetInterface();
+ static const PPB_URLLoader_Dev* GetInterface();
+
+ // Returns a pointer to the interface implementing PPB_URLLoaderTrusted that
+ // is exposed to the plugin.
+ static const PPB_URLLoaderTrusted_Dev* GetTrustedInterface();
// Resource overrides.
URLLoader* AsURLLoader() { return this; }
@@ -38,8 +43,12 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient {
int32_t FollowRedirect(PP_CompletionCallback callback);
int32_t ReadResponseBody(char* buffer, int32_t bytes_to_read,
PP_CompletionCallback callback);
+ int32_t FinishStreamingToFile(PP_CompletionCallback callback);
void Close();
+ // PPB_URLLoaderTrusted implementation.
+ void GrantUniversalAccess();
+
// WebKit::WebURLLoaderClient implementation.
virtual void willSendRequest(WebKit::WebURLLoader* loader,
WebKit::WebURLRequest& new_request,
@@ -49,10 +58,13 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient {
unsigned long long total_bytes_to_be_sent);
virtual void didReceiveResponse(WebKit::WebURLLoader* loader,
const WebKit::WebURLResponse& response);
+ virtual void didDownloadData(WebKit::WebURLLoader* loader,
+ int data_length);
virtual void didReceiveData(WebKit::WebURLLoader* loader,
const char* data,
int data_length);
- virtual void didFinishLoading(WebKit::WebURLLoader* loader);
+ virtual void didFinishLoading(WebKit::WebURLLoader* loader,
+ double finish_time);
virtual void didFail(WebKit::WebURLLoader* loader,
const WebKit::WebURLError& error);
@@ -81,7 +93,8 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient {
int64_t total_bytes_to_be_received_;
char* user_buffer_;
size_t user_buffer_size_;
- bool done_;
+ int32_t done_status_;
+ bool has_universal_access_;
};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_url_request_info.cc b/webkit/glue/plugins/pepper_url_request_info.cc
index d230f20..4edbe83 100644
--- a/webkit/glue/plugins/pepper_url_request_info.cc
+++ b/webkit/glue/plugins/pepper_url_request_info.cc
@@ -22,7 +22,6 @@
#include "webkit/glue/webkit_glue.h"
using WebKit::WebData;
-using WebKit::WebFileInfo;
using WebKit::WebHTTPBody;
using WebKit::WebString;
using WebKit::WebFrame;
@@ -62,7 +61,7 @@ bool IsURLRequestInfo(PP_Resource resource) {
}
bool SetProperty(PP_Resource request_id,
- PP_URLRequestProperty property,
+ PP_URLRequestProperty_Dev property,
PP_Var var) {
scoped_refptr<URLRequestInfo> request(
Resource::GetAs<URLRequestInfo>(request_id));
@@ -72,8 +71,11 @@ bool SetProperty(PP_Resource request_id,
if (var.type == PP_VARTYPE_BOOL)
return request->SetBooleanProperty(property, var.value.as_bool);
- if (var.type == PP_VARTYPE_STRING)
- return request->SetStringProperty(property, GetString(var)->value());
+ if (var.type == PP_VARTYPE_STRING) {
+ scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
+ if (string)
+ return request->SetStringProperty(property, string->value());
+ }
return false;
}
@@ -84,7 +86,7 @@ bool AppendDataToBody(PP_Resource request_id, PP_Var var) {
if (!request)
return false;
- String* data = GetString(var);
+ scoped_refptr<StringVar> data(StringVar::FromPPVar(var));
if (!data)
return false;
@@ -111,7 +113,7 @@ bool AppendFileToBody(PP_Resource request_id,
expected_last_modified_time);
}
-const PPB_URLRequestInfo ppb_urlrequestinfo = {
+const PPB_URLRequestInfo_Dev ppb_urlrequestinfo = {
&Create,
&IsURLRequestInfo,
&SetProperty,
@@ -122,24 +124,31 @@ const PPB_URLRequestInfo ppb_urlrequestinfo = {
} // namespace
URLRequestInfo::URLRequestInfo(PluginModule* module)
- : Resource(module) {
+ : Resource(module),
+ stream_to_file_(false) {
}
URLRequestInfo::~URLRequestInfo() {
}
// static
-const PPB_URLRequestInfo* URLRequestInfo::GetInterface() {
+const PPB_URLRequestInfo_Dev* URLRequestInfo::GetInterface() {
return &ppb_urlrequestinfo;
}
-bool URLRequestInfo::SetBooleanProperty(PP_URLRequestProperty property,
+bool URLRequestInfo::SetBooleanProperty(PP_URLRequestProperty_Dev property,
bool value) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return false;
+ switch (property) {
+ case PP_URLREQUESTPROPERTY_STREAMTOFILE:
+ stream_to_file_ = value;
+ return true;
+ default:
+ NOTIMPLEMENTED(); // TODO(darin): Implement me!
+ return false;
+ }
}
-bool URLRequestInfo::SetStringProperty(PP_URLRequestProperty property,
+bool URLRequestInfo::SetStringProperty(PP_URLRequestProperty_Dev property,
const std::string& value) {
// TODO(darin): Validate input. Perhaps at a different layer?
switch (property) {
@@ -167,6 +176,14 @@ bool URLRequestInfo::AppendFileToBody(FileRef* file_ref,
int64_t start_offset,
int64_t number_of_bytes,
PP_Time expected_last_modified_time) {
+ // Ignore a call to append nothing.
+ if (number_of_bytes == 0)
+ return true;
+
+ // Check for bad values. (-1 means read until end of file.)
+ if (start_offset < 0 || number_of_bytes < -1)
+ return false;
+
body_.push_back(BodyItem(file_ref,
start_offset,
number_of_bytes,
@@ -178,6 +195,7 @@ WebURLRequest URLRequestInfo::ToWebURLRequest(WebFrame* frame) const {
WebURLRequest web_request;
web_request.initialize();
web_request.setURL(frame->document().completeURL(WebString::fromUTF8(url_)));
+ web_request.setDownloadToFile(stream_to_file_);
if (!method_.empty())
web_request.setHTTPMethod(WebString::fromUTF8(method_));
@@ -198,13 +216,11 @@ WebURLRequest URLRequestInfo::ToWebURLRequest(WebFrame* frame) const {
http_body.initialize();
for (size_t i = 0; i < body_.size(); ++i) {
if (body_[i].file_ref) {
- WebFileInfo file_info;
- file_info.modificationTime = body_[i].expected_last_modified_time;
http_body.appendFileRange(
webkit_glue::FilePathToWebString(body_[i].file_ref->system_path()),
body_[i].start_offset,
body_[i].number_of_bytes,
- file_info);
+ body_[i].expected_last_modified_time);
} else {
DCHECK(!body_[i].data.empty());
http_body.appendData(WebData(body_[i].data));
diff --git a/webkit/glue/plugins/pepper_url_request_info.h b/webkit/glue/plugins/pepper_url_request_info.h
index ef1452c..7220531 100644
--- a/webkit/glue/plugins/pepper_url_request_info.h
+++ b/webkit/glue/plugins/pepper_url_request_info.h
@@ -9,7 +9,7 @@
#include <vector>
#include "base/ref_counted.h"
-#include "third_party/ppapi/c/ppb_url_request_info.h"
+#include "third_party/ppapi/c/dev/ppb_url_request_info_dev.h"
#include "webkit/glue/plugins/pepper_file_ref.h"
#include "webkit/glue/plugins/pepper_resource.h"
@@ -27,14 +27,14 @@ class URLRequestInfo : public Resource {
// Returns a pointer to the interface implementing PPB_URLRequestInfo that is
// exposed to the plugin.
- static const PPB_URLRequestInfo* GetInterface();
+ static const PPB_URLRequestInfo_Dev* GetInterface();
// Resource overrides.
URLRequestInfo* AsURLRequestInfo() { return this; }
// PPB_URLRequestInfo implementation.
- bool SetBooleanProperty(PP_URLRequestProperty property, bool value);
- bool SetStringProperty(PP_URLRequestProperty property,
+ bool SetBooleanProperty(PP_URLRequestProperty_Dev property, bool value);
+ bool SetStringProperty(PP_URLRequestProperty_Dev property,
const std::string& value);
bool AppendDataToBody(const std::string& data);
bool AppendFileToBody(FileRef* file_ref,
@@ -76,6 +76,7 @@ class URLRequestInfo : public Resource {
std::string method_;
std::string headers_;
Body body_;
+ bool stream_to_file_;
};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_url_response_info.cc b/webkit/glue/plugins/pepper_url_response_info.cc
index bff92aa..79042ba 100644
--- a/webkit/glue/plugins/pepper_url_response_info.cc
+++ b/webkit/glue/plugins/pepper_url_response_info.cc
@@ -12,6 +12,7 @@
#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h"
#include "webkit/glue/plugins/pepper_file_ref.h"
#include "webkit/glue/plugins/pepper_var.h"
+#include "webkit/glue/webkit_glue.h"
using WebKit::WebHTTPHeaderVisitor;
using WebKit::WebString;
@@ -42,7 +43,7 @@ bool IsURLResponseInfo(PP_Resource resource) {
}
PP_Var GetProperty(PP_Resource response_id,
- PP_URLResponseProperty property) {
+ PP_URLResponseProperty_Dev property) {
scoped_refptr<URLResponseInfo> response(
Resource::GetAs<URLResponseInfo>(response_id));
if (!response)
@@ -65,7 +66,7 @@ PP_Resource GetBody(PP_Resource response_id) {
return body->GetReference();
}
-const PPB_URLResponseInfo ppb_urlresponseinfo = {
+const PPB_URLResponseInfo_Dev ppb_urlresponseinfo = {
&IsURLResponseInfo,
&GetProperty,
&GetBody
@@ -82,18 +83,18 @@ URLResponseInfo::~URLResponseInfo() {
}
// static
-const PPB_URLResponseInfo* URLResponseInfo::GetInterface() {
+const PPB_URLResponseInfo_Dev* URLResponseInfo::GetInterface() {
return &ppb_urlresponseinfo;
}
-PP_Var URLResponseInfo::GetProperty(PP_URLResponseProperty property) {
+PP_Var URLResponseInfo::GetProperty(PP_URLResponseProperty_Dev property) {
switch (property) {
case PP_URLRESPONSEPROPERTY_URL:
- return StringToPPVar(url_);
+ return StringVar::StringToPPVar(module(), url_);
case PP_URLRESPONSEPROPERTY_STATUSCODE:
return PP_MakeInt32(status_code_);
case PP_URLRESPONSEPROPERTY_HEADERS:
- return StringToPPVar(headers_);
+ return StringVar::StringToPPVar(module(), headers_);
default:
NOTIMPLEMENTED(); // TODO(darin): Implement me!
return PP_MakeVoid();
@@ -107,6 +108,10 @@ bool URLResponseInfo::Initialize(const WebURLResponse& response) {
HeaderFlattener flattener;
response.visitHTTPHeaderFields(&flattener);
headers_ = flattener.buffer();
+
+ WebString file_path = response.downloadFilePath();
+ if (!file_path.isEmpty())
+ body_ = new FileRef(module(), webkit_glue::WebStringToFilePath(file_path));
return true;
}
diff --git a/webkit/glue/plugins/pepper_url_response_info.h b/webkit/glue/plugins/pepper_url_response_info.h
index 8874919..d8e1321 100644
--- a/webkit/glue/plugins/pepper_url_response_info.h
+++ b/webkit/glue/plugins/pepper_url_response_info.h
@@ -7,7 +7,7 @@
#include <string>
-#include "third_party/ppapi/c/ppb_url_response_info.h"
+#include "third_party/ppapi/c/dev/ppb_url_response_info_dev.h"
#include "webkit/glue/plugins/pepper_resource.h"
namespace WebKit {
@@ -23,13 +23,13 @@ class URLResponseInfo : public Resource {
// Returns a pointer to the interface implementing PPB_URLResponseInfo that
// is exposed to the plugin.
- static const PPB_URLResponseInfo* GetInterface();
+ static const PPB_URLResponseInfo_Dev* GetInterface();
// Resource overrides.
URLResponseInfo* AsURLResponseInfo() { return this; }
// PPB_URLResponseInfo implementation.
- PP_Var GetProperty(PP_URLResponseProperty property);
+ PP_Var GetProperty(PP_URLResponseProperty_Dev property);
bool Initialize(const WebKit::WebURLResponse& response);
diff --git a/webkit/glue/plugins/pepper_var.cc b/webkit/glue/plugins/pepper_var.cc
index 414df7b..b4ba014 100644
--- a/webkit/glue/plugins/pepper_var.cc
+++ b/webkit/glue/plugins/pepper_var.cc
@@ -9,9 +9,9 @@
#include "base/string_util.h"
#include "third_party/ppapi/c/pp_var.h"
#include "third_party/ppapi/c/ppb_var.h"
-#include "third_party/ppapi/c/ppp_class.h"
#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h"
-#include "webkit/glue/plugins/pepper_string.h"
+#include "webkit/glue/plugins/pepper_plugin_module.h"
+#include "webkit/glue/plugins/pepper_plugin_object.h"
#include "v8/include/v8.h"
using WebKit::WebBindings;
@@ -20,43 +20,9 @@ namespace pepper {
namespace {
-void Release(PP_Var var);
-PP_Var VarFromUtf8(const char* data, uint32_t len);
-
-// ---------------------------------------------------------------------------
-// Exceptions
-
-class TryCatch {
- public:
- TryCatch(PP_Var* exception) : exception_(exception) {
- WebBindings::pushExceptionHandler(&TryCatch::Catch, this);
- }
-
- ~TryCatch() {
- WebBindings::popExceptionHandler();
- }
-
- bool HasException() const {
- return exception_ && exception_->type != PP_VARTYPE_VOID;
- }
-
- void SetException(const char* message) {
- DCHECK(!HasException());
- if (exception_)
- *exception_ = VarFromUtf8(message, strlen(message));
- }
-
- private:
- static void Catch(void* self, const NPUTF8* message) {
- static_cast<TryCatch*>(self)->SetException(message);
- }
-
- // May be null if the consumer isn't interesting in catching exceptions.
- PP_Var* exception_;
-};
-
const char kInvalidObjectException[] = "Error: Invalid object";
const char kInvalidPropertyException[] = "Error: Invalid property";
+const char kInvalidValueException[] = "Error: Invalid value";
const char kUnableToGetPropertyException[] = "Error: Unable to get property";
const char kUnableToSetPropertyException[] = "Error: Unable to set property";
const char kUnableToRemovePropertyException[] =
@@ -69,531 +35,182 @@ const char kUnableToConstructException[] = "Error: Unable to construct";
// ---------------------------------------------------------------------------
// Utilities
-String* GetStringUnchecked(PP_Var var) {
- return reinterpret_cast<String*>(var.value.as_id);
-}
-
-NPObject* GetNPObjectUnchecked(PP_Var var) {
- return reinterpret_cast<NPObject*>(var.value.as_id);
-}
-
-// Returns a PP_Var that corresponds to the given NPVariant. The contents of
-// the NPVariant will be copied unless the NPVariant corresponds to an object.
-PP_Var NPVariantToPPVar(const NPVariant* variant) {
- switch (variant->type) {
- case NPVariantType_Void:
- return PP_MakeVoid();
- case NPVariantType_Null:
- return PP_MakeNull();
- case NPVariantType_Bool:
- return PP_MakeBool(NPVARIANT_TO_BOOLEAN(*variant));
- case NPVariantType_Int32:
- return PP_MakeInt32(NPVARIANT_TO_INT32(*variant));
- case NPVariantType_Double:
- return PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant));
- case NPVariantType_String:
- return VarFromUtf8(NPVARIANT_TO_STRING(*variant).UTF8Characters,
- NPVARIANT_TO_STRING(*variant).UTF8Length);
- case NPVariantType_Object:
- return NPObjectToPPVar(NPVARIANT_TO_OBJECT(*variant));
- }
- NOTREACHED();
- return PP_MakeVoid();
-}
-
-// Returns a NPVariant that corresponds to the given PP_Var. The contents of
-// the PP_Var will be copied unless the PP_Var corresponds to an object.
-NPVariant PPVarToNPVariant(PP_Var var) {
- NPVariant ret;
+// Converts the given PP_Var to an NPVariant, returning true on success.
+// False means that the given variant is invalid. In this case, the result
+// NPVariant will be set to a void one.
+//
+// The contents of the PP_Var will NOT be copied, so you need to ensure that
+// the PP_Var remains valid while the resultant NPVariant is in use.
+bool PPVarToNPVariantNoCopy(PP_Var var, NPVariant* result) {
switch (var.type) {
case PP_VARTYPE_VOID:
- VOID_TO_NPVARIANT(ret);
+ VOID_TO_NPVARIANT(*result);
break;
case PP_VARTYPE_NULL:
- NULL_TO_NPVARIANT(ret);
+ NULL_TO_NPVARIANT(*result);
break;
case PP_VARTYPE_BOOL:
- BOOLEAN_TO_NPVARIANT(var.value.as_bool, ret);
+ BOOLEAN_TO_NPVARIANT(var.value.as_bool, *result);
break;
case PP_VARTYPE_INT32:
- INT32_TO_NPVARIANT(var.value.as_int, ret);
+ INT32_TO_NPVARIANT(var.value.as_int, *result);
break;
case PP_VARTYPE_DOUBLE:
- DOUBLE_TO_NPVARIANT(var.value.as_double, ret);
+ DOUBLE_TO_NPVARIANT(var.value.as_double, *result);
break;
case PP_VARTYPE_STRING: {
- const std::string& value = GetStringUnchecked(var)->value();
- STRINGN_TO_NPVARIANT(base::strdup(value.c_str()), value.size(), ret);
+ scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
+ if (!string) {
+ VOID_TO_NPVARIANT(*result);
+ return false;
+ }
+ const std::string& value = string->value();
+ STRINGN_TO_NPVARIANT(value.c_str(), value.size(), *result);
break;
}
case PP_VARTYPE_OBJECT: {
- NPObject* object = GetNPObjectUnchecked(var);
- OBJECT_TO_NPVARIANT(WebBindings::retainObject(object), ret);
+ scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var));
+ if (!object) {
+ VOID_TO_NPVARIANT(*result);
+ return false;
+ }
+ OBJECT_TO_NPVARIANT(object->np_object(), *result);
break;
}
- }
- return ret;
-}
-
-// Returns a NPVariant that corresponds to the given PP_Var. The contents of
-// the PP_Var will NOT be copied, so you need to ensure that the PP_Var remains
-// valid while the resultant NPVariant is in use.
-NPVariant PPVarToNPVariantNoCopy(PP_Var var) {
- NPVariant ret;
- switch (var.type) {
- case PP_VARTYPE_VOID:
- VOID_TO_NPVARIANT(ret);
- break;
- case PP_VARTYPE_NULL:
- NULL_TO_NPVARIANT(ret);
- break;
- case PP_VARTYPE_BOOL:
- BOOLEAN_TO_NPVARIANT(var.value.as_bool, ret);
- break;
- case PP_VARTYPE_INT32:
- INT32_TO_NPVARIANT(var.value.as_int, ret);
- break;
- case PP_VARTYPE_DOUBLE:
- DOUBLE_TO_NPVARIANT(var.value.as_double, ret);
- break;
- case PP_VARTYPE_STRING: {
- const std::string& value = GetStringUnchecked(var)->value();
- STRINGN_TO_NPVARIANT(value.c_str(), value.size(), ret);
- break;
- }
- case PP_VARTYPE_OBJECT: {
- OBJECT_TO_NPVARIANT(GetNPObjectUnchecked(var), ret);
- break;
- }
- }
- return ret;
-}
-
-// Returns a NPIdentifier that corresponds to the given PP_Var. The contents
-// of the PP_Var will be copied. Returns NULL if the given PP_Var is not a a
-// string or integer type.
-NPIdentifier PPVarToNPIdentifier(PP_Var var) {
- switch (var.type) {
- case PP_VARTYPE_STRING:
- return WebBindings::getStringIdentifier(
- GetStringUnchecked(var)->value().c_str());
- case PP_VARTYPE_INT32:
- return WebBindings::getIntIdentifier(var.value.as_int);
default:
- return NULL;
+ VOID_TO_NPVARIANT(*result);
+ return false;
}
+ return true;
}
-PP_Var NPIdentifierToPPVar(NPIdentifier id) {
- const NPUTF8* string_value = NULL;
- int32_t int_value = 0;
- bool is_string = false;
- WebBindings::extractIdentifierData(id, string_value, int_value, is_string);
- if (is_string)
- return VarFromUtf8(string_value, strlen(string_value));
-
- return PP_MakeInt32(int_value);
-}
-
-PP_Var NPIdentifierToPPVarString(NPIdentifier id) {
- PP_Var var = NPIdentifierToPPVar(id);
- if (var.type == PP_VARTYPE_STRING)
- return var;
- DCHECK(var.type == PP_VARTYPE_INT32);
- const std::string& str = IntToString(var.value.as_int);
- return VarFromUtf8(str.data(), str.size());
-}
-
-void ThrowException(NPObject* object, PP_Var exception) {
- String* str = GetString(exception);
- if (str)
- WebBindings::setException(object, str->value().c_str());
-}
-
-// ---------------------------------------------------------------------------
-// NPObject implementation in terms of PPP_Class
-
-struct WrapperObject : NPObject {
- const PPP_Class* ppp_class;
- void* ppp_class_data;
-};
-
-static WrapperObject* ToWrapper(NPObject* object) {
- return static_cast<WrapperObject*>(object);
-}
-
-NPObject* WrapperClass_Allocate(NPP npp, NPClass* unused) {
- return new WrapperObject;
-}
-
-void WrapperClass_Deallocate(NPObject* object) {
- WrapperObject* wrapper = ToWrapper(object);
- wrapper->ppp_class->Deallocate(wrapper->ppp_class_data);
- delete object;
-}
-
-void WrapperClass_Invalidate(NPObject* object) {
- // TODO(darin): Do I need to do something here?
-}
-
-bool WrapperClass_HasMethod(NPObject* object, NPIdentifier method_name) {
- WrapperObject* wrapper = ToWrapper(object);
-
- PP_Var method_name_var = NPIdentifierToPPVarString(method_name);
- PP_Var exception = PP_MakeVoid();
- bool rv = wrapper->ppp_class->HasMethod(wrapper->ppp_class_data,
- method_name_var,
- &exception);
- Release(method_name_var);
-
- if (exception.type != PP_VARTYPE_VOID) {
- ThrowException(object, exception);
- Release(exception);
- return false;
- }
- return rv;
-}
-
-bool WrapperClass_Invoke(NPObject* object, NPIdentifier method_name,
- const NPVariant* argv, uint32_t argc,
- NPVariant* result) {
- WrapperObject* wrapper = ToWrapper(object);
-
- scoped_array<PP_Var> args;
- if (argc) {
- args.reset(new PP_Var[argc]);
- for (uint32_t i = 0; i < argc; ++i)
- args[i] = NPVariantToPPVar(&argv[i]);
- }
- PP_Var method_name_var = NPIdentifierToPPVarString(method_name);
- PP_Var exception = PP_MakeVoid();
- PP_Var result_var = wrapper->ppp_class->Call(wrapper->ppp_class_data,
- method_name_var, argc,
- args.get(), &exception);
- Release(method_name_var);
- for (uint32_t i = 0; i < argc; ++i)
- Release(args[i]);
-
- bool rv;
- if (exception.type == PP_VARTYPE_VOID) {
- rv = true;
- *result = PPVarToNPVariant(result_var);
- } else {
- rv = false;
- ThrowException(object, exception);
- Release(exception);
- }
- Release(result_var);
- return rv;
-}
-
-bool WrapperClass_InvokeDefault(NPObject* object, const NPVariant* argv,
- uint32_t argc, NPVariant* result) {
- WrapperObject* wrapper = ToWrapper(object);
-
- scoped_array<PP_Var> args;
- if (argc) {
- args.reset(new PP_Var[argc]);
- for (uint32_t i = 0; i < argc; ++i)
- args[i] = NPVariantToPPVar(&argv[i]);
- }
- PP_Var exception = PP_MakeVoid();
- PP_Var result_var = wrapper->ppp_class->Call(wrapper->ppp_class_data,
- PP_MakeVoid(), argc, args.get(),
- &exception);
- for (uint32_t i = 0; i < argc; ++i)
- Release(args[i]);
-
- bool rv;
- if (exception.type == PP_VARTYPE_VOID) {
- rv = true;
- *result = PPVarToNPVariant(result_var);
- } else {
- rv = false;
- ThrowException(object, exception);
- Release(exception);
- }
- Release(result_var);
- return rv;
-}
-
-bool WrapperClass_HasProperty(NPObject* object, NPIdentifier property_name) {
- WrapperObject* wrapper = ToWrapper(object);
-
- PP_Var property_name_var = NPIdentifierToPPVar(property_name);
- PP_Var exception = PP_MakeVoid();
- bool rv = wrapper->ppp_class->HasProperty(wrapper->ppp_class_data,
- property_name_var,
- &exception);
- Release(property_name_var);
-
- if (exception.type != PP_VARTYPE_VOID) {
- ThrowException(object, exception);
- Release(exception);
- return false;
- }
- return rv;
-}
-
-bool WrapperClass_GetProperty(NPObject* object, NPIdentifier property_name,
- NPVariant* result) {
- WrapperObject* wrapper = ToWrapper(object);
-
- PP_Var property_name_var = NPIdentifierToPPVar(property_name);
- PP_Var exception = PP_MakeVoid();
- PP_Var result_var = wrapper->ppp_class->GetProperty(wrapper->ppp_class_data,
- property_name_var,
- &exception);
- Release(property_name_var);
-
- bool rv;
- if (exception.type == PP_VARTYPE_VOID) {
- rv = true;
- *result = PPVarToNPVariant(result_var);
- } else {
- rv = false;
- ThrowException(object, exception);
- Release(exception);
- }
- Release(result_var);
- return rv;
-}
-
-bool WrapperClass_SetProperty(NPObject* object, NPIdentifier property_name,
- const NPVariant* value) {
- WrapperObject* wrapper = ToWrapper(object);
+// ObjectAccessorTryCatch ------------------------------------------------------
- PP_Var property_name_var = NPIdentifierToPPVar(property_name);
- PP_Var value_var = NPVariantToPPVar(value);
- PP_Var exception = PP_MakeVoid();
- wrapper->ppp_class->SetProperty(wrapper->ppp_class_data, property_name_var,
- value_var, &exception);
- Release(value_var);
- Release(property_name_var);
-
- if (exception.type != PP_VARTYPE_VOID) {
- ThrowException(object, exception);
- Release(exception);
- return false;
+// Automatically sets up a TryCatch for accessing the object identified by the
+// given PP_Var. The module from the object will be used for the exception
+// strings generated by the TryCatch.
+//
+// This will automatically retrieve the ObjectVar from the object and throw
+// an exception if it's invalid. At the end of construction, if there is no
+// exception, you know that there is no previously set exception, that the
+// object passed in is valid and ready to use (via the object() getter), and
+// that the TryCatch's module() getter is also set up properly and ready to
+// use.
+class ObjectAccessorTryCatch : public TryCatch {
+ public:
+ ObjectAccessorTryCatch(PP_Var object, PP_Var* exception)
+ : TryCatch(NULL, exception),
+ object_(ObjectVar::FromPPVar(object)) {
+ if (!object_) {
+ // No object or an invalid object was given. This means we have no module
+ // to associated with the exception text, so use the magic invalid object
+ // exception.
+ SetInvalidObjectException();
+ } else {
+ // When the object is valid, we have a valid module to associate
+ set_module(object_->module());
+ }
}
- return true;
-}
-bool WrapperClass_RemoveProperty(NPObject* object, NPIdentifier property_name) {
- WrapperObject* wrapper = ToWrapper(object);
+ ObjectVar* object() { return object_.get(); }
- PP_Var property_name_var = NPIdentifierToPPVar(property_name);
- PP_Var exception = PP_MakeVoid();
- wrapper->ppp_class->RemoveProperty(wrapper->ppp_class_data, property_name_var,
- &exception);
- Release(property_name_var);
+ protected:
+ scoped_refptr<ObjectVar> object_;
- if (exception.type != PP_VARTYPE_VOID) {
- ThrowException(object, exception);
- Release(exception);
- return false;
- }
- return true;
-}
+ DISALLOW_COPY_AND_ASSIGN(ObjectAccessorTryCatch);
+};
-bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values,
- uint32_t* count) {
- WrapperObject* wrapper = ToWrapper(object);
-
- uint32_t property_count = 0;
- PP_Var* properties = NULL;
- PP_Var exception = PP_MakeVoid();
- wrapper->ppp_class->GetAllPropertyNames(wrapper->ppp_class_data,
- &property_count,
- &properties,
- &exception);
-
- bool rv;
- if (exception.type == PP_VARTYPE_VOID) {
- rv = true;
- if (property_count == 0) {
- *values = NULL;
- *count = 0;
- } else {
- *values = static_cast<NPIdentifier*>(
- malloc(sizeof(NPIdentifier) * property_count));
- *count = property_count;
- for (uint32_t i = 0; i < property_count; ++i)
- (*values)[i] = PPVarToNPIdentifier(properties[i]);
+// ObjectAccessiorWithIdentifierTryCatch ---------------------------------------
+
+// Automatically sets up a TryCatch for accessing the identifier on the given
+// object. This just extends ObjectAccessorTryCatch to additionally convert
+// the given identifier to an NPIdentifier and validate it, throwing an
+// exception if it's invalid.
+//
+// At the end of construction, if there is no exception, you know that there is
+// no previously set exception, that the object passed in is valid and ready to
+// use (via the object() getter), that the identifier is valid and ready to
+// use (via the identifier() getter), and that the TryCatch's module() getter
+// is also set up properly and ready to use.
+class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch {
+ public:
+ ObjectAccessorWithIdentifierTryCatch(PP_Var object,
+ PP_Var identifier,
+ PP_Var* exception)
+ : ObjectAccessorTryCatch(object, exception),
+ identifier_(0) {
+ if (!has_exception()) {
+ identifier_ = Var::PPVarToNPIdentifier(identifier);
+ if (!identifier_)
+ SetException(kInvalidPropertyException);
}
- } else {
- rv = false;
- ThrowException(object, exception);
- Release(exception);
}
- for (uint32_t i = 0; i < property_count; ++i)
- Release(properties[i]);
- free(properties);
- return rv;
-}
+ NPIdentifier identifier() const { return identifier_; }
-bool WrapperClass_Construct(NPObject* object, const NPVariant* argv,
- uint32_t argc, NPVariant* result) {
- WrapperObject* wrapper = ToWrapper(object);
-
- scoped_array<PP_Var> args;
- if (argc) {
- args.reset(new PP_Var[argc]);
- for (uint32_t i = 0; i < argc; ++i)
- args[i] = NPVariantToPPVar(&argv[i]);
- }
+ private:
+ NPIdentifier identifier_;
- PP_Var exception = PP_MakeVoid();
- PP_Var result_var = wrapper->ppp_class->Construct(wrapper->ppp_class_data,
- argc, args.get(),
- &exception);
- for (uint32_t i = 0; i < argc; ++i)
- Release(args[i]);
-
- bool rv;
- if (exception.type == PP_VARTYPE_VOID) {
- rv = true;
- *result = PPVarToNPVariant(result_var);
- } else {
- rv = false;
- ThrowException(object, exception);
- Release(exception);
- }
- Release(result_var);
- return rv;
-}
-
-const NPClass wrapper_class = {
- NP_CLASS_STRUCT_VERSION,
- WrapperClass_Allocate,
- WrapperClass_Deallocate,
- WrapperClass_Invalidate,
- WrapperClass_HasMethod,
- WrapperClass_Invoke,
- WrapperClass_InvokeDefault,
- WrapperClass_HasProperty,
- WrapperClass_GetProperty,
- WrapperClass_SetProperty,
- WrapperClass_RemoveProperty,
- WrapperClass_Enumerate,
- WrapperClass_Construct
+ DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch);
};
-// ---------------------------------------------------------------------------
-// PPB_Var methods
-
-void AddRef(PP_Var var) {
- if (var.type == PP_VARTYPE_STRING) {
- GetStringUnchecked(var)->AddRef();
- } else if (var.type == PP_VARTYPE_OBJECT) {
- // TODO(darin): Add thread safety check
- WebBindings::retainObject(GetNPObjectUnchecked(var));
- }
-}
-
-void Release(PP_Var var) {
- if (var.type == PP_VARTYPE_STRING) {
- GetStringUnchecked(var)->Release();
- } else if (var.type == PP_VARTYPE_OBJECT) {
- // TODO(darin): Add thread safety check
- WebBindings::releaseObject(GetNPObjectUnchecked(var));
- }
-}
+// PPB_Var methods -------------------------------------------------------------
-PP_Var VarFromUtf8(const char* data, uint32_t len) {
- String* str = new String(data, len);
- str->AddRef(); // This is for the caller, we return w/ a refcount of 1.
- PP_Var ret;
- ret.type = PP_VARTYPE_STRING;
- ret.value.as_id = reinterpret_cast<intptr_t>(str);
- return ret;
+PP_Var VarFromUtf8(PP_Module module_id, const char* data, uint32_t len) {
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return PP_MakeNull();
+ return StringVar::StringToPPVar(module, data, len);
}
const char* VarToUtf8(PP_Var var, uint32_t* len) {
- if (var.type != PP_VARTYPE_STRING) {
+ scoped_refptr<StringVar> str(StringVar::FromPPVar(var));
+ if (!str) {
*len = 0;
return NULL;
}
- const std::string& str = GetStringUnchecked(var)->value();
- *len = static_cast<uint32_t>(str.size());
- if (str.empty())
+ *len = static_cast<uint32_t>(str->value().size());
+ if (str->value().empty())
return ""; // Don't return NULL on success.
- return str.data();
+ return str->value().data();
}
bool HasProperty(PP_Var var,
PP_Var name,
PP_Var* exception) {
- TryCatch try_catch(exception);
- if (try_catch.HasException())
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
return false;
-
- NPObject* object = GetNPObject(var);
- if (!object) {
- try_catch.SetException(kInvalidObjectException);
- return false;
- }
-
- NPIdentifier identifier = PPVarToNPIdentifier(name);
- if (!identifier) {
- try_catch.SetException(kInvalidPropertyException);
- return false;
- }
-
- return WebBindings::hasProperty(NULL, object, identifier);
+ return WebBindings::hasProperty(NULL, accessor.object()->np_object(),
+ accessor.identifier());
}
bool HasMethod(PP_Var var,
PP_Var name,
PP_Var* exception) {
- TryCatch try_catch(exception);
- if (try_catch.HasException())
- return false;
-
- NPObject* object = GetNPObject(var);
- if (!object) {
- try_catch.SetException(kInvalidObjectException);
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
return false;
- }
-
- NPIdentifier identifier = PPVarToNPIdentifier(name);
- if (!identifier) {
- try_catch.SetException(kInvalidPropertyException);
- return false;
- }
-
- return WebBindings::hasMethod(NULL, object, identifier);
+ return WebBindings::hasMethod(NULL, accessor.object()->np_object(),
+ accessor.identifier());
}
PP_Var GetProperty(PP_Var var,
PP_Var name,
PP_Var* exception) {
- TryCatch try_catch(exception);
- if (try_catch.HasException())
- return PP_MakeVoid();
-
- NPObject* object = GetNPObject(var);
- if (!object) {
- try_catch.SetException(kInvalidObjectException);
- return PP_MakeVoid();
- }
-
- NPIdentifier identifier = PPVarToNPIdentifier(name);
- if (!identifier) {
- try_catch.SetException(kInvalidPropertyException);
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
return PP_MakeVoid();
- }
NPVariant result;
- if (!WebBindings::getProperty(NULL, object, identifier, &result)) {
+ if (!WebBindings::getProperty(NULL, accessor.object()->np_object(),
+ accessor.identifier(), &result)) {
// An exception may have been raised.
- if (!try_catch.HasException())
- try_catch.SetException(kUnableToGetPropertyException);
+ accessor.SetException(kUnableToGetPropertyException);
return PP_MakeVoid();
}
- PP_Var ret = NPVariantToPPVar(&result);
+ PP_Var ret = Var::NPVariantToPPVar(accessor.object()->module(), &result);
WebBindings::releaseVariantValue(&result);
return ret;
}
@@ -605,21 +222,15 @@ void GetAllPropertyNames(PP_Var var,
*properties = NULL;
*property_count = 0;
- TryCatch try_catch(exception);
- if (try_catch.HasException())
+ ObjectAccessorTryCatch accessor(var, exception);
+ if (accessor.has_exception())
return;
- NPObject* object = GetNPObject(var);
- if (!object) {
- try_catch.SetException(kInvalidObjectException);
- return;
- }
-
NPIdentifier* identifiers = NULL;
uint32_t count = 0;
- if (!WebBindings::enumerate(NULL, object, &identifiers, &count)) {
- if (!try_catch.HasException())
- try_catch.SetException(kUnableToGetAllPropertiesException);
+ if (!WebBindings::enumerate(NULL, accessor.object()->np_object(),
+ &identifiers, &count)) {
+ accessor.SetException(kUnableToGetAllPropertiesException);
return;
}
@@ -628,8 +239,10 @@ void GetAllPropertyNames(PP_Var var,
*property_count = count;
*properties = static_cast<PP_Var*>(malloc(sizeof(PP_Var) * count));
- for (uint32_t i = 0; i < count; ++i)
- (*properties)[i] = NPIdentifierToPPVar(identifiers[i]);
+ for (uint32_t i = 0; i < count; ++i) {
+ (*properties)[i] = Var::NPIdentifierToPPVar(accessor.object()->module(),
+ identifiers[i]);
+ }
free(identifiers);
}
@@ -637,52 +250,30 @@ void SetProperty(PP_Var var,
PP_Var name,
PP_Var value,
PP_Var* exception) {
- TryCatch try_catch(exception);
- if (try_catch.HasException())
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
return;
- NPObject* object = GetNPObject(var);
- if (!object) {
- try_catch.SetException(kInvalidObjectException);
+ NPVariant variant;
+ if (!PPVarToNPVariantNoCopy(value, &variant)) {
+ accessor.SetException(kInvalidValueException);
return;
}
-
- NPIdentifier identifier = PPVarToNPIdentifier(name);
- if (!identifier) {
- try_catch.SetException(kInvalidPropertyException);
- return;
- }
-
- NPVariant variant = PPVarToNPVariantNoCopy(value);
- if (!WebBindings::setProperty(NULL, object, identifier, &variant)) {
- if (!try_catch.HasException())
- try_catch.SetException(kUnableToSetPropertyException);
- }
+ if (!WebBindings::setProperty(NULL, accessor.object()->np_object(),
+ accessor.identifier(), &variant))
+ accessor.SetException(kUnableToSetPropertyException);
}
void RemoveProperty(PP_Var var,
PP_Var name,
PP_Var* exception) {
- TryCatch try_catch(exception);
- if (try_catch.HasException())
- return;
-
- NPObject* object = GetNPObject(var);
- if (!object) {
- try_catch.SetException(kInvalidObjectException);
- return;
- }
-
- NPIdentifier identifier = PPVarToNPIdentifier(name);
- if (!identifier) {
- try_catch.SetException(kInvalidPropertyException);
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
return;
- }
- if (!WebBindings::removeProperty(NULL, object, identifier)) {
- if (!try_catch.HasException())
- try_catch.SetException(kUnableToRemovePropertyException);
- }
+ if (!WebBindings::removeProperty(NULL, accessor.object()->np_object(),
+ accessor.identifier()))
+ accessor.SetException(kUnableToRemovePropertyException);
}
PP_Var Call(PP_Var var,
@@ -690,56 +281,55 @@ PP_Var Call(PP_Var var,
uint32_t argc,
PP_Var* argv,
PP_Var* exception) {
- TryCatch try_catch(exception);
- if (try_catch.HasException())
+ ObjectAccessorTryCatch accessor(var, exception);
+ if (accessor.has_exception())
return PP_MakeVoid();
- NPObject* object = GetNPObject(var);
- if (!object) {
- try_catch.SetException(kInvalidObjectException);
- return PP_MakeVoid();
- }
-
NPIdentifier identifier;
if (method_name.type == PP_VARTYPE_VOID) {
identifier = NULL;
} else if (method_name.type == PP_VARTYPE_STRING) {
// Specifically allow only string functions to be called.
- identifier = PPVarToNPIdentifier(method_name);
+ identifier = Var::PPVarToNPIdentifier(method_name);
if (!identifier) {
- try_catch.SetException(kInvalidPropertyException);
+ accessor.SetException(kInvalidPropertyException);
return PP_MakeVoid();
}
} else {
- try_catch.SetException(kInvalidPropertyException);
+ accessor.SetException(kInvalidPropertyException);
return PP_MakeVoid();
}
scoped_array<NPVariant> args;
if (argc) {
args.reset(new NPVariant[argc]);
- for (uint32_t i = 0; i < argc; ++i)
- args[i] = PPVarToNPVariantNoCopy(argv[i]);
+ for (uint32_t i = 0; i < argc; ++i) {
+ if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
+ // This argument was invalid, throw an exception & give up.
+ accessor.SetException(kInvalidValueException);
+ return PP_MakeVoid();
+ }
+ }
}
bool ok;
NPVariant result;
if (identifier) {
- ok = WebBindings::invoke(NULL, object, identifier, args.get(), argc,
- &result);
+ ok = WebBindings::invoke(NULL, accessor.object()->np_object(),
+ identifier, args.get(), argc, &result);
} else {
- ok = WebBindings::invokeDefault(NULL, object, args.get(), argc, &result);
+ ok = WebBindings::invokeDefault(NULL, accessor.object()->np_object(),
+ args.get(), argc, &result);
}
if (!ok) {
// An exception may have been raised.
- if (!try_catch.HasException())
- try_catch.SetException(kUnableToCallMethodException);
+ accessor.SetException(kUnableToCallMethodException);
return PP_MakeVoid();
}
- PP_Var ret = NPVariantToPPVar(&result);
+ PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result);
WebBindings::releaseVariantValue(&result);
return ret;
}
@@ -748,67 +338,58 @@ PP_Var Construct(PP_Var var,
uint32_t argc,
PP_Var* argv,
PP_Var* exception) {
- TryCatch try_catch(exception);
- if (try_catch.HasException())
+ ObjectAccessorTryCatch accessor(var, exception);
+ if (accessor.has_exception())
return PP_MakeVoid();
- NPObject* object = GetNPObject(var);
- if (!object) {
- try_catch.SetException(kInvalidObjectException);
- return PP_MakeVoid();
- }
-
scoped_array<NPVariant> args;
if (argc) {
args.reset(new NPVariant[argc]);
- for (uint32_t i = 0; i < argc; ++i)
- args[i] = PPVarToNPVariantNoCopy(argv[i]);
+ for (uint32_t i = 0; i < argc; ++i) {
+ if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
+ // This argument was invalid, throw an exception & give up.
+ accessor.SetException(kInvalidValueException);
+ return PP_MakeVoid();
+ }
+ }
}
NPVariant result;
- if (!WebBindings::construct(NULL, object, args.get(), argc, &result)) {
+ if (!WebBindings::construct(NULL, accessor.object()->np_object(),
+ args.get(), argc, &result)) {
// An exception may have been raised.
- if (!try_catch.HasException())
- try_catch.SetException(kUnableToConstructException);
+ accessor.SetException(kUnableToConstructException);
return PP_MakeVoid();
}
- PP_Var ret = NPVariantToPPVar(&result);
+ PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result);
WebBindings::releaseVariantValue(&result);
return ret;
}
-bool IsInstanceOf(PP_Var var, const PPP_Class* ppp_class,
+bool IsInstanceOf(PP_Var var,
+ const PPP_Class* ppp_class,
void** ppp_class_data) {
- NPObject* object = GetNPObject(var);
+ scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var));
if (!object)
- return false;
-
- if (object->_class != &wrapper_class)
- return false;
+ return false; // Not an object at all.
- WrapperObject* wrapper = ToWrapper(object);
- if (wrapper->ppp_class != ppp_class)
- return false;
-
- if (ppp_class_data)
- *ppp_class_data = wrapper->ppp_class_data;
- return true;
+ return PluginObject::IsInstanceOf(object->np_object(),
+ ppp_class, ppp_class_data);
}
-PP_Var CreateObject(const PPP_Class* ppp_class, void* ppp_class_data) {
- NPObject* object =
- WebBindings::createObject(NULL, const_cast<NPClass*>(&wrapper_class));
- static_cast<WrapperObject*>(object)->ppp_class = ppp_class;
- static_cast<WrapperObject*>(object)->ppp_class_data = ppp_class_data;
- PP_Var ret = NPObjectToPPVar(object);
- WebBindings::releaseObject(object); // Release reference from createObject
- return ret;
+PP_Var CreateObject(PP_Module module_id,
+ const PPP_Class* ppp_class,
+ void* ppp_class_data) {
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return PP_MakeNull();
+ return PluginObject::Create(module, ppp_class, ppp_class_data);
}
const PPB_Var var_interface = {
- &AddRef,
- &Release,
+ &Var::PluginAddRefPPVar,
+ &Var::PluginReleasePPVar,
&VarFromUtf8,
&VarToUtf8,
&HasProperty,
@@ -825,33 +406,206 @@ const PPB_Var var_interface = {
} // namespace
-const PPB_Var* GetVarInterface() {
+// Var -------------------------------------------------------------------------
+
+Var::Var(PluginModule* module) : Resource(module) {
+}
+
+Var::~Var() {
+}
+
+// static
+PP_Var Var::NPVariantToPPVar(PluginModule* module, const NPVariant* variant) {
+ switch (variant->type) {
+ case NPVariantType_Void:
+ return PP_MakeVoid();
+ case NPVariantType_Null:
+ return PP_MakeNull();
+ case NPVariantType_Bool:
+ return PP_MakeBool(NPVARIANT_TO_BOOLEAN(*variant));
+ case NPVariantType_Int32:
+ return PP_MakeInt32(NPVARIANT_TO_INT32(*variant));
+ case NPVariantType_Double:
+ return PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant));
+ case NPVariantType_String:
+ return StringVar::StringToPPVar(
+ module,
+ NPVARIANT_TO_STRING(*variant).UTF8Characters,
+ NPVARIANT_TO_STRING(*variant).UTF8Length);
+ case NPVariantType_Object:
+ return ObjectVar::NPObjectToPPVar(module, NPVARIANT_TO_OBJECT(*variant));
+ }
+ NOTREACHED();
+ return PP_MakeVoid();
+}
+
+// static
+NPIdentifier Var::PPVarToNPIdentifier(PP_Var var) {
+ switch (var.type) {
+ case PP_VARTYPE_STRING: {
+ scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
+ if (!string)
+ return NULL;
+ return WebBindings::getStringIdentifier(string->value().c_str());
+ }
+ case PP_VARTYPE_INT32:
+ return WebBindings::getIntIdentifier(var.value.as_int);
+ default:
+ return NULL;
+ }
+}
+
+// static
+PP_Var Var::NPIdentifierToPPVar(PluginModule* module, NPIdentifier id) {
+ const NPUTF8* string_value = NULL;
+ int32_t int_value = 0;
+ bool is_string = false;
+ WebBindings::extractIdentifierData(id, string_value, int_value, is_string);
+ if (is_string)
+ return StringVar::StringToPPVar(module, string_value);
+
+ return PP_MakeInt32(int_value);
+}
+
+// static
+void Var::PluginAddRefPPVar(PP_Var var) {
+ if (var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT) {
+ // TODO(brettw) consider checking that the ID is actually a var ID rather
+ // than some random other resource ID.
+ if (!ResourceTracker::Get()->AddRefResource(var.value.as_id))
+ DLOG(WARNING) << "AddRefVar()ing a nonexistant string/object var.";
+ }
+}
+
+// static
+void Var::PluginReleasePPVar(PP_Var var) {
+ if (var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT) {
+ // TODO(brettw) consider checking that the ID is actually a var ID rather
+ // than some random other resource ID.
+ if (!ResourceTracker::Get()->UnrefResource(var.value.as_id))
+ DLOG(WARNING) << "ReleaseVar()ing a nonexistant string/object var.";
+ }
+}
+
+// static
+const PPB_Var* Var::GetInterface() {
return &var_interface;
}
-PP_Var NPObjectToPPVar(NPObject* object) {
+// StringVar -------------------------------------------------------------------
+
+StringVar::StringVar(PluginModule* module, const char* str, uint32 len)
+ : Var(module),
+ value_(str, len) {
+}
+
+StringVar::~StringVar() {
+}
+
+// static
+PP_Var StringVar::StringToPPVar(PluginModule* module, const std::string& var) {
+ return StringToPPVar(module, var.c_str(), var.size());
+}
+
+// static
+PP_Var StringVar::StringToPPVar(PluginModule* module,
+ const char* data, uint32 len) {
+ scoped_refptr<StringVar> str(new StringVar(module, data, len));
+ if (!str || !IsStringUTF8(str->value()))
+ return PP_MakeNull();
+
PP_Var ret;
- ret.type = PP_VARTYPE_OBJECT;
- ret.value.as_id = reinterpret_cast<intptr_t>(object);
- WebBindings::retainObject(object);
+ ret.type = PP_VARTYPE_STRING;
+
+ // The caller takes ownership now.
+ ret.value.as_id = str->GetReference();
return ret;
}
-NPObject* GetNPObject(PP_Var var) {
+// static
+scoped_refptr<StringVar> StringVar::FromPPVar(PP_Var var) {
+ if (var.type != PP_VARTYPE_STRING)
+ return scoped_refptr<StringVar>(NULL);
+ return Resource::GetAs<StringVar>(var.value.as_id);
+}
+
+// ObjectVar -------------------------------------------------------------
+
+ObjectVar::ObjectVar(PluginModule* module, NPObject* np_object)
+ : Var(module),
+ np_object_(np_object) {
+ WebBindings::retainObject(np_object_);
+ module->AddNPObjectVar(this);
+}
+
+ObjectVar::~ObjectVar() {
+ module()->RemoveNPObjectVar(this);
+ WebBindings::releaseObject(np_object_);
+}
+
+// static
+PP_Var ObjectVar::NPObjectToPPVar(PluginModule* module, NPObject* object) {
+ scoped_refptr<ObjectVar> object_var(module->ObjectVarForNPObject(object));
+ if (!object_var) // No object for this module yet, make a new one.
+ object_var = new ObjectVar(module, object);
+
+ if (!object_var)
+ return PP_MakeVoid();
+
+ // Convert to a PP_Var, GetReference will AddRef for us.
+ PP_Var result;
+ result.type = PP_VARTYPE_OBJECT;
+ result.value.as_id = object_var->GetReference();
+ return result;
+}
+
+// static
+scoped_refptr<ObjectVar> ObjectVar::FromPPVar(PP_Var var) {
if (var.type != PP_VARTYPE_OBJECT)
- return NULL;
- return GetNPObjectUnchecked(var);
+ return scoped_refptr<ObjectVar>(NULL);
+ return Resource::GetAs<ObjectVar>(var.value.as_id);
}
-PP_Var StringToPPVar(const std::string& str) {
- DCHECK(IsStringUTF8(str));
- return VarFromUtf8(str.data(), str.size());
+// TryCatch --------------------------------------------------------------------
+
+TryCatch::TryCatch(PluginModule* module, PP_Var* exception)
+ : module_(module),
+ has_exception_(exception && exception->type != PP_VARTYPE_VOID),
+ exception_(exception) {
+ WebBindings::pushExceptionHandler(&TryCatch::Catch, this);
}
-String* GetString(PP_Var var) {
- if (var.type != PP_VARTYPE_STRING)
- return NULL;
- return GetStringUnchecked(var);
+TryCatch::~TryCatch() {
+ WebBindings::popExceptionHandler();
+}
+
+void TryCatch::SetException(const char* message) {
+ if (!module_) {
+ // Don't have a module to make the string.
+ SetInvalidObjectException();
+ return;
+ }
+
+ if (!has_exception()) {
+ has_exception_ = true;
+ if (exception_)
+ *exception_ = StringVar::StringToPPVar(module_, message, strlen(message));
+ }
+}
+
+void TryCatch::SetInvalidObjectException() {
+ if (!has_exception()) {
+ has_exception_ = true;
+ // TODO(brettw) bug 54504: Have a global singleton string that can hold
+ // a generic error message.
+ if (exception_)
+ *exception_ = PP_MakeInt32(1);
+ }
+}
+
+// static
+void TryCatch::Catch(void* self, const char* message) {
+ static_cast<TryCatch*>(self)->SetException(message);
}
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_var.h b/webkit/glue/plugins/pepper_var.h
index b8c31cc..b618029 100644
--- a/webkit/glue/plugins/pepper_var.h
+++ b/webkit/glue/plugins/pepper_var.h
@@ -7,39 +7,240 @@
#include <string>
-typedef struct _pp_Var PP_Var;
-typedef struct _ppb_Var PPB_Var;
+#include "webkit/glue/plugins/pepper_resource.h"
+
+struct PP_Var;
+struct PPB_Var;
typedef struct NPObject NPObject;
typedef struct _NPVariant NPVariant;
typedef void* NPIdentifier;
namespace pepper {
-class String;
+// Var -------------------------------------------------------------------------
+
+// Represents a non-POD var. This is derived from a resource even though it
+// isn't a resource from the plugin's perspective. This allows us to re-use
+// the refcounting and the association with the module from the resource code.
+class Var : public Resource {
+ public:
+ virtual ~Var();
+
+ // Resource overrides.
+ virtual Var* AsVar() { return this; }
+
+ // Returns a PP_Var that corresponds to the given NPVariant. The contents of
+ // the NPVariant will be copied unless the NPVariant corresponds to an
+ // object. This will handle all Variant types including POD, strings, and
+ // objects.
+ //
+ // The returned PP_Var will have a refcount of 1, this passing ownership of
+ // the reference to the caller. This is suitable for returning to a plugin.
+ static PP_Var NPVariantToPPVar(PluginModule* module,
+ const NPVariant* variant);
+
+ // Returns a NPIdentifier that corresponds to the given PP_Var. The contents
+ // of the PP_Var will be copied. Returns 0 if the given PP_Var is not a a
+ // string or integer type.
+ static NPIdentifier PPVarToNPIdentifier(PP_Var var);
+
+ // Returns a PP_Var corresponding to the given identifier. In the case of
+ // a string identifier, the string will be allocated associated with the
+ // given module. A returned string will have a reference count of 1.
+ static PP_Var NPIdentifierToPPVar(PluginModule* module, NPIdentifier id);
+
+ // Provides access to the manual refcounting of a PP_Var from the plugin's
+ // perspective. This is different than the AddRef/Release on this scoped
+ // object. This uses the ResourceTracker, which keeps a separate "plugin
+ // refcount" that prevents the plugin from messing up our refcounting or
+ // freeing something out from under us.
+ //
+ // You should not generally need to use these functions. However, if you
+ // call a plugin function that returns a var, it will transfer a ref to us
+ // (the caller) which in the case of a string or object var will need to
+ // be released.
+ //
+ // Example, assuming we're expecting the plugin to return a string:
+ // PP_Var rv = some_ppp_interface->DoSomething(a, b, c);
+ //
+ // // Get the string value. This will take a reference to the object which
+ // // will prevent it from being deleted out from under us when we call
+ // // PluginReleasePPVar().
+ // scoped_refptr<StringVar> string(StringVar::FromPPVar(rv));
+ //
+ // // Release the reference the plugin gave us when returning the value.
+ // // This is legal to do for all types of vars.
+ // Var::PluginReleasePPVar(rv);
+ //
+ // // Use the string.
+ // if (!string)
+ // return false; // It didn't return a proper string.
+ // UseTheString(string->value());
+ static void PluginAddRefPPVar(PP_Var var);
+ static void PluginReleasePPVar(PP_Var var);
+
+ // Returns the PPB_Var interface for the plugin to use.
+ static const PPB_Var* GetInterface();
+
+ protected:
+ // This can only be constructed as a StringVar or an ObjectVar.
+ explicit Var(PluginModule* module);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Var);
+};
+
+// StringVar -------------------------------------------------------------------
+
+// Represents a string-based Var.
+//
+// Returning a given string as a PP_Var:
+// return StringVar::StringToPPVar(module, my_string);
+//
+// Converting a PP_Var to a string:
+// scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
+// if (!string)
+// return false; // Not a string or an invalid var.
+// DoSomethingWithTheString(string->value());
+class StringVar : public Var {
+ public:
+ StringVar(PluginModule* module, const char* str, uint32 len);
+ virtual ~StringVar();
+
+ const std::string& value() const { return value_; }
+
+ // Resource overrides.
+ virtual StringVar* AsStringVar() { return this; }
+
+ // Helper function to create a PP_Var of type string that contains a copy of
+ // the given string. The input data must be valid UTF-8 encoded text, if it
+ // is not valid UTF-8, a NULL var will be returned.
+ //
+ // The return value will have a reference count of 1. Internally, this will
+ // create a StringVar, associate it with a module, and return the reference
+ // to it in the var.
+ static PP_Var StringToPPVar(PluginModule* module, const std::string& str);
+ static PP_Var StringToPPVar(PluginModule* module,
+ const char* str, uint32 len);
+
+ // Helper function that converts a PP_Var to a string. This will return NULL
+ // if the PP_Var is not of string type or the string is invalid.
+ static scoped_refptr<StringVar> FromPPVar(PP_Var var);
+
+ private:
+ std::string value_;
+
+ DISALLOW_COPY_AND_ASSIGN(StringVar);
+};
+
+// ObjectVar -------------------------------------------------------------------
+
+// Represents a JavaScript object Var. By itself, this represents random
+// NPObjects that a given plugin (identified by the resource's module) wants to
+// reference. If two different modules reference the same NPObject (like the
+// "window" object), then there will be different ObjectVar's (and hence PP_Var
+// IDs) for each module. This allows us to track all references owned by a
+// given module and free them when the plugin exits independently of other
+// plugins that may be running at the same time.
+//
+// See StringVar for examples, except obviously using NPObjects instead of
+// strings.
+class ObjectVar : public Var {
+ public:
+ virtual ~ObjectVar();
+
+ // Resource overrides.
+ virtual ObjectVar* AsObjectVar() { return this; }
+
+ // Returns the underlying NPObject corresponding to this ObjectVar.
+ // Guaranteed non-NULL.
+ NPObject* np_object() const { return np_object_; }
+
+ // Helper function to create a PP_Var of type object that contains the given
+ // NPObject for use byt he given module. Calling this function multiple times
+ // given the same module + NPObject results in the same PP_Var, assuming that
+ // there is still a PP_Var with a reference open to it from the previous
+ // call.
+ //
+ // The module is necessary because we can have different modules pointing to
+ // the same NPObject, and we want to keep their refs separate.
+ //
+ // If no ObjectVar currently exists corresponding to the NPObject, one is
+ // created associated with the given module.
+ static PP_Var NPObjectToPPVar(PluginModule* module, NPObject* object);
+
+ // Helper function that converts a PP_Var to an object. This will return NULL
+ // if the PP_Var is not of object type or the object is invalid.
+ static scoped_refptr<ObjectVar> FromPPVar(PP_Var var);
+
+ protected:
+ // You should always use FromNPObject to create an ObjectVar. This function
+ // guarantees that we maintain the 1:1 mapping between NPObject and
+ // ObjectVar.
+ ObjectVar(PluginModule* module, NPObject* np_object);
+
+ private:
+ // Guaranteed non-NULL, this is the underlying object used by WebKit. We
+ // hold a reference to this object.
+ NPObject* np_object_;
+
+ DISALLOW_COPY_AND_ASSIGN(ObjectVar);
+};
+
+// TryCatch --------------------------------------------------------------------
+
+// Instantiate this object on the stack to catch V8 exceptions and pass them
+// to an optional out parameter supplied by the plugin.
+class TryCatch {
+ public:
+ // The given exception may be NULL if the consumer isn't interested in
+ // catching exceptions. If non-NULL, the given var will be updated if any
+ // exception is thrown (so it must outlive the TryCatch object).
+ //
+ // The module associated with the exception is passed so we know which module
+ // to associate any exception string with. It may be NULL if you don't know
+ // the module at construction time, in which case you should set it later
+ // by calling set_module().
+ //
+ // If an exception is thrown when the module is NULL, setting *any* exception
+ // will result in using the InvalidObjectException.
+ TryCatch(PluginModule* module, PP_Var* exception);
+ ~TryCatch();
+
+ // Get and set the module. This may be NULL (see the constructor).
+ PluginModule* module() { return module_; }
+ void set_module(PluginModule* module) { module_ = module; }
+
+ // Returns true is an exception has been thrown. This can be true immediately
+ // after construction if the var passed to the constructor is non-void.
+ bool has_exception() const { return has_exception_; }
+
+ // Sets the given exception. If no module has been set yet, the message will
+ // be ignored (since we have no module to associate the string with) and the
+ // SetInvalidObjectException() will be used instead.
+ //
+ // If an exception has been previously set, this function will do nothing
+ // (normally you want only the first exception).
+ void SetException(const char* message);
-// There's no class implementing Var since it could represent a number of
-// objects. Instead, we just expose a getter for the interface implemented in
-// the .cc file here.
-const PPB_Var* GetVarInterface();
+ // Sets the exception to be a generic message contained in a magic string
+ // not associated with any module.
+ void SetInvalidObjectException();
-// Returns a PP_Var of type object that wraps the given NPObject. Calling this
-// function multiple times given the same NPObject results in the same PP_Var.
-PP_Var NPObjectToPPVar(NPObject* object);
+ private:
+ static void Catch(void* self, const char* message);
-// Returns the NPObject corresponding to the PP_Var. This pointer has not been
-// retained, so you should not call WebBindings::releaseObject unless you first
-// call WebBindings::retainObject. Returns NULL if the PP_Var is not an object
-// type.
-NPObject* GetNPObject(PP_Var var);
+ PluginModule* module_;
-// Returns a PP_Var of type string that contains a copy of the given string.
-// The input data must be valid UTF-8 encoded text.
-PP_Var StringToPPVar(const std::string& str);
+ // True if an exception has been thrown. Since the exception itself may be
+ // NULL if the plugin isn't interested in getting the exception, this will
+ // always indicate if SetException has been called, regardless of whether
+ // the exception itself has been stored.
+ bool has_exception_;
-// Returns the String corresponding to the PP_Var. This pointer has not been
-// AddRef'd, so you should not call Release! Returns NULL if the PP_Var is not
-// a string type.
-String* GetString(PP_Var var);
+ // May be null if the consumer isn't interesting in catching exceptions.
+ PP_Var* exception_;
+};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_webplugin_impl.cc b/webkit/glue/plugins/pepper_webplugin_impl.cc
index df8aae0..32903b0 100644
--- a/webkit/glue/plugins/pepper_webplugin_impl.cc
+++ b/webkit/glue/plugins/pepper_webplugin_impl.cc
@@ -4,7 +4,6 @@
#include "webkit/glue/plugins/pepper_webplugin_impl.h"
-#include "base/file_path.h"
#include "base/message_loop.h"
#include "third_party/ppapi/c/pp_var.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h"
@@ -74,11 +73,16 @@ void WebPluginImpl::destroy() {
}
NPObject* WebPluginImpl::scriptableObject() {
- return GetNPObject(instance_->GetInstanceObject());
+ scoped_refptr<ObjectVar> object(
+ ObjectVar::FromPPVar(instance_->GetInstanceObject()));
+ if (object)
+ return object->np_object();
+ return NULL;
}
void WebPluginImpl::paint(WebCanvas* canvas, const WebRect& rect) {
- instance_->Paint(canvas, plugin_rect_, rect);
+ if (!instance_->IsFullscreen())
+ instance_->Paint(canvas, plugin_rect_, rect);
}
void WebPluginImpl::updateGeometry(
@@ -87,10 +91,12 @@ void WebPluginImpl::updateGeometry(
const WebVector<WebRect>& cut_outs_rects,
bool is_visible) {
plugin_rect_ = window_rect;
- instance_->ViewChanged(plugin_rect_, clip_rect);
+ if (!instance_->IsFullscreen())
+ instance_->ViewChanged(plugin_rect_, clip_rect);
}
void WebPluginImpl::updateFocus(bool focused) {
+ instance_->SetWebKitFocus(focused);
}
void WebPluginImpl::updateVisibility(bool visible) {
@@ -102,6 +108,8 @@ bool WebPluginImpl::acceptsInputEvents() {
bool WebPluginImpl::handleInputEvent(const WebKit::WebInputEvent& event,
WebKit::WebCursorInfo& cursor_info) {
+ if (instance_->IsFullscreen())
+ return false;
return instance_->HandleInputEvent(event, &cursor_info);
}
@@ -123,7 +131,7 @@ void WebPluginImpl::didReceiveData(const char* data, int data_length) {
void WebPluginImpl::didFinishLoading() {
if (document_loader_) {
- document_loader_->didFinishLoading(NULL);
+ document_loader_->didFinishLoading(NULL, 0);
document_loader_ = NULL;
}
}
diff --git a/webkit/glue/plugins/pepper_widget.cc b/webkit/glue/plugins/pepper_widget.cc
index 74b0e40..1ba5280 100644
--- a/webkit/glue/plugins/pepper_widget.cc
+++ b/webkit/glue/plugins/pepper_widget.cc
@@ -5,10 +5,10 @@
#include "webkit/glue/plugins/pepper_widget.h"
#include "base/logging.h"
+#include "third_party/ppapi/c/dev/ppb_widget_dev.h"
+#include "third_party/ppapi/c/dev/ppp_widget_dev.h"
#include "third_party/ppapi/c/pp_completion_callback.h"
#include "third_party/ppapi/c/pp_errors.h"
-#include "third_party/ppapi/c/ppb_widget.h"
-#include "third_party/ppapi/c/ppp_widget.h"
#include "webkit/glue/plugins/pepper_image_data.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
@@ -27,10 +27,13 @@ bool Paint(PP_Resource resource, const PP_Rect* rect, PP_Resource image_id) {
return false;
scoped_refptr<ImageData> image(Resource::GetAs<ImageData>(image_id));
- return widget && widget->Paint(rect, image);
+ if (!image)
+ return false;
+
+ return widget->Paint(rect, image);
}
-bool HandleEvent(PP_Resource resource, const PP_Event* event) {
+bool HandleEvent(PP_Resource resource, const PP_InputEvent* event) {
scoped_refptr<Widget> widget(Resource::GetAs<Widget>(resource));
return widget && widget->HandleEvent(event);
}
@@ -46,7 +49,7 @@ void SetLocation(PP_Resource resource, const PP_Rect* location) {
widget->SetLocation(location);
}
-const PPB_Widget ppb_widget = {
+const PPB_Widget_Dev ppb_widget = {
&IsWidget,
&Paint,
&HandleEvent,
@@ -65,7 +68,7 @@ Widget::~Widget() {
}
// static
-const PPB_Widget* Widget::GetInterface() {
+const PPB_Widget_Dev* Widget::GetInterface() {
return &ppb_widget;
}
@@ -80,8 +83,8 @@ void Widget::SetLocation(const PP_Rect* location) {
}
void Widget::Invalidate(const PP_Rect* dirty) {
- const PPP_Widget* widget = static_cast<const PPP_Widget*>(
- module()->GetPluginInterface(PPP_WIDGET_INTERFACE));
+ const PPP_Widget_Dev* widget = static_cast<const PPP_Widget_Dev*>(
+ module()->GetPluginInterface(PPP_WIDGET_DEV_INTERFACE));
if (!widget)
return;
ScopedResourceId resource(this);
diff --git a/webkit/glue/plugins/pepper_widget.h b/webkit/glue/plugins/pepper_widget.h
index 048a718..47826e3 100644
--- a/webkit/glue/plugins/pepper_widget.h
+++ b/webkit/glue/plugins/pepper_widget.h
@@ -9,8 +9,8 @@
#include "third_party/ppapi/c/pp_rect.h"
#include "webkit/glue/plugins/pepper_resource.h"
-typedef struct _ppb_Widget PPB_Widget;
-typedef struct _pp_Event PP_Event;
+struct PPB_Widget_Dev;
+struct PP_InputEvent;
namespace pepper {
@@ -24,14 +24,14 @@ class Widget : public Resource {
// Returns a pointer to the interface implementing PPB_Widget that is
// exposed to the plugin.
- static const PPB_Widget* GetInterface();
+ static const PPB_Widget_Dev* GetInterface();
// Resource overrides.
Widget* AsWidget() { return this; }
// PPB_Widget implementation.
virtual bool Paint(const PP_Rect* rect, ImageData* image) = 0;
- virtual bool HandleEvent(const PP_Event* event) = 0;
+ virtual bool HandleEvent(const PP_InputEvent* event) = 0;
bool GetLocation(PP_Rect* location);
void SetLocation(const PP_Rect* location);
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc
index fe1d7ef..a1a6d5f 100644
--- a/webkit/glue/plugins/plugin_host.cc
+++ b/webkit/glue/plugins/plugin_host.cc
@@ -13,6 +13,7 @@
#include "base/sys_info.h"
#endif
#include "base/sys_string_conversions.h"
+#include "base/utf_string_conversions.h"
#include "net/base/net_util.h"
#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h"
#include "webkit/glue/webkit_glue.h"
@@ -449,7 +450,7 @@ static NPError PostURLNotify(NPP id,
base::SysNativeMBToWide(file_path_ascii));
}
- file_util::FileInfo post_file_info = {0};
+ base::PlatformFileInfo post_file_info = {0};
if (!file_util::GetFileInfo(file_path, &post_file_info) ||
post_file_info.is_directory)
return NPERR_FILE_NOT_FOUND;
diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc
index 8506623..f7b3bf7 100644
--- a/webkit/glue/plugins/plugin_instance.cc
+++ b/webkit/glue/plugins/plugin_instance.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -8,7 +8,7 @@
#include "base/file_util.h"
#include "base/message_loop.h"
-#include "base/string_util.h"
+#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/plugins/plugin_host.h"
@@ -489,13 +489,13 @@ void PluginInstance::RequestRead(NPStream* stream, NPByteRange* range_list) {
std::string range_info = "bytes=";
while (range_list) {
- range_info += IntToString(range_list->offset);
- range_info += "-";
- range_info += IntToString(range_list->offset + range_list->length - 1);
+ range_info += base::IntToString(range_list->offset);
+ range_info.push_back('-');
+ range_info +=
+ base::IntToString(range_list->offset + range_list->length - 1);
range_list = range_list->next;
- if (range_list) {
- range_info += ",";
- }
+ if (range_list)
+ range_info.push_back(',');
}
if (plugin_data_stream_) {
diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h
index 36bf601..0dd3ee4 100644
--- a/webkit/glue/plugins/plugin_instance.h
+++ b/webkit/glue/plugins/plugin_instance.h
@@ -9,7 +9,6 @@
#define WEBKIT_GLUE_PLUGIN_PLUGIN_INSTANCE_H__
#include <map>
-#include <set>
#include <stack>
#include <string>
#include <vector>
diff --git a/webkit/glue/plugins/plugin_lib.cc b/webkit/glue/plugins/plugin_lib.cc
index 877548e..9a0770e 100644
--- a/webkit/glue/plugins/plugin_lib.cc
+++ b/webkit/glue/plugins/plugin_lib.cc
@@ -98,8 +98,9 @@ NPPluginFuncs* PluginLib::functions() {
}
NPError PluginLib::NP_Initialize() {
- LOG(INFO) << "PluginLib::NP_Initialize(" << web_plugin_info_.path.value() <<
- "): initialized=" << initialized_;
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
+ << "PluginLib::NP_Initialize(" << web_plugin_info_.path.value()
+ << "): initialized=" << initialized_;
if (initialized_)
return NPERR_NO_ERROR;
@@ -123,8 +124,9 @@ NPError PluginLib::NP_Initialize() {
}
#endif // OS_MACOSX
#endif
- LOG(INFO) << "PluginLib::NP_Initialize(" << web_plugin_info_.path.value() <<
- "): result=" << rv;
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
+ << "PluginLib::NP_Initialize(" << web_plugin_info_.path.value()
+ << "): result=" << rv;
initialized_ = (rv == NPERR_NO_ERROR);
return rv;
}
@@ -165,7 +167,7 @@ bool PluginLib::Load() {
if (!internal_) {
library = base::LoadNativeLibrary(web_plugin_info_.path);
if (library == 0) {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Couldn't load plugin " << web_plugin_info_.path.value();
return rv;
}
@@ -215,12 +217,12 @@ bool PluginLib::Load() {
if (!internal_) {
if (rv) {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Plugin " << web_plugin_info_.path.value()
<< " loaded successfully.";
library_ = library;
} else {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Plugin " << web_plugin_info_.path.value()
<< " failed to load, unloading.";
base::UnloadNativeLibrary(library);
@@ -277,14 +279,14 @@ void PluginLib::Unload() {
FreePluginLibraryTask* free_library_task =
new FreePluginLibraryTask(skip_unload_ ? NULL : library_,
entry_points_.np_shutdown);
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Scheduling delayed unload for plugin "
<< web_plugin_info_.path.value();
MessageLoop::current()->PostTask(FROM_HERE, free_library_task);
} else {
Shutdown();
if (!skip_unload_) {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Unloading plugin " << web_plugin_info_.path.value();
base::UnloadNativeLibrary(library_);
}
diff --git a/webkit/glue/plugins/plugin_lib.h b/webkit/glue/plugins/plugin_lib.h
index 647916e..ca46e41 100644
--- a/webkit/glue/plugins/plugin_lib.h
+++ b/webkit/glue/plugins/plugin_lib.h
@@ -9,13 +9,13 @@
#include <vector>
#include "base/basictypes.h"
-#include "base/file_path.h"
#include "base/native_library.h"
#include "base/ref_counted.h"
#include "build/build_config.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/webplugin.h"
+class FilePath;
struct WebPluginInfo;
namespace NPAPI {
diff --git a/webkit/glue/plugins/plugin_lib_mac.mm b/webkit/glue/plugins/plugin_lib_mac.mm
index 263b3b4..07da77c 100644
--- a/webkit/glue/plugins/plugin_lib_mac.mm
+++ b/webkit/glue/plugins/plugin_lib_mac.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -9,6 +9,7 @@
#include "base/native_library.h"
#include "base/scoped_cftyperef.h"
#include "base/scoped_ptr.h"
+#include "base/string_split.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
diff --git a/webkit/glue/plugins/plugin_lib_posix.cc b/webkit/glue/plugins/plugin_lib_posix.cc
index dbc64ed..fb813b6 100644
--- a/webkit/glue/plugins/plugin_lib_posix.cc
+++ b/webkit/glue/plugins/plugin_lib_posix.cc
@@ -17,6 +17,7 @@
#include "base/eintr_wrapper.h"
#include "base/file_util.h"
+#include "base/string_split.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
@@ -118,14 +119,14 @@ void UnwrapNSPluginWrapper(void **dl, FilePath* unwrapped_path) {
if (!newdl) {
// We couldn't load the unwrapped plugin for some reason, despite
// being able to load the wrapped one. Just use the wrapped one.
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Could not use unwrapped nspluginwrapper plugin "
<< unwrapped_path->value() << ", using the wrapped one.";
return;
}
// Unload the wrapped plugin, and use the wrapped plugin instead.
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Using unwrapped version " << unwrapped_path->value()
<< " of nspluginwrapper-wrapped plugin.";
base::UnloadNativeLibrary(*dl);
@@ -144,7 +145,7 @@ bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
// Skip files that aren't appropriate for our architecture.
if (!ELFMatchesCurrentArchitecture(filename)) {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Skipping plugin " << filename.value()
<< " because it doesn't match the current architecture.";
return false;
@@ -152,7 +153,7 @@ bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
void* dl = base::LoadNativeLibrary(filename);
if (!dl) {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "While reading plugin info, unable to load library "
<< filename.value() << ", skipping.";
return false;
@@ -193,12 +194,12 @@ bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
if (description)
info->desc = UTF8ToUTF16(description);
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Got info for plugin " << filename.value()
<< " Name = \"" << UTF16ToUTF8(info->name)
<< "\", Description = \"" << UTF16ToUTF8(info->desc) << "\".";
} else {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Plugin " << filename.value()
<< " has no GetValue() and probably won't work.";
}
diff --git a/webkit/glue/plugins/plugin_lib_unittest.cc b/webkit/glue/plugins/plugin_lib_unittest.cc
index a52510b..5ac6bdc 100644
--- a/webkit/glue/plugins/plugin_lib_unittest.cc
+++ b/webkit/glue/plugins/plugin_lib_unittest.cc
@@ -5,6 +5,7 @@
#include "webkit/glue/plugins/plugin_lib.h"
#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/webkit/glue/plugins/plugin_lib_win.cc b/webkit/glue/plugins/plugin_lib_win.cc
index 00f6243..382c2c8 100644
--- a/webkit/glue/plugins/plugin_lib_win.cc
+++ b/webkit/glue/plugins/plugin_lib_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -6,12 +6,13 @@
#include "base/file_version_info.h"
#include "base/file_version_info_win.h"
+#include "base/logging.h"
#include "base/path_service.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_list.h"
-namespace NPAPI
-{
+namespace NPAPI {
+
bool PluginLib::ReadWebPluginInfo(const FilePath &filename,
WebPluginInfo* info) {
// On windows, the way we get the mime types for the library is
@@ -21,8 +22,12 @@ bool PluginLib::ReadWebPluginInfo(const FilePath &filename,
// video/quicktime|audio/aiff|image/jpeg
scoped_ptr<FileVersionInfo> version_info(
FileVersionInfo::CreateFileVersionInfo(filename.value()));
- if (!version_info.get())
+ if (!version_info.get()) {
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
+ << "Could not get version info for plugin "
+ << filename.value();
return false;
+ }
FileVersionInfoWin* version_info_win =
static_cast<FileVersionInfoWin*>(version_info.get());
diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc
index a3412d7..b2a7634 100644
--- a/webkit/glue/plugins/plugin_list.cc
+++ b/webkit/glue/plugins/plugin_list.cc
@@ -9,9 +9,9 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
-#include "base/time.h"
#include "googleurl/src/gurl.h"
#include "net/base/mime_util.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
@@ -45,8 +45,11 @@ void PluginList::RefreshPlugins() {
}
void PluginList::AddExtraPluginPath(const FilePath& plugin_path) {
+ // Chrome OS only loads plugins from /opt/google/chrome/plugins.
+#if !defined(OS_CHROMEOS)
AutoLock lock(lock_);
extra_plugin_paths_.push_back(plugin_path);
+#endif
}
void PluginList::RemoveExtraPluginPath(const FilePath& plugin_path) {
@@ -59,8 +62,11 @@ void PluginList::RemoveExtraPluginPath(const FilePath& plugin_path) {
}
void PluginList::AddExtraPluginDir(const FilePath& plugin_dir) {
+ // Chrome OS only loads plugins from /opt/google/chrome/plugins.
+#if !defined(OS_CHROMEOS)
AutoLock lock(lock_);
extra_plugin_dirs_.push_back(plugin_dir);
+#endif
}
void PluginList::RegisterInternalPlugin(const PluginVersionInfo& info) {
@@ -108,8 +114,11 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi,
info->mime_types.clear();
- if (mime_types.empty())
+ if (mime_types.empty()) {
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
+ << "Plugin " << pvi.product_name << " has no MIME types, skipping";
return false;
+ }
info->name = WideToUTF16(pvi.product_name);
info->desc = WideToUTF16(pvi.file_description);
@@ -168,8 +177,6 @@ void PluginList::LoadPlugins(bool refresh) {
internal_plugins = internal_plugins_;
}
- base::TimeTicks start_time = base::TimeTicks::Now();
-
std::vector<WebPluginInfo> new_plugins;
std::set<FilePath> visited_plugins;
@@ -209,10 +216,6 @@ void PluginList::LoadPlugins(bool refresh) {
if (webkit_glue::IsDefaultPluginEnabled())
LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins);
- base::TimeTicks end_time = base::TimeTicks::Now();
- base::TimeDelta elapsed = end_time - start_time;
- DLOG(INFO) << "Loaded plugin list in " << elapsed.InMilliseconds() << " ms.";
-
// Only update the data now since loading plugins can take a while.
AutoLock lock(lock_);
@@ -230,6 +233,9 @@ void PluginList::LoadPlugins(bool refresh) {
void PluginList::LoadPlugin(const FilePath& path,
std::vector<WebPluginInfo>* plugins) {
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
+ << "Loading plugin " << path.value();
+
WebPluginInfo plugin_info;
const PluginEntryPoints* entry_points;
diff --git a/webkit/glue/plugins/plugin_list_mac.mm b/webkit/glue/plugins/plugin_list_mac.mm
index 16bde9d..ee6c6ad 100644
--- a/webkit/glue/plugins/plugin_list_mac.mm
+++ b/webkit/glue/plugins/plugin_list_mac.mm
@@ -92,6 +92,14 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
if (IsBlacklistedPlugin(info))
return false;
+ // Flip4Mac has a reproducible hang during a synchronous call from the render
+ // with certain content types (as well as a common crash). Disable by default
+ // to minimize those issues, but don't blacklist it so that users can choose
+ // to enable it.
+ if (StartsWith(info.name, ASCIIToUTF16("Flip4Mac Windows Media Plugin"),
+ false))
+ DisablePlugin(info.path);
+
// Hierarchy check
// (we're loading plugins hierarchically from Library folders, so plugins we
// encounter earlier must override plugins we encounter later)
diff --git a/webkit/glue/plugins/plugin_list_posix.cc b/webkit/glue/plugins/plugin_list_posix.cc
index 1fbd76f..b23909b 100644
--- a/webkit/glue/plugins/plugin_list_posix.cc
+++ b/webkit/glue/plugins/plugin_list_posix.cc
@@ -7,6 +7,7 @@
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/sha1.h"
+#include "base/string_split.h"
#include "base/string_util.h"
#include "build/build_config.h"
@@ -121,6 +122,8 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
PathService::Get(base::DIR_EXE, &dir);
plugin_dirs->push_back(dir.Append("plugins"));
+ // Chrome OS only loads plugins from /opt/google/chrome/plugins.
+#if !defined(OS_CHROMEOS)
// Mozilla code to reference:
// http://mxr.mozilla.org/firefox/ident?i=NS_APP_PLUGINS_DIR_LIST
// and tens of accompanying files (mxr is very helpful).
@@ -156,7 +159,8 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
plugin_dirs->push_back(FilePath("/usr/lib64/mozilla/plugins"));
plugin_dirs->push_back(FilePath("/usr/lib64/firefox/plugins"));
plugin_dirs->push_back(FilePath("/usr/lib64/xulrunner-addons/plugins"));
-#endif
+#endif // defined(ARCH_CPU_64_BITS)
+#endif // !defined(OS_CHROMEOS)
}
void PluginList::LoadPluginsFromDir(const FilePath& dir_path,
@@ -183,18 +187,18 @@ void PluginList::LoadPluginsFromDir(const FilePath& dir_path,
// symlinks.
FilePath orig_path = path;
file_util::AbsolutePath(&path);
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Resolved " << orig_path.value() << " -> " << path.value();
if (visited_plugins->find(path) != visited_plugins->end()) {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Skipping duplicate instance of " << path.value();
continue;
}
visited_plugins->insert(path);
if (IsBlacklistedPlugin(path)) {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Skipping blacklisted plugin " << path.value();
continue;
}
@@ -209,14 +213,15 @@ void PluginList::LoadPluginsFromDir(const FilePath& dir_path,
// Go back to the old path.
path = orig_path;
} else {
- LOG(ERROR) << "Flash misbehaves when used from a directory containing "
- << kNetscapeInPath << ", so skipping " << orig_path.value();
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
+ << "Flash misbehaves when used from a directory containing "
+ << kNetscapeInPath << ", so skipping " << orig_path.value();
continue;
}
}
// Get mtime.
- file_util::FileInfo info;
+ base::PlatformFileInfo info;
if (!file_util::GetFileInfo(path, &info))
continue;
@@ -232,14 +237,13 @@ void PluginList::LoadPluginsFromDir(const FilePath& dir_path,
}
}
-
bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
std::vector<WebPluginInfo>* plugins) {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Considering " << info.path.value() << " (" << info.name << ")";
if (IsUndesirablePlugin(info)) {
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< info.path.value() << " is undesirable.";
// See if we have a better version of this plugin.
@@ -248,7 +252,7 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
!IsUndesirablePlugin(plugins->at(i))) {
// Skip the current undesirable one so we can use the better one
// we just found.
- LOG_IF(INFO, PluginList::DebugPluginLoading())
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Skipping " << info.path.value() << ", preferring "
<< plugins->at(i).path.value();
return false;
diff --git a/webkit/glue/plugins/plugin_list_win.cc b/webkit/glue/plugins/plugin_list_win.cc
index 1c91916..b5ded9e 100644
--- a/webkit/glue/plugins/plugin_list_win.cc
+++ b/webkit/glue/plugins/plugin_list_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -14,6 +14,8 @@
#include "base/path_service.h"
#include "base/registry.h"
#include "base/scoped_ptr.h"
+#include "base/string_number_conversions.h"
+#include "base/string_split.h"
#include "base/string_util.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_lib.h"
@@ -65,7 +67,7 @@ bool GetInstalledPath(const TCHAR* app, FilePath* out) {
reg_path.append(L"\\");
reg_path.append(app);
- RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str());
+ RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str(), KEY_READ);
std::wstring path;
if (key.ReadValue(kRegistryPath, &path)) {
*out = FilePath(path);
@@ -86,7 +88,7 @@ void GetPluginsInRegistryDirectory(
std::wstring reg_path = registry_folder;
reg_path.append(L"\\");
reg_path.append(iter.Name());
- RegKey key(root_key, reg_path.c_str());
+ RegKey key(root_key, reg_path.c_str(), KEY_READ);
std::wstring path;
if (key.ReadValue(kRegistryPath, &path))
@@ -313,8 +315,10 @@ bool IsNewerVersion(const std::wstring& a, const std::wstring& b) {
if (a_ver.size() != b_ver.size())
return false;
for (size_t i = 0; i < a_ver.size(); i++) {
- int cur_a = StringToInt(a_ver[i]);
- int cur_b = StringToInt(b_ver[i]);
+ int cur_a, cur_b;
+ base::StringToInt(a_ver[i], &cur_a);
+ base::StringToInt(b_ver[i], &cur_b);
+
if (cur_a > cur_b)
return false;
if (cur_a < cur_b)
@@ -370,9 +374,9 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
SplitString(info.version, '.', &ver);
int major, minor, update;
if (ver.size() == 4 &&
- StringToInt(ver[0], &major) &&
- StringToInt(ver[1], &minor) &&
- StringToInt(ver[2], &update)) {
+ base::StringToInt(ver[0], &major) &&
+ base::StringToInt(ver[1], &minor) &&
+ base::StringToInt(ver[2], &update)) {
if (major == 6 && minor == 0 && update < 120)
return false; // Java SE6 Update 11 or older.
}
diff --git a/webkit/glue/plugins/plugin_stream.h b/webkit/glue/plugins/plugin_stream.h
index f15ea66..c17faaf 100644
--- a/webkit/glue/plugins/plugin_stream.h
+++ b/webkit/glue/plugins/plugin_stream.h
@@ -2,13 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef WEBKIT_GLUE_PLUGIN_PLUGIN_STREAM_H__
-#define WEBKIT_GLUE_PLUGIN_PLUGIN_STREAM_H__
+#ifndef WEBKIT_GLUE_PLUGINS_PLUGIN_STREAM_H_
+#define WEBKIT_GLUE_PLUGINS_PLUGIN_STREAM_H_
+
+#include "build/build_config.h"
#include <string>
#include <vector>
+#if defined(OS_POSIX)
#include "base/file_path.h"
+#endif
#include "base/ref_counted.h"
#include "third_party/npapi/bindings/npapi.h"
@@ -110,7 +114,8 @@ class PluginStream : public base::RefCounted<PluginStream> {
// Send the data to the plugin, returning how many bytes it accepted, or -1
// if an error occurred.
- int TryWriteToPlugin(const char *buf, const int length, const int data_offset);
+ int TryWriteToPlugin(const char *buf, const int length,
+ const int data_offset);
// The callback which calls TryWriteToPlugin.
void OnDelayDelivery();
@@ -141,6 +146,6 @@ class PluginStream : public base::RefCounted<PluginStream> {
DISALLOW_COPY_AND_ASSIGN(PluginStream);
};
-} // namespace NPAPI
+} // namespace NPAPI
-#endif // WEBKIT_GLUE_PLUGIN_PLUGIN_STREAM_H__
+#endif // WEBKIT_GLUE_PLUGINS_PLUGIN_STREAM_H_
diff --git a/webkit/glue/plugins/ppb_private.h b/webkit/glue/plugins/ppb_private.h
index a0956f0..218f73a 100644
--- a/webkit/glue/plugins/ppb_private.h
+++ b/webkit/glue/plugins/ppb_private.h
@@ -5,17 +5,103 @@
#ifndef WEBKIT_GLUE_PLUGINS_PPB_PRIVATE_H_
#define WEBKIT_GLUE_PLUGINS_PPB_PRIVATE_H_
+#include "third_party/ppapi/c/pp_module.h"
#include "third_party/ppapi/c/pp_var.h"
#define PPB_PRIVATE_INTERFACE "PPB_Private;1"
-typedef enum _pp_ResourceString {
+typedef enum {
PP_RESOURCESTRING_PDFGETPASSWORD = 0,
} PP_ResourceString;
-typedef struct _ppb_Private {
+typedef enum {
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTH = 0,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTH_HOVER = 1,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTH_PRESSED = 2,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW = 3,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER = 4,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED = 5,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN = 6,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER = 7,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED = 8,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT = 9,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER = 10,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED = 11,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0 = 12,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1 = 13,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2 = 14,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3 = 15,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4 = 16,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5 = 17,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6 = 18,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7 = 19,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8 = 20,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9 = 21,
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND = 22,
+} PP_ResourceImage;
+
+typedef enum {
+ PP_PRIVATEFONTPITCH_DEFAULT = 0,
+ PP_PRIVATEFONTPITCH_FIXED = 1
+} PP_PrivateFontPitch;
+
+typedef enum {
+ PP_PRIVATEFONTFAMILY_DEFAULT = 0,
+ PP_PRIVATEFONTFAMILY_ROMAN = 1,
+ PP_PRIVATEFONTFAMILY_SCRIPT = 2
+} PP_PrivateFontFamily;
+
+typedef enum {
+ PP_PRIVATEFONTCHARSET_ANSI = 0,
+ PP_PRIVATEFONTCHARSET_DEFAULT = 1,
+ PP_PRIVATEFONTCHARSET_SYMBOL = 2,
+ PP_PRIVATEFONTCHARSET_MAC = 77,
+ PP_PRIVATEFONTCHARSET_SHIFTJIS = 128,
+ PP_PRIVATEFONTCHARSET_HANGUL = 129,
+ PP_PRIVATEFONTCHARSET_JOHAB = 130,
+ PP_PRIVATEFONTCHARSET_GB2312 =134,
+ PP_PRIVATEFONTCHARSET_CHINESEBIG5 = 136,
+ PP_PRIVATEFONTCHARSET_GREEK = 161,
+ PP_PRIVATEFONTCHARSET_TURKISH = 162,
+ PP_PRIVATEFONTCHARSET_VIETNAMESE = 163,
+ PP_PRIVATEFONTCHARSET_HEBREW = 177,
+ PP_PRIVATEFONTCHARSET_ARABIC = 178,
+ PP_PRIVATEFONTCHARSET_BALTIC = 186,
+ PP_PRIVATEFONTCHARSET_RUSSIAN = 204,
+ PP_PRIVATEFONTCHARSET_THAI = 222,
+ PP_PRIVATEFONTCHARSET_EASTEUROPE = 238,
+ PP_PRIVATEFONTCHARSET_OEM = 255
+} PP_PrivateFontCharset;
+
+struct PP_PrivateFontFileDescription {
+ const char* face;
+ uint32_t weight;
+ bool italic;
+ PP_PrivateFontPitch pitch;
+ PP_PrivateFontFamily family;
+ PP_PrivateFontCharset charset;
+};
+
+struct PPB_Private {
// Returns a localized string.
- PP_Var (*GetLocalizedString)(PP_ResourceString string_id);
-} PPB_Private;
+ PP_Var (*GetLocalizedString)(PP_Module module, PP_ResourceString string_id);
+
+ // Returns a resource image.
+ PP_Resource (*GetResourceImage)(PP_Module module,
+ PP_ResourceImage image_id);
+
+ // Returns a resource identifying a font file corresponding to the given font
+ // request after applying the browser-specific fallback. Linux only.
+ PP_Resource (*GetFontFileWithFallback)(
+ PP_Module module,
+ const PP_PrivateFontFileDescription* description);
+
+ // Given a resource previously returned by GetFontFileWithFallback, returns
+ // a pointer to the requested font table. Linux only.
+ bool (*GetFontTableForPrivateFontFile)(PP_Resource font_file,
+ uint32_t table,
+ void* output,
+ uint32_t* output_length);
+};
#endif // WEBKIT_GLUE_PLUGINS_PPB_PRIVATE_H_
diff --git a/webkit/glue/plugins/test/npapi_test.cc b/webkit/glue/plugins/test/npapi_test.cc
index d7c4fa7..895a842 100644
--- a/webkit/glue/plugins/test/npapi_test.cc
+++ b/webkit/glue/plugins/test/npapi_test.cc
@@ -66,13 +66,55 @@ EXPORT NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* pFuncs) {
return NPAPIClient::PluginClient::GetEntryPoints(pFuncs);
}
-EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* pFuncs) {
- return NPAPIClient::PluginClient::Initialize(pFuncs);
-}
-
EXPORT NPError API_CALL NP_Shutdown() {
return NPAPIClient::PluginClient::Shutdown();
}
+
+#if defined(OS_WIN) || defined(OS_MACOSX)
+EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnFuncs) {
+ return NPAPIClient::PluginClient::Initialize(npnFuncs);
+}
+#elif defined(OS_POSIX)
+EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnFuncs,
+ NPPluginFuncs* nppFuncs) {
+ NPError error = NPAPIClient::PluginClient::Initialize(npnFuncs);
+ if (error == NPERR_NO_ERROR) {
+ error = NP_GetEntryPoints(nppFuncs);
+ }
+ return error;
+}
+
+EXPORT NPError API_CALL NP_GetValue(NPP instance, NPPVariable variable,
+ void* value) {
+ NPError err = NPERR_NO_ERROR;
+
+ switch (variable) {
+ case NPPVpluginNameString:
+ *(static_cast<const char**>(value)) = "NPAPI Test Plugin";
+ break;
+ case NPPVpluginDescriptionString:
+ *(static_cast<const char**>(value)) =
+ "Simple NPAPI plug-in for Chromium unit tests";
+ break;
+ case NPPVpluginNeedsXEmbed:
+ *(static_cast<NPBool*>(value)) = true;
+ break;
+ default:
+ err = NPERR_GENERIC_ERROR;
+ break;
+ }
+
+ return err;
+}
+
+EXPORT const char* API_CALL NP_GetMIMEDescription(void) {
+ // The layout test LayoutTests/fast/js/navigator-mimeTypes-length.html
+ // asserts that the number of mimetypes handled by plugins should be
+ // greater than the number of plugins. We specify a mimetype here so
+ // this plugin has at least one.
+ return "application/vnd.npapi-test:npapitest:test npapi";
+}
+#endif // OS_POSIX
} // extern "C"
namespace WebCore {
diff --git a/webkit/glue/plugins/test/plugin_arguments_test.cc b/webkit/glue/plugins/test/plugin_arguments_test.cc
index ee6d2c0..46ccf43 100644
--- a/webkit/glue/plugins/test/plugin_arguments_test.cc
+++ b/webkit/glue/plugins/test/plugin_arguments_test.cc
@@ -1,9 +1,10 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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 "base/basictypes.h"
#include "base/string_util.h"
+#include "base/stringprintf.h"
#include "webkit/glue/plugins/test/plugin_arguments_test.h"
@@ -45,7 +46,7 @@ NPError PluginArgumentsTest::New(uint16 mode, int16 argc,
int size = atoi(size_string);
for (int index = 1; index <= max_args; index++) {
- std::string arg_name = StringPrintf("%s%d", "val", index);
+ std::string arg_name = base::StringPrintf("%s%d", "val", index);
const char *val_string = GetArgValue(arg_name.c_str(), argc, argn,
argv);
ExpectAsciiStringNotEqual(val_string, (const char*)NULL);
diff --git a/webkit/glue/plugins/test/plugin_geturl_test.cc b/webkit/glue/plugins/test/plugin_geturl_test.cc
index f321b4b..aedf582 100644
--- a/webkit/glue/plugins/test/plugin_geturl_test.cc
+++ b/webkit/glue/plugins/test/plugin_geturl_test.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -8,6 +8,8 @@
#include "base/basictypes.h"
#include "base/file_util.h"
+#include "base/string_number_conversions.h"
+#include "base/utf_string_conversions.h"
// url for "self". The %22%22 is to make a statement for javascript to
// evaluate and return.
@@ -357,7 +359,7 @@ void PluginGetURLTest::URLNotify(const char* url, NPReason reason, void* data) {
case BOGUS_URL_STREAM_ID:
if (reason != NPRES_NETWORK_ERR) {
std::string err = "BOGUS_URL received unexpected URLNotify status: ";
- err.append(IntToString(reason));
+ err.append(base::IntToString(reason));
SetError(err);
}
tests_in_progress_--;
diff --git a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc
index b62a764..10b3239 100644
--- a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc
+++ b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc
@@ -17,7 +17,8 @@ NPObjectDeletePluginInNPN_Evaluate*
NPObjectLifetimeTest::NPObjectLifetimeTest(NPP id,
NPNetscapeFuncs *host_functions)
: PluginTest(id, host_functions),
- other_plugin_instance_object_(NULL) {
+ other_plugin_instance_object_(NULL),
+ timer_id_(0) {
}
NPError NPObjectLifetimeTest::SetWindow(NPWindow* pNPWindow) {
@@ -30,8 +31,8 @@ NPError NPObjectLifetimeTest::SetWindow(NPWindow* pNPWindow) {
// We attempt to retreive the NPObject for the plugin instance identified
// by the NPObjectLifetimeTestInstance2 class as it may not have been
// instantiated yet.
- SetTimer(window_handle, kNPObjectLifetimeTimer, kNPObjectLifetimeTimerElapse,
- TimerProc);
+ timer_id_ = SetTimer(window_handle, kNPObjectLifetimeTimer,
+ kNPObjectLifetimeTimerElapse, TimerProc);
}
return NPERR_NO_ERROR;
}
@@ -40,10 +41,11 @@ void CALLBACK NPObjectLifetimeTest::TimerProc(
HWND window, UINT message, UINT timer_id,
unsigned long elapsed_milli_seconds) {
- KillTimer(window, kNPObjectLifetimeTimer);
NPObjectLifetimeTest* this_instance =
reinterpret_cast<NPObjectLifetimeTest*>
(::GetProp(window, L"Plugin_Instance"));
+ KillTimer(window, this_instance->timer_id_);
+ this_instance->timer_id_ = 0;
this_instance->other_plugin_instance_object_ =
NPObjectLifetimeTestInstance2::plugin_instance_object_;
@@ -107,7 +109,7 @@ NPObjectDeletePluginInNPN_Evaluate::NPObjectDeletePluginInNPN_Evaluate(
NPP id, NPNetscapeFuncs *host_functions)
: PluginTest(id, host_functions),
plugin_instance_object_(NULL),
- npn_evaluate_timer_proc_set_(false) {
+ timer_id_(0) {
g_npn_evaluate_test_instance_ = this;
}
@@ -128,12 +130,10 @@ NPError NPObjectDeletePluginInNPN_Evaluate::SetWindow(NPWindow* np_window) {
// while it is being used in webkit as this leads to crashes and is a
// more accurate representation of the renderer crash as described in
// http://b/issue?id=1134683.
- if (!npn_evaluate_timer_proc_set_) {
- npn_evaluate_timer_proc_set_ = true;
- SetTimer(window_handle, kNPObjectLifetimeTimer, kNPObjectLifetimeTimerElapse,
- TimerProc);
+ if (!timer_id_) {
+ timer_id_ = SetTimer(window_handle, kNPObjectLifetimeTimer,
+ kNPObjectLifetimeTimerElapse, TimerProc);
}
-
return NPERR_NO_ERROR;
}
@@ -141,7 +141,8 @@ void CALLBACK NPObjectDeletePluginInNPN_Evaluate::TimerProc(
HWND window, UINT message, UINT timer_id,
unsigned long elapsed_milli_seconds) {
- KillTimer(window, kNPObjectLifetimeTimer);
+ KillTimer(window, g_npn_evaluate_test_instance_->timer_id_);
+ g_npn_evaluate_test_instance_->timer_id_ = 0;
NPObject *window_obj = NULL;
g_npn_evaluate_test_instance_->HostFunctions()->getvalue(
g_npn_evaluate_test_instance_->id(), NPNVWindowNPObject,
diff --git a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.h b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.h
index 4303d99..60d0314 100644
--- a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.h
+++ b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.h
@@ -30,6 +30,7 @@ class NPObjectLifetimeTest : public PluginTest {
#if defined(OS_WIN)
static void CALLBACK TimerProc(HWND window, UINT message, UINT timer_id,
unsigned long elapsed_milli_seconds);
+ UINT_PTR timer_id_;
#endif
DISALLOW_IMPLICIT_CONSTRUCTORS(NPObjectLifetimeTest);
};
@@ -67,10 +68,10 @@ class NPObjectDeletePluginInNPN_Evaluate : public PluginTest {
#if defined(OS_WIN)
static void CALLBACK TimerProc(HWND window, UINT message, UINT timer_id,
unsigned long elapsed_milli_seconds);
+ UINT_PTR timer_id_;
#endif
private:
- bool npn_evaluate_timer_proc_set_;
static NPObjectDeletePluginInNPN_Evaluate* g_npn_evaluate_test_instance_;
DISALLOW_IMPLICIT_CONSTRUCTORS(NPObjectDeletePluginInNPN_Evaluate);
diff --git a/webkit/glue/plugins/test/plugin_schedule_timer_test.h b/webkit/glue/plugins/test/plugin_schedule_timer_test.h
index 9ca947f..e3e6505 100644
--- a/webkit/glue/plugins/test/plugin_schedule_timer_test.h
+++ b/webkit/glue/plugins/test/plugin_schedule_timer_test.h
@@ -1,12 +1,10 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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 WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_SCHEDULE_TIMER_TEST_H
#define WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_SCHEDULE_TIMER_TEST_H
-#include <vector>
-
#include "base/at_exit.h"
#include "base/time.h"
#include "webkit/glue/plugins/test/plugin_test.h"
diff --git a/webkit/glue/plugins/test/plugin_test.h b/webkit/glue/plugins/test/plugin_test.h
index f06307e..eed6e3f 100644
--- a/webkit/glue/plugins/test/plugin_test.h
+++ b/webkit/glue/plugins/test/plugin_test.h
@@ -1,12 +1,13 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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 WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H__
-#define WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H__
+#ifndef WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H_
+#define WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H_
#include <string>
+#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "third_party/npapi/bindings/npapi.h"
#include "third_party/npapi/bindings/nphostapi.h"
@@ -82,9 +83,9 @@ class PluginTest {
if (val1 != val2) {
std::string err;
err = "Expected Equal for '";
- err.append(IntToString(val1));
+ err.append(base::IntToString(val1));
err.append("' and '");
- err.append(IntToString(val2));
+ err.append(base::IntToString(val2));
err.append("'");
SetError(err);
}
@@ -128,4 +129,4 @@ class PluginTest {
} // namespace NPAPIClient
-#endif // WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H__
+#endif // WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H_
diff --git a/webkit/glue/plugins/test/plugin_test_factory.cc b/webkit/glue/plugins/test/plugin_test_factory.cc
index e2b42b3..62a3977 100644
--- a/webkit/glue/plugins/test/plugin_test_factory.cc
+++ b/webkit/glue/plugins/test/plugin_test_factory.cc
@@ -66,7 +66,8 @@ PluginTest* CreatePluginTest(const std::string& test_name,
new_test = new NPObjectLifetimeTestInstance2(instance, host_functions);
} else if (test_name == "new_fails") {
new_test = new NewFailsTest(instance, host_functions);
- } else if (test_name == "npobject_delete_plugin_in_evaluate") {
+ } else if (test_name == "npobject_delete_plugin_in_evaluate" ||
+ test_name == "npobject_delete_create_plugin_in_evaluate") {
new_test = new NPObjectDeletePluginInNPN_Evaluate(instance, host_functions);
#endif
} else if (test_name == "plugin_javascript_open_popup_with_plugin") {
@@ -86,7 +87,8 @@ PluginTest* CreatePluginTest(const std::string& test_name,
} else if (test_name == "hidden_plugin" ||
test_name == "create_instance_in_paint" ||
test_name == "alert_in_window_message" ||
- test_name == "ensure_scripting_works_in_destroy") {
+ test_name == "ensure_scripting_works_in_destroy" ||
+ test_name == "invoke_js_function_on_create") {
new_test = new WindowedPluginTest(instance, host_functions);
#endif
}
diff --git a/webkit/glue/plugins/test/plugin_thread_async_call_test.cc b/webkit/glue/plugins/test/plugin_thread_async_call_test.cc
index 2e9f9e9..c01a49e 100644
--- a/webkit/glue/plugins/test/plugin_thread_async_call_test.cc
+++ b/webkit/glue/plugins/test/plugin_thread_async_call_test.cc
@@ -4,6 +4,7 @@
#include "webkit/glue/plugins/test/plugin_thread_async_call_test.h"
+#include "base/at_exit.h"
#include "base/message_loop.h"
#include "base/thread.h"
#include "webkit/glue/plugins/test/plugin_client.h"
diff --git a/webkit/glue/plugins/test/plugin_thread_async_call_test.h b/webkit/glue/plugins/test/plugin_thread_async_call_test.h
index 020e5e1..78e4e8d 100644
--- a/webkit/glue/plugins/test/plugin_thread_async_call_test.h
+++ b/webkit/glue/plugins/test/plugin_thread_async_call_test.h
@@ -1,16 +1,17 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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 WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H
-#define WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H
+#ifndef WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H_
+#define WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H_
-#include <vector>
-
-#include "base/at_exit.h"
#include "base/scoped_ptr.h"
#include "webkit/glue/plugins/test/plugin_test.h"
+namespace base {
+class AtExitManager;
+}
+
namespace NPAPIClient {
// This class tests scheduling and unscheduling of async callbacks using
@@ -35,4 +36,4 @@ class PluginThreadAsyncCallTest : public PluginTest {
} // namespace NPAPIClient
-#endif // WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H
+#endif // WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H_
diff --git a/webkit/glue/plugins/test/plugin_windowed_test.cc b/webkit/glue/plugins/test/plugin_windowed_test.cc
index 5ae8e30..461fc20 100644
--- a/webkit/glue/plugins/test/plugin_windowed_test.cc
+++ b/webkit/glue/plugins/test/plugin_windowed_test.cc
@@ -36,7 +36,8 @@ NPError WindowedPluginTest::SetWindow(NPWindow* pNPWindow) {
}
if ((test_name() == "create_instance_in_paint" && test_id() == "1") ||
- test_name() == "alert_in_window_message") {
+ test_name() == "alert_in_window_message" ||
+ test_name() == "invoke_js_function_on_create") {
static ATOM window_class = 0;
if (!window_class) {
WNDCLASSEX wcex;
@@ -130,6 +131,11 @@ LRESULT CALLBACK WindowedPluginTest::WindowProc(
// and verify that we don't hang the browser.
CallJSFunction(this_ptr, "CallAlert");
CallJSFunction(this_ptr, "CallAlert");
+ } else if (this_ptr->test_name() ==
+ "invoke_js_function_on_create" &&
+ message == WM_PAINT) {
+ this_ptr->done_ = true;
+ CallJSFunction(this_ptr, "PluginCreated");
}
}
diff --git a/webkit/glue/plugins/test/plugin_windowless_test.cc b/webkit/glue/plugins/test/plugin_windowless_test.cc
index c47c1d7..aa6a9d7 100644
--- a/webkit/glue/plugins/test/plugin_windowless_test.cc
+++ b/webkit/glue/plugins/test/plugin_windowless_test.cc
@@ -1,8 +1,9 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
#define STRSAFE_NO_DEPRECATE
+#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "webkit/glue/plugins/test/plugin_windowless_test.h"
#include "webkit/glue/plugins/test/plugin_client.h"
@@ -151,9 +152,9 @@ void WindowlessPluginTest::MultipleInstanceSyncCalls(NPNetscapeFuncs* browser) {
#if defined(OS_MACOSX)
std::string StringForPoint(int x, int y) {
std::string point_string("(");
- point_string.append(IntToString(x));
+ point_string.append(base::IntToString(x));
point_string.append(", ");
- point_string.append(IntToString(y));
+ point_string.append(base::IntToString(y));
point_string.append(")");
return point_string;
}
diff --git a/webkit/glue/plugins/webplugin.cc b/webkit/glue/plugins/webplugin.cc
index 6443318..18f722b 100644
--- a/webkit/glue/plugins/webplugin.cc
+++ b/webkit/glue/plugins/webplugin.cc
@@ -12,6 +12,9 @@ WebPluginGeometry::WebPluginGeometry()
visible(false) {
}
+WebPluginGeometry::~WebPluginGeometry() {
+}
+
bool WebPluginGeometry::Equals(const WebPluginGeometry& rhs) const {
return window == rhs.window &&
window_rect == rhs.window_rect &&
diff --git a/webkit/glue/plugins/webplugin.h b/webkit/glue/plugins/webplugin.h
index 1813842..19c6cb0 100644
--- a/webkit/glue/plugins/webplugin.h
+++ b/webkit/glue/plugins/webplugin.h
@@ -33,6 +33,7 @@ class WebPluginResourceClient;
// Describes the new location for a plugin window.
struct WebPluginGeometry {
WebPluginGeometry();
+ ~WebPluginGeometry();
bool Equals(const WebPluginGeometry& rhs) const;
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc
index b73b5ae..5374546 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl.cc
@@ -156,6 +156,42 @@ void WebPluginDelegateImpl::UpdateGeometry(
}
}
+void WebPluginDelegateImpl::SetFocus(bool focused) {
+ DCHECK(windowless_);
+ // This is called when internal WebKit focus (the focused element on the page)
+ // changes, but plugins need to know about OS-level focus, so we have an extra
+ // layer of focus tracking.
+ //
+ // On Windows, historically browsers did not set focus events to windowless
+ // plugins when the toplevel window focus changes. Sending such focus events
+ // breaks full screen mode in Flash because it will come out of full screen
+ // mode when it loses focus, and its full screen window causes the browser to
+ // lose focus.
+ has_webkit_focus_ = focused;
+#ifndef OS_WIN
+ if (containing_view_has_focus_)
+ SetPluginHasFocus(focused);
+#else
+ SetPluginHasFocus(focused);
+#endif
+}
+
+void WebPluginDelegateImpl::SetPluginHasFocus(bool focused) {
+ if (focused == plugin_has_focus_)
+ return;
+ if (PlatformSetPluginHasFocus(focused))
+ plugin_has_focus_ = focused;
+}
+
+void WebPluginDelegateImpl::SetContentAreaHasFocus(bool has_focus) {
+ containing_view_has_focus_ = has_focus;
+ if (!windowless_)
+ return;
+#ifndef OS_WIN // See SetFocus above.
+ SetPluginHasFocus(containing_view_has_focus_ && has_webkit_focus_);
+#endif
+}
+
NPObject* WebPluginDelegateImpl::GetPluginScriptableObject() {
return instance_->GetPluginScriptableObject();
}
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index ebf5d3e..650d398 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -2,16 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef WEBKIT_GLUE_PLUGIN_WEBPLUGIN_DELEGATE_IMPL_H_
-#define WEBKIT_GLUE_PLUGIN_WEBPLUGIN_DELEGATE_IMPL_H_
+#ifndef WEBKIT_GLUE_PLUGINS_WEBPLUGIN_DELEGATE_IMPL_H_
+#define WEBKIT_GLUE_PLUGINS_WEBPLUGIN_DELEGATE_IMPL_H_
#include "build/build_config.h"
#include <string>
#include <list>
-#include <set>
-#include "base/file_path.h"
#include "base/ref_counted.h"
#include "base/task.h"
#include "base/time.h"
@@ -27,9 +25,13 @@
#endif
#if defined(USE_X11)
+#include "app/x11_util.h"
+
typedef struct _GdkDrawable GdkPixmap;
#endif
+class FilePath;
+
namespace NPAPI {
class PluginInstance;
}
@@ -135,6 +137,9 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
// Returns a combination of PluginQuirks.
int GetQuirks() const { return quirks_; }
+ // Informs the plugin that the view it is in has gained or lost focus.
+ void SetContentAreaHasFocus(bool has_focus);
+
#if defined(OS_MACOSX)
// Informs the plugin that the geometry has changed, as with UpdateGeometry,
// but also includes the new buffer context for that new geometry.
@@ -148,16 +153,14 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
static WebPluginDelegateImpl* GetActiveDelegate();
// Informs the plugin that the window it is in has gained or lost focus.
void SetWindowHasFocus(bool has_focus);
- // Informs the plugin that the view it is in has gained or lost first
- // responder status.
- void SetContentAreaHasFocus(bool has_focus);
// Returns whether or not the window the plugin is in has focus.
bool GetWindowHasFocus() const { return containing_window_has_focus_; }
// Informs the plugin that its tab or window has been hidden or shown.
void SetContainerVisibility(bool is_visible);
// Informs the plugin that its containing window's frame has changed.
// Frames are in screen coordinates.
- void WindowFrameChanged(gfx::Rect window_frame, gfx::Rect view_frame);
+ void WindowFrameChanged(const gfx::Rect& window_frame,
+ const gfx::Rect& view_frame);
// Informs the delegate that the plugin set a Carbon ThemeCursor.
void SetThemeCursor(ThemeCursor cursor);
// Informs the delegate that the plugin set a Carbon Cursor.
@@ -181,6 +184,12 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
void set_windowed_handle(gfx::PluginWindowHandle handle);
#endif
+#if defined(USE_X11)
+ void SetWindowlessShmPixmap(XID shm_pixmap) {
+ windowless_shm_pixmap_ = shm_pixmap;
+ }
+#endif
+
private:
friend class DeleteTask<WebPluginDelegateImpl>;
friend class webkit_glue::WebPluginDelegate;
@@ -246,6 +255,14 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
// See NPAPI NPP_SetWindow for more information.
void WindowlessSetWindow();
+ // Informs the plugin that it has gained or lost keyboard focus (on the Mac,
+ // this just means window first responder status).
+ void SetPluginHasFocus(bool focused);
+
+ // Handles the platform specific details of setting plugin focus. Returns
+ // false if the platform cancelled the focus tranfer.
+ bool PlatformSetPluginHasFocus(bool focused);
+
//-----------------------------------------
// used for windowed and windowless plugins
@@ -289,9 +306,12 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
// layout of this process with the one of the browser process.
HKL keyboard_layout_;
int parent_thread_id_;
-#endif // OS_WIN
+#endif // defined(OS_WIN)
#if defined(USE_X11)
+ // The SHM pixmap for a windowless plugin.
+ XID windowless_shm_pixmap_;
+
// The pixmap we're drawing into, for a windowless plugin.
GdkPixmap* pixmap_;
double first_event_time_;
@@ -366,10 +386,6 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
// Updates everything that depends on the plugin's absolute screen location.
void PluginScreenLocationChanged();
- // Informs the plugin that it has gained or lost keyboard focus (i.e., window
- // first responder status).
- void SetPluginHasFocus(bool has_focus);
-
// Returns the apparent zoom ratio for the given event, as inferred from our
// current knowledge about about where on screen the plugin is.
// This is a temporary workaround for <http://crbug.com/9996>; once that is
@@ -424,14 +440,6 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
// relative to an upper-left (0,0).
gfx::Point content_area_origin_;
- // True if the plugin thinks it has keyboard focus
- bool plugin_has_focus_;
- // True if the plugin element has focus within the page, regardless of whether
- // its containing view is currently the first responder for the window.
- bool has_webkit_focus_;
- // True if the containing view is the window's first responder.
- bool containing_view_has_focus_;
-
bool containing_window_has_focus_;
bool initial_window_focus_;
bool container_is_visible_;
@@ -484,7 +492,18 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
// call received by the plugin.
bool first_set_window_call_;
+ // True if the plugin thinks it has keyboard focus
+ bool plugin_has_focus_;
+ // True if the plugin element has focus within the web content, regardless of
+ // whether its containing view currently has focus.
+ bool has_webkit_focus_;
+ // True if the containing view currently has focus.
+ // Initially set to true so that plugin focus still works in environments
+ // where SetContentAreaHasFocus is never called. See
+ // https://bugs.webkit.org/show_bug.cgi?id=46013 for details.
+ bool containing_view_has_focus_;
+
DISALLOW_COPY_AND_ASSIGN(WebPluginDelegateImpl);
};
-#endif // WEBKIT_GLUE_PLUGIN_WEBPLUGIN_DELEGATE_IMPL_H_
+#endif // WEBKIT_GLUE_PLUGINS_WEBPLUGIN_DELEGATE_IMPL_H_
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
index 18b1504..3d112fa 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
@@ -44,6 +44,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
windowless_(false),
plugin_(NULL),
instance_(instance),
+ windowless_shm_pixmap_(None),
pixmap_(NULL),
first_event_time_(-1.0),
plug_(NULL),
@@ -51,7 +52,10 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
parent_(containing_view),
quirks_(0),
handle_event_depth_(0),
- first_set_window_call_(true) {
+ first_set_window_call_(true),
+ plugin_has_focus_(false),
+ has_webkit_focus_(false),
+ containing_view_has_focus_(true) {
memset(&window_, 0, sizeof(window_));
if (instance_->mime_type() == "application/x-shockwave-flash") {
// Flash is tied to Firefox's whacky behavior with windowless plugins. See
@@ -399,47 +403,99 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_t* context,
pixmap_draw_rect.right(),
pixmap_draw_rect.bottom());
- EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height());
-
- // Copy the current image into the pixmap, so the plugin can draw over
- // this background.
- cairo_t* cairo = gdk_cairo_create(pixmap_);
- BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin());
- cairo_destroy(cairo);
-
// Construct the paint message, targeting the pixmap.
NPEvent np_event = {0};
XGraphicsExposeEvent &event = np_event.xgraphicsexpose;
event.type = GraphicsExpose;
- event.display = GDK_DISPLAY();
- event.drawable = GDK_PIXMAP_XID(pixmap_);
event.x = pixmap_draw_rect.x();
event.y = pixmap_draw_rect.y();
event.width = pixmap_draw_rect.width();
event.height = pixmap_draw_rect.height();
+ event.display = GDK_DISPLAY();
- // Tell the plugin to paint into the pixmap.
- static StatsRate plugin_paint("Plugin.Paint");
- StatsScope<StatsRate> scope(plugin_paint);
- NPError err = instance()->NPP_HandleEvent(&np_event);
- DCHECK_EQ(err, NPERR_NO_ERROR);
+ if (windowless_shm_pixmap_ != None) {
+ Pixmap pixmap = None;
+ GC xgc = NULL;
+ Display* display = event.display;
+ gfx::Rect plugin_draw_rect = draw_rect;
+
+ // Make plugin_draw_rect relative to the plugin window.
+ plugin_draw_rect.Offset(-window_rect_.x(), -window_rect_.y());
+
+ // In case the drawing area does not start with the plugin window origin,
+ // we can not let the plugin directly draw over the shared memory pixmap.
+ if (plugin_draw_rect.x() != pixmap_draw_rect.x() ||
+ plugin_draw_rect.y() != pixmap_draw_rect.y()) {
+ pixmap = XCreatePixmap(display, windowless_shm_pixmap_,
+ std::max(1, pixmap_rect.width()),
+ std::max(1, pixmap_rect.height()),
+ DefaultDepth(display, 0));
+ xgc = XCreateGC(display, windowless_shm_pixmap_, 0, NULL);
+ // Copy the current image into the pixmap, so the plugin can draw over it.
+ XCopyArea(display, windowless_shm_pixmap_, pixmap, xgc,
+ plugin_draw_rect.x(), plugin_draw_rect.y(),
+ pixmap_draw_rect.width(), pixmap_draw_rect.height(),
+ pixmap_draw_rect.x(), pixmap_draw_rect.y());
+
+ event.drawable = pixmap;
+ } else {
+ event.drawable = windowless_shm_pixmap_;
+ }
+
+ // Tell the plugin to paint into the pixmap.
+ static StatsRate plugin_paint("Plugin.Paint");
+ StatsScope<StatsRate> scope(plugin_paint);
+ NPError err = instance()->NPP_HandleEvent(&np_event);
+ DCHECK_EQ(err, NPERR_NO_ERROR);
- cairo_save(context);
- // Now copy the rendered image pixmap back into the drawing buffer.
- gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y);
- cairo_rectangle(context, draw_rect.x(), draw_rect.y(),
- draw_rect.width(), draw_rect.height());
- cairo_clip(context);
- cairo_paint(context);
+ if (pixmap != None) {
+ // Copy the rendered image pixmap back into the shm pixmap
+ // and thus the drawing buffer.
+ XCopyArea(display, pixmap, windowless_shm_pixmap_, xgc,
+ pixmap_draw_rect.x(), pixmap_draw_rect.y(),
+ pixmap_draw_rect.width(), pixmap_draw_rect.height(),
+ plugin_draw_rect.x(), plugin_draw_rect.y());
+ XSync(display, FALSE);
+ if (xgc)
+ XFreeGC(display, xgc);
+ XFreePixmap(display, pixmap);
+ } else {
+ XSync(display, FALSE);
+ }
+ } else {
+ EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height());
+
+ // Copy the current image into the pixmap, so the plugin can draw over
+ // this background.
+ cairo_t* cairo = gdk_cairo_create(pixmap_);
+ BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin());
+ cairo_destroy(cairo);
+
+ event.drawable = GDK_PIXMAP_XID(pixmap_);
+
+ // Tell the plugin to paint into the pixmap.
+ static StatsRate plugin_paint("Plugin.Paint");
+ StatsScope<StatsRate> scope(plugin_paint);
+ NPError err = instance()->NPP_HandleEvent(&np_event);
+ DCHECK_EQ(err, NPERR_NO_ERROR);
+
+ cairo_save(context);
+ // Now copy the rendered image pixmap back into the drawing buffer.
+ gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y);
+ cairo_rectangle(context, draw_rect.x(), draw_rect.y(),
+ draw_rect.width(), draw_rect.height());
+ cairo_clip(context);
+ cairo_paint(context);
#ifdef DEBUG_RECTANGLES
- // Draw some debugging rectangles.
- // Pixmap rect = blue.
- DrawDebugRectangle(context, pixmap_rect, 0, 0, 1);
- // Drawing rect = red.
- DrawDebugRectangle(context, draw_rect, 1, 0, 0);
+ // Draw some debugging rectangles.
+ // Pixmap rect = blue.
+ DrawDebugRectangle(context, pixmap_rect, 0, 0, 1);
+ // Drawing rect = red.
+ DrawDebugRectangle(context, draw_rect, 1, 0, 0);
#endif
- cairo_restore(context);
+ cairo_restore(context);
+ }
}
void WebPluginDelegateImpl::WindowlessSetWindow() {
@@ -485,7 +541,7 @@ void WebPluginDelegateImpl::WindowlessSetWindow() {
}
}
-void WebPluginDelegateImpl::SetFocus(bool focused) {
+bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) {
DCHECK(instance()->windowless());
NPEvent np_event = {0};
@@ -496,6 +552,7 @@ void WebPluginDelegateImpl::SetFocus(bool focused) {
event.mode = -1;
event.detail = NotifyDetailNone;
instance()->NPP_HandleEvent(&np_event);
+ return true;
}
// Converts a WebInputEvent::Modifiers bitfield into a
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
index efa6bdd..614f1d2 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
+++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
@@ -12,11 +12,11 @@
#include <set>
#include "base/file_util.h"
-#include "base/lazy_instance.h"
#include "base/message_loop.h"
#include "base/scoped_ptr.h"
#include "base/stats_counters.h"
#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "webkit/glue/plugins/plugin_instance.h"
#include "webkit/glue/plugins/plugin_lib.h"
@@ -258,16 +258,16 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
layer_(nil),
surface_(NULL),
renderer_(nil),
- plugin_has_focus_(false),
- has_webkit_focus_(false),
- containing_view_has_focus_(false),
containing_window_has_focus_(false),
initial_window_focus_(false),
container_is_visible_(false),
have_called_set_window_(false),
external_drag_tracker_(new ExternalDragTracker()),
handle_event_depth_(0),
- first_set_window_call_(true) {
+ first_set_window_call_(true),
+ plugin_has_focus_(false),
+ has_webkit_focus_(false),
+ containing_view_has_focus_(true) {
memset(&window_, 0, sizeof(window_));
#ifndef NP_NO_CARBON
memset(&np_cg_context_, 0, sizeof(np_cg_context_));
@@ -385,12 +385,6 @@ bool WebPluginDelegateImpl::PlatformInitialize() {
break;
}
- // TODO(stuartmorgan): We need real plugin container visibility information
- // when the plugin is initialized; for now, assume it's visible.
- // None of the calls SetContainerVisibility would make are useful at this
- // point, so we just set the initial state directly.
- container_is_visible_ = true;
-
// Let the WebPlugin know that we are windowless (unless this is a
// Core Animation plugin, in which case BindFakePluginWindowHandle will take
// care of setting up the appropriate window handle).
@@ -472,15 +466,6 @@ void WebPluginDelegateImpl::Print(CGContextRef context) {
NOTIMPLEMENTED();
}
-void WebPluginDelegateImpl::SetFocus(bool focused) {
- // This is called when internal WebKit focus (the focused element on the page)
- // changes, but plugins need to know about actual first responder status, so
- // we have an extra layer of focus tracking.
- has_webkit_focus_ = focused;
- if (containing_view_has_focus_)
- SetPluginHasFocus(focused);
-}
-
bool WebPluginDelegateImpl::PlatformHandleInputEvent(
const WebInputEvent& event, WebCursorInfo* cursor_info) {
DCHECK(cursor_info != NULL);
@@ -497,12 +482,6 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent(
if (WebInputEvent::isMouseEventType(event.type) ||
event.type == WebInputEvent::MouseWheel) {
- // Ideally we would compute the content origin from the web event using the
- // code below as a safety net for missed content area location changes.
- // Because of <http://crbug.com/9996>, however, only globalX/Y are right if
- // the page has been zoomed, so for now the coordinates we get aren't
- // trustworthy enough to use for corrections.
-#if PLUGIN_SCALING_FIXED
// Check our plugin location before we send the event to the plugin, just
// in case we somehow missed a plugin frame change.
const WebMouseEvent* mouse_event =
@@ -517,7 +496,6 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent(
<< content_origin;
SetContentAreaOrigin(content_origin);
}
-#endif
current_windowless_cursor_.GetCursorInfo(cursor_info);
}
@@ -593,25 +571,6 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent(
}
}
-#ifndef PLUGIN_SCALING_FIXED
- // Because of <http://crbug.com/9996>, the non-global coordinates we get for
- // zoomed pages are wrong. As a temporary hack around that bug, override the
- // coordinates we are given with ones computed based on our knowledge of where
- // the plugin is on screen. We only need to do this for Cocoa, since Carbon
- // only uses the global coordinates.
- if (instance()->event_model() == NPEventModelCocoa &&
- (WebInputEvent::isMouseEventType(event.type) ||
- event.type == WebInputEvent::MouseWheel)) {
- const WebMouseEvent* mouse_event =
- static_cast<const WebMouseEvent*>(&event);
- NPCocoaEvent* cocoa_event = static_cast<NPCocoaEvent*>(plugin_event);
- cocoa_event->data.mouse.pluginX =
- mouse_event->globalX - content_area_origin_.x() - window_rect_.x();
- cocoa_event->data.mouse.pluginY =
- mouse_event->globalY - content_area_origin_.y() - window_rect_.y();
- }
-#endif
-
// Send the plugin the event.
scoped_ptr<NPAPI::ScopedCurrentPluginEvent> event_scope(NULL);
if (instance()->event_model() == NPEventModelCocoa) {
@@ -855,13 +814,9 @@ void WebPluginDelegateImpl::SetWindowHasFocus(bool has_focus) {
}
}
-void WebPluginDelegateImpl::SetPluginHasFocus(bool has_focus) {
+bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) {
if (!have_called_set_window_)
- return;
-
- if (has_focus == plugin_has_focus_)
- return;
- plugin_has_focus_ = has_focus;
+ return false;
ScopedActiveDelegate active_delegate(this);
@@ -869,7 +824,7 @@ void WebPluginDelegateImpl::SetPluginHasFocus(bool has_focus) {
#ifndef NP_NO_CARBON
case NPEventModelCarbon: {
NPEvent focus_event = { 0 };
- if (plugin_has_focus_)
+ if (focused)
focus_event.what = NPEventType_GetFocusEvent;
else
focus_event.what = NPEventType_LoseFocusEvent;
@@ -882,16 +837,12 @@ void WebPluginDelegateImpl::SetPluginHasFocus(bool has_focus) {
NPCocoaEvent focus_event;
memset(&focus_event, 0, sizeof(focus_event));
focus_event.type = NPCocoaEventFocusChanged;
- focus_event.data.focus.hasFocus = plugin_has_focus_;
+ focus_event.data.focus.hasFocus = focused;
instance()->NPP_HandleEvent(&focus_event);
break;
}
}
-}
-
-void WebPluginDelegateImpl::SetContentAreaHasFocus(bool has_focus) {
- containing_view_has_focus_ = has_focus;
- SetPluginHasFocus(containing_view_has_focus_ && has_webkit_focus_);
+ return true;
}
void WebPluginDelegateImpl::SetContainerVisibility(bool is_visible) {
@@ -925,8 +876,8 @@ void WebPluginDelegateImpl::SetContainerVisibility(bool is_visible) {
instance()->webplugin()->InvalidateRect(gfx::Rect());
}
-void WebPluginDelegateImpl::WindowFrameChanged(gfx::Rect window_frame,
- gfx::Rect view_frame) {
+void WebPluginDelegateImpl::WindowFrameChanged(const gfx::Rect& window_frame,
+ const gfx::Rect& view_frame) {
instance()->set_window_frame(window_frame);
SetContentAreaOrigin(gfx::Point(view_frame.x(), view_frame.y()));
}
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_win.cc b/webkit/glue/plugins/webplugin_delegate_impl_win.cc
index 09184ab..9cdc7db 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_win.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -15,7 +15,10 @@
#include "base/registry.h"
#include "base/scoped_ptr.h"
#include "base/stats_counters.h"
+#include "base/string_number_conversions.h"
+#include "base/string_split.h"
#include "base/string_util.h"
+#include "base/stringprintf.h"
#include "base/win_util.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
@@ -264,7 +267,10 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
user_gesture_msg_factory_(this),
handle_event_depth_(0),
mouse_hook_(NULL),
- first_set_window_call_(true) {
+ first_set_window_call_(true),
+ plugin_has_focus_(false),
+ has_webkit_focus_(false),
+ containing_view_has_focus_(true) {
memset(&window_, 0, sizeof(window_));
const WebPluginInfo& plugin_info = instance_->plugin_lib()->plugin_info();
@@ -285,7 +291,8 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
std::vector<std::wstring> version;
SplitString(plugin_info.version, L'.', &version);
if (version.size() > 0) {
- int major = static_cast<int>(StringToInt64(version[0]));
+ int major;
+ base::StringToInt(version[0], &major);
if (major >= 9) {
quirks_ |= PLUGIN_QUIRK_DIE_AFTER_UNLOAD;
@@ -410,7 +417,8 @@ bool WebPluginDelegateImpl::PlatformInitialize() {
if ((quirks_ & PLUGIN_QUIRK_PATCH_REGENUMKEYEXW) &&
win_util::GetWinVersion() == win_util::WINVERSION_XP &&
!RegKey().Open(HKEY_LOCAL_MACHINE,
- L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe") &&
+ L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe",
+ KEY_READ) &&
!g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched()) {
g_iat_patch_reg_enum_key_ex_w.Pointer()->Patch(
L"wmpdxm.dll", "advapi32.dll", "RegEnumKeyExW",
@@ -1048,7 +1056,7 @@ void WebPluginDelegateImpl::WindowlessSetWindow() {
DCHECK(err == NPERR_NO_ERROR);
}
-void WebPluginDelegateImpl::SetFocus(bool focused) {
+bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) {
DCHECK(instance()->windowless());
NPEvent focus_event;
@@ -1057,6 +1065,7 @@ void WebPluginDelegateImpl::SetFocus(bool focused) {
focus_event.lParam = 0;
instance()->NPP_HandleEvent(&focus_event);
+ return true;
}
static bool NPEventFromWebMouseEvent(const WebMouseEvent& event,
@@ -1187,7 +1196,7 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent(
parent_thread_id_ = GetWindowThreadProcessId(parent_, NULL);
HKL parent_layout = GetKeyboardLayout(parent_thread_id_);
if (keyboard_layout_ != parent_layout) {
- std::wstring layout_name(StringPrintf(L"%08x", parent_layout));
+ std::wstring layout_name(base::StringPrintf(L"%08x", parent_layout));
LoadKeyboardLayout(layout_name.c_str(), KLF_ACTIVATE);
keyboard_layout_ = parent_layout;
}
diff --git a/webkit/glue/plugins/webplugin_impl.cc b/webkit/glue/plugins/webplugin_impl.cc
index 1660ede..80bc197 100644
--- a/webkit/glue/plugins/webplugin_impl.cc
+++ b/webkit/glue/plugins/webplugin_impl.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/string_util.h"
+#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "gfx/rect.h"
#include "googleurl/src/gurl.h"
@@ -113,7 +114,7 @@ class MultiPartResponseClient : public WebURLLoaderClient {
byte_range_lower_bound_ += data_size;
}
- virtual void didFinishLoading(WebURLLoader*) {}
+ virtual void didFinishLoading(WebURLLoader*, double finishTime) {}
virtual void didFail(WebURLLoader*, const WebURLError&) {}
void Clear() {
@@ -160,7 +161,7 @@ std::string GetAllHeaders(const WebURLResponse& response) {
return result;
// TODO(darin): Shouldn't we also report HTTP version numbers?
- result = StringPrintf("HTTP %d ", response.httpStatusCode());
+ result = base::StringPrintf("HTTP %d ", response.httpStatusCode());
result.append(status.utf8());
result.append("\n");
@@ -340,6 +341,10 @@ bool WebPluginImpl::acceptsInputEvents() {
bool WebPluginImpl::handleInputEvent(
const WebInputEvent& event, WebCursorInfo& cursor_info) {
+ // Swallow context menu events in order to suppress the default context menu.
+ if (event.type == WebInputEvent::ContextMenu)
+ return true;
+
return delegate_->HandleInputEvent(event, &cursor_info);
}
@@ -913,7 +918,7 @@ void WebPluginImpl::didReceiveData(WebURLLoader* loader,
}
}
-void WebPluginImpl::didFinishLoading(WebURLLoader* loader) {
+void WebPluginImpl::didFinishLoading(WebURLLoader* loader, double finishTime) {
ClientInfo* client_info = GetClientInfoFromLoader(loader);
if (client_info && client_info->client) {
MultiPartResponseHandlerMap::iterator index =
diff --git a/webkit/glue/plugins/webplugin_impl.h b/webkit/glue/plugins/webplugin_impl.h
index 9b75e6e..5fe96d2 100644
--- a/webkit/glue/plugins/webplugin_impl.h
+++ b/webkit/glue/plugins/webplugin_impl.h
@@ -204,7 +204,8 @@ class WebPluginImpl : public WebPlugin,
const WebKit::WebURLResponse& response);
virtual void didReceiveData(WebKit::WebURLLoader* loader, const char *buffer,
int length);
- virtual void didFinishLoading(WebKit::WebURLLoader* loader);
+ virtual void didFinishLoading(WebKit::WebURLLoader* loader,
+ double finishTime);
virtual void didFail(WebKit::WebURLLoader* loader,
const WebKit::WebURLError& error);
diff --git a/webkit/glue/plugins/webview_plugin.cc b/webkit/glue/plugins/webview_plugin.cc
index 413ae10..231bd37 100644
--- a/webkit/glue/plugins/webview_plugin.cc
+++ b/webkit/glue/plugins/webview_plugin.cc
@@ -4,6 +4,7 @@
#include "webkit/glue/plugins/webview_plugin.h"
+#include "base/histogram.h"
#include "base/message_loop.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
@@ -12,6 +13,7 @@
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
#if WEBKIT_USING_CG
@@ -27,18 +29,21 @@ using WebKit::WebDragOperationsMask;
using WebKit::WebFrame;
using WebKit::WebImage;
using WebKit::WebInputEvent;
+using WebKit::WebPlugin;
using WebKit::WebPluginContainer;
using WebKit::WebPoint;
using WebKit::WebRect;
using WebKit::WebSize;
using WebKit::WebURLError;
using WebKit::WebURLRequest;
+using WebKit::WebURLResponse;
using WebKit::WebVector;
using WebKit::WebView;
WebViewPlugin::WebViewPlugin(WebViewPlugin::Delegate* delegate)
: delegate_(delegate),
- container_(NULL) {
+ container_(NULL),
+ finished_loading_(false) {
web_view_ = WebView::create(this, NULL);
web_view_->initializeMainFrame(this);
}
@@ -47,6 +52,26 @@ WebViewPlugin::~WebViewPlugin() {
web_view_->close();
}
+void WebViewPlugin::ReplayReceivedData(WebPlugin* plugin) {
+ if (!response_.isNull()) {
+ plugin->didReceiveResponse(response_);
+ size_t total_bytes = 0;
+ for (std::list<std::string>::iterator it = data_.begin();
+ it != data_.end(); ++it) {
+ plugin->didReceiveData(it->c_str(), it->length());
+ total_bytes += it->length();
+ }
+ UMA_HISTOGRAM_MEMORY_KB("PluginDocument.Memory", (total_bytes / 1024));
+ UMA_HISTOGRAM_COUNTS("PluginDocument.NumChunks", data_.size());
+ }
+ if (finished_loading_) {
+ plugin->didFinishLoading();
+ }
+ if (error_.get()) {
+ plugin->didFailLoading(*error_);
+ }
+}
+
bool WebViewPlugin::initialize(WebPluginContainer* container) {
container_ = container;
return true;
@@ -55,6 +80,7 @@ bool WebViewPlugin::initialize(WebPluginContainer* container) {
void WebViewPlugin::destroy() {
delegate_->WillDestroyPlugin();
delegate_ = NULL;
+ container_ = NULL;
MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
@@ -104,6 +130,25 @@ bool WebViewPlugin::handleInputEvent(const WebInputEvent& event,
return handled;
}
+void WebViewPlugin::didReceiveResponse(const WebURLResponse& response) {
+ DCHECK(response_.isNull());
+ response_ = response;
+}
+
+void WebViewPlugin::didReceiveData(const char* data, int data_length) {
+ data_.push_back(std::string(data, data_length));
+}
+
+void WebViewPlugin::didFinishLoading() {
+ DCHECK(!finished_loading_);
+ finished_loading_ = true;
+}
+
+void WebViewPlugin::didFailLoading(const WebURLError& error) {
+ DCHECK(!error_.get());
+ error_.reset(new WebURLError(error));
+}
+
void WebViewPlugin::startDragging(const WebDragData&,
WebDragOperationsMask,
const WebImage&,
@@ -114,7 +159,7 @@ void WebViewPlugin::startDragging(const WebDragData&,
void WebViewPlugin::didInvalidateRect(const WebRect& rect) {
if (container_)
- container_->invalidateRect(WebRect(rect));
+ container_->invalidateRect(rect);
}
void WebViewPlugin::didChangeCursor(const WebCursorInfo& cursor) {
@@ -122,7 +167,8 @@ void WebViewPlugin::didChangeCursor(const WebCursorInfo& cursor) {
}
void WebViewPlugin::didClearWindowObject(WebFrame* frame) {
- delegate_->BindWebFrame(frame);
+ if (delegate_)
+ delegate_->BindWebFrame(frame);
}
bool WebViewPlugin::canHandleRequest(WebFrame* frame,
diff --git a/webkit/glue/plugins/webview_plugin.h b/webkit/glue/plugins/webview_plugin.h
index 2e41218..757a012 100644
--- a/webkit/glue/plugins/webview_plugin.h
+++ b/webkit/glue/plugins/webview_plugin.h
@@ -5,11 +5,14 @@
#ifndef WEBKIT_GLUE_PLUGINS_WEBVIEW_PLUGIN_H_
#define WEBKIT_GLUE_PLUGINS_WEBVIEW_PLUGIN_H_
+#include <list>
+
#include "base/scoped_ptr.h"
#include "base/task.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrameClient.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h"
#include "third_party/WebKit/WebKit/chromium/public/WebViewClient.h"
// This class implements the WebPlugin interface by forwarding drawing and
@@ -36,9 +39,14 @@ class WebViewPlugin: public WebKit::WebPlugin, public WebKit::WebViewClient,
explicit WebViewPlugin(Delegate* delegate);
- virtual WebKit::WebView* web_view() { return web_view_; }
+ WebKit::WebView* web_view() { return web_view_; }
- virtual WebKit::WebPluginContainer* container() { return container_; }
+ WebKit::WebPluginContainer* container() { return container_; }
+
+ // When loading a plug-in document (i.e. a full page plug-in not embedded in
+ // another page), we save all data that has been received, and replay it with
+ // this method on the actual plug-in.
+ void ReplayReceivedData(WebKit::WebPlugin* plugin);
// WebPlugin methods:
virtual bool initialize(WebKit::WebPluginContainer*);
@@ -60,10 +68,10 @@ class WebViewPlugin: public WebKit::WebPlugin, public WebKit::WebViewClient,
virtual bool handleInputEvent(const WebKit::WebInputEvent& event,
WebKit::WebCursorInfo& cursor_info);
- virtual void didReceiveResponse(const WebKit::WebURLResponse& response) { }
- virtual void didReceiveData(const char* data, int data_length) { }
- virtual void didFinishLoading() { }
- virtual void didFailLoading(const WebKit::WebURLError& error) { }
+ virtual void didReceiveResponse(const WebKit::WebURLResponse& response);
+ virtual void didReceiveData(const char* data, int data_length);
+ virtual void didFinishLoading();
+ virtual void didFailLoading(const WebKit::WebURLError& error);
// Called in response to WebPluginContainer::loadFrameRequest
virtual void didFinishLoadingFrameRequest(
@@ -102,6 +110,11 @@ class WebViewPlugin: public WebKit::WebPlugin, public WebKit::WebViewClient,
WebKit::WebPluginContainer* container_;
WebKit::WebView* web_view_;
gfx::Rect rect_;
+
+ WebKit::WebURLResponse response_;
+ std::list<std::string> data_;
+ bool finished_loading_;
+ scoped_ptr<WebKit::WebURLError> error_;
};
#endif // WEBKIT_GLUE_PLUGINS_WEBVIEW_PLUGIN_H_