Home | History | Annotate | Download | only in pepper
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback_helpers.h"
      9 #include "base/debug/trace_event.h"
     10 #include "base/logging.h"
     11 #include "base/memory/linked_ptr.h"
     12 #include "base/message_loop/message_loop.h"
     13 #include "base/stl_util.h"
     14 #include "base/strings/stringprintf.h"
     15 #include "base/strings/utf_offset_string_conversions.h"
     16 #include "base/strings/utf_string_conversions.h"
     17 #include "base/time/time.h"
     18 #include "cc/layers/texture_layer.h"
     19 #include "content/common/content_constants_internal.h"
     20 #include "content/public/common/page_zoom.h"
     21 #include "content/public/renderer/content_renderer_client.h"
     22 #include "content/renderer/pepper/common.h"
     23 #include "content/renderer/pepper/content_decryptor_delegate.h"
     24 #include "content/renderer/pepper/event_conversion.h"
     25 #include "content/renderer/pepper/fullscreen_container.h"
     26 #include "content/renderer/pepper/gfx_conversion.h"
     27 #include "content/renderer/pepper/host_dispatcher_wrapper.h"
     28 #include "content/renderer/pepper/host_globals.h"
     29 #include "content/renderer/pepper/message_channel.h"
     30 #include "content/renderer/pepper/npapi_glue.h"
     31 #include "content/renderer/pepper/pepper_browser_connection.h"
     32 #include "content/renderer/pepper/pepper_graphics_2d_host.h"
     33 #include "content/renderer/pepper/pepper_in_process_router.h"
     34 #include "content/renderer/pepper/pepper_platform_context_3d.h"
     35 #include "content/renderer/pepper/pepper_url_loader_host.h"
     36 #include "content/renderer/pepper/plugin_module.h"
     37 #include "content/renderer/pepper/plugin_object.h"
     38 #include "content/renderer/pepper/ppb_buffer_impl.h"
     39 #include "content/renderer/pepper/ppb_file_ref_impl.h"
     40 #include "content/renderer/pepper/ppb_graphics_3d_impl.h"
     41 #include "content/renderer/pepper/ppb_image_data_impl.h"
     42 #include "content/renderer/pepper/ppp_pdf.h"
     43 #include "content/renderer/pepper/renderer_ppapi_host_impl.h"
     44 #include "content/renderer/pepper/url_request_info_util.h"
     45 #include "content/renderer/pepper/url_response_info_util.h"
     46 #include "content/renderer/render_thread_impl.h"
     47 #include "content/renderer/render_view_impl.h"
     48 #include "content/renderer/render_widget_fullscreen_pepper.h"
     49 #include "content/renderer/sad_plugin.h"
     50 #include "media/base/audio_hardware_config.h"
     51 #include "ppapi/c/dev/ppb_find_dev.h"
     52 #include "ppapi/c/dev/ppb_zoom_dev.h"
     53 #include "ppapi/c/dev/ppp_find_dev.h"
     54 #include "ppapi/c/dev/ppp_selection_dev.h"
     55 #include "ppapi/c/dev/ppp_text_input_dev.h"
     56 #include "ppapi/c/dev/ppp_zoom_dev.h"
     57 #include "ppapi/c/pp_rect.h"
     58 #include "ppapi/c/ppb_audio_config.h"
     59 #include "ppapi/c/ppb_core.h"
     60 #include "ppapi/c/ppb_gamepad.h"
     61 #include "ppapi/c/ppp_input_event.h"
     62 #include "ppapi/c/ppp_instance.h"
     63 #include "ppapi/c/ppp_messaging.h"
     64 #include "ppapi/c/ppp_mouse_lock.h"
     65 #include "ppapi/c/private/ppp_instance_private.h"
     66 #include "ppapi/host/ppapi_host.h"
     67 #include "ppapi/proxy/ppapi_messages.h"
     68 #include "ppapi/proxy/url_loader_resource.h"
     69 #include "ppapi/shared_impl/ppapi_permissions.h"
     70 #include "ppapi/shared_impl/ppapi_preferences.h"
     71 #include "ppapi/shared_impl/ppb_gamepad_shared.h"
     72 #include "ppapi/shared_impl/ppb_input_event_shared.h"
     73 #include "ppapi/shared_impl/ppb_url_util_shared.h"
     74 #include "ppapi/shared_impl/ppb_view_shared.h"
     75 #include "ppapi/shared_impl/ppp_instance_combined.h"
     76 #include "ppapi/shared_impl/resource.h"
     77 #include "ppapi/shared_impl/scoped_pp_resource.h"
     78 #include "ppapi/shared_impl/time_conversion.h"
     79 #include "ppapi/shared_impl/url_request_info_data.h"
     80 #include "ppapi/shared_impl/var.h"
     81 #include "ppapi/thunk/enter.h"
     82 #include "ppapi/thunk/ppb_buffer_api.h"
     83 #include "printing/metafile.h"
     84 #include "printing/metafile_skia_wrapper.h"
     85 #include "printing/units.h"
     86 #include "skia/ext/platform_canvas.h"
     87 #include "skia/ext/platform_device.h"
     88 #include "third_party/WebKit/public/platform/WebGamepads.h"
     89 #include "third_party/WebKit/public/platform/WebString.h"
     90 #include "third_party/WebKit/public/platform/WebURL.h"
     91 #include "third_party/WebKit/public/platform/WebURLError.h"
     92 #include "third_party/WebKit/public/platform/WebURLRequest.h"
     93 #include "third_party/WebKit/public/web/WebBindings.h"
     94 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
     95 #include "third_party/WebKit/public/web/WebCursorInfo.h"
     96 #include "third_party/WebKit/public/web/WebDocument.h"
     97 #include "third_party/WebKit/public/web/WebElement.h"
     98 #include "third_party/WebKit/public/web/WebFrame.h"
     99 #include "third_party/WebKit/public/web/WebInputEvent.h"
    100 #include "third_party/WebKit/public/web/WebPluginContainer.h"
    101 #include "third_party/WebKit/public/web/WebPrintParams.h"
    102 #include "third_party/WebKit/public/web/WebPrintScalingOption.h"
    103 #include "third_party/WebKit/public/web/WebScopedUserGesture.h"
    104 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
    105 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
    106 #include "third_party/WebKit/public/web/WebView.h"
    107 #include "third_party/skia/include/core/SkCanvas.h"
    108 #include "third_party/skia/include/core/SkRect.h"
    109 #include "ui/base/range/range.h"
    110 #include "ui/gfx/image/image_skia.h"
    111 #include "ui/gfx/image/image_skia_rep.h"
    112 #include "ui/gfx/rect_conversions.h"
    113 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
    114 #include "v8/include/v8.h"
    115 #include "webkit/renderer/compositor_bindings/web_layer_impl.h"
    116 
    117 #if defined(OS_MACOSX)
    118 #include "printing/metafile_impl.h"
    119 #endif  // defined(OS_MACOSX)
    120 
    121 #if defined(OS_WIN)
    122 #include "base/metrics/histogram.h"
    123 #include "base/win/windows_version.h"
    124 #include "skia/ext/platform_canvas.h"
    125 #include "ui/gfx/codec/jpeg_codec.h"
    126 #include "ui/gfx/gdi_util.h"
    127 #endif
    128 
    129 using base::StringPrintf;
    130 using ppapi::InputEventData;
    131 using ppapi::PpapiGlobals;
    132 using ppapi::PPB_InputEvent_Shared;
    133 using ppapi::PPB_View_Shared;
    134 using ppapi::PPP_Instance_Combined;
    135 using ppapi::Resource;
    136 using ppapi::ScopedPPResource;
    137 using ppapi::StringVar;
    138 using ppapi::TrackedCallback;
    139 using ppapi::thunk::EnterResourceNoLock;
    140 using ppapi::thunk::PPB_Buffer_API;
    141 using ppapi::thunk::PPB_Gamepad_API;
    142 using ppapi::thunk::PPB_Graphics2D_API;
    143 using ppapi::thunk::PPB_Graphics3D_API;
    144 using ppapi::thunk::PPB_ImageData_API;
    145 using ppapi::Var;
    146 using ppapi::ArrayBufferVar;
    147 using ppapi::ViewData;
    148 using WebKit::WebBindings;
    149 using WebKit::WebCanvas;
    150 using WebKit::WebCursorInfo;
    151 using WebKit::WebDocument;
    152 using WebKit::WebElement;
    153 using WebKit::WebFrame;
    154 using WebKit::WebInputEvent;
    155 using WebKit::WebPlugin;
    156 using WebKit::WebPluginContainer;
    157 using WebKit::WebPrintParams;
    158 using WebKit::WebPrintScalingOption;
    159 using WebKit::WebScopedUserGesture;
    160 using WebKit::WebString;
    161 using WebKit::WebURLError;
    162 using WebKit::WebURLLoader;
    163 using WebKit::WebURLLoaderClient;
    164 using WebKit::WebURLRequest;
    165 using WebKit::WebURLResponse;
    166 using WebKit::WebUserGestureIndicator;
    167 using WebKit::WebUserGestureToken;
    168 using WebKit::WebView;
    169 
    170 namespace content {
    171 
    172 #if defined(OS_WIN)
    173 // Exported by pdf.dll
    174 typedef bool (*RenderPDFPageToDCProc)(
    175     const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc,
    176     int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y,
    177     int bounds_width, int bounds_height, bool fit_to_bounds,
    178     bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds,
    179     bool autorotate);
    180 
    181 void DrawEmptyRectangle(HDC dc) {
    182   // TODO(sanjeevr): This is a temporary hack. If we output a JPEG
    183   // to the EMF, the EnumEnhMetaFile call fails in the browser
    184   // process. The failure also happens if we output nothing here.
    185   // We need to investigate the reason for this failure and fix it.
    186   // In the meantime this temporary hack of drawing an empty
    187   // rectangle in the DC gets us by.
    188   Rectangle(dc, 0, 0, 0, 0);
    189 }
    190 #endif  // defined(OS_WIN)
    191 
    192 namespace {
    193 
    194 // Check PP_TextInput_Type and ui::TextInputType are kept in sync.
    195 COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_NONE) == \
    196     int(PP_TEXTINPUT_TYPE_NONE), mismatching_enums);
    197 COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_TEXT) == \
    198     int(PP_TEXTINPUT_TYPE_TEXT), mismatching_enums);
    199 COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_PASSWORD) == \
    200     int(PP_TEXTINPUT_TYPE_PASSWORD), mismatching_enums);
    201 COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_SEARCH) == \
    202     int(PP_TEXTINPUT_TYPE_SEARCH), mismatching_enums);
    203 COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_EMAIL) == \
    204     int(PP_TEXTINPUT_TYPE_EMAIL), mismatching_enums);
    205 COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_NUMBER) == \
    206     int(PP_TEXTINPUT_TYPE_NUMBER), mismatching_enums);
    207 COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_TELEPHONE) == \
    208     int(PP_TEXTINPUT_TYPE_TELEPHONE), mismatching_enums);
    209 COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_URL) == \
    210     int(PP_TEXTINPUT_TYPE_URL), mismatching_enums);
    211 
    212 // The default text input type is to regard the plugin always accept text input.
    213 // This is for allowing users to use input methods even on completely-IME-
    214 // unaware plugins (e.g., PPAPI Flash or PDF plugin for M16).
    215 // Plugins need to explicitly opt out the text input mode if they know
    216 // that they don't accept texts.
    217 const ui::TextInputType kPluginDefaultTextInputType = ui::TEXT_INPUT_TYPE_TEXT;
    218 
    219 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \
    220     COMPILE_ASSERT(static_cast<int>(WebCursorInfo::webkit_name) \
    221                        == static_cast<int>(np_name), \
    222                    mismatching_enums)
    223 
    224 #define COMPILE_ASSERT_PRINT_SCALING_MATCHING_ENUM(webkit_name, pp_name) \
    225     COMPILE_ASSERT(static_cast<int>(webkit_name) \
    226                        == static_cast<int>(pp_name), \
    227                    mismatching_enums)
    228 
    229 // <embed>/<object> attributes.
    230 const char kWidth[] = "width";
    231 const char kHeight[] = "height";
    232 const char kBorder[] = "border";  // According to w3c, deprecated.
    233 const char kStyle[] = "style";
    234 
    235 COMPILE_ASSERT_MATCHING_ENUM(TypePointer, PP_MOUSECURSOR_TYPE_POINTER);
    236 COMPILE_ASSERT_MATCHING_ENUM(TypeCross, PP_MOUSECURSOR_TYPE_CROSS);
    237 COMPILE_ASSERT_MATCHING_ENUM(TypeHand, PP_MOUSECURSOR_TYPE_HAND);
    238 COMPILE_ASSERT_MATCHING_ENUM(TypeIBeam, PP_MOUSECURSOR_TYPE_IBEAM);
    239 COMPILE_ASSERT_MATCHING_ENUM(TypeWait, PP_MOUSECURSOR_TYPE_WAIT);
    240 COMPILE_ASSERT_MATCHING_ENUM(TypeHelp, PP_MOUSECURSOR_TYPE_HELP);
    241 COMPILE_ASSERT_MATCHING_ENUM(TypeEastResize, PP_MOUSECURSOR_TYPE_EASTRESIZE);
    242 COMPILE_ASSERT_MATCHING_ENUM(TypeNorthResize, PP_MOUSECURSOR_TYPE_NORTHRESIZE);
    243 COMPILE_ASSERT_MATCHING_ENUM(TypeNorthEastResize,
    244                              PP_MOUSECURSOR_TYPE_NORTHEASTRESIZE);
    245 COMPILE_ASSERT_MATCHING_ENUM(TypeNorthWestResize,
    246                              PP_MOUSECURSOR_TYPE_NORTHWESTRESIZE);
    247 COMPILE_ASSERT_MATCHING_ENUM(TypeSouthResize, PP_MOUSECURSOR_TYPE_SOUTHRESIZE);
    248 COMPILE_ASSERT_MATCHING_ENUM(TypeSouthEastResize,
    249                              PP_MOUSECURSOR_TYPE_SOUTHEASTRESIZE);
    250 COMPILE_ASSERT_MATCHING_ENUM(TypeSouthWestResize,
    251                              PP_MOUSECURSOR_TYPE_SOUTHWESTRESIZE);
    252 COMPILE_ASSERT_MATCHING_ENUM(TypeWestResize, PP_MOUSECURSOR_TYPE_WESTRESIZE);
    253 COMPILE_ASSERT_MATCHING_ENUM(TypeNorthSouthResize,
    254                              PP_MOUSECURSOR_TYPE_NORTHSOUTHRESIZE);
    255 COMPILE_ASSERT_MATCHING_ENUM(TypeEastWestResize,
    256                              PP_MOUSECURSOR_TYPE_EASTWESTRESIZE);
    257 COMPILE_ASSERT_MATCHING_ENUM(TypeNorthEastSouthWestResize,
    258                              PP_MOUSECURSOR_TYPE_NORTHEASTSOUTHWESTRESIZE);
    259 COMPILE_ASSERT_MATCHING_ENUM(TypeNorthWestSouthEastResize,
    260                              PP_MOUSECURSOR_TYPE_NORTHWESTSOUTHEASTRESIZE);
    261 COMPILE_ASSERT_MATCHING_ENUM(TypeColumnResize,
    262                              PP_MOUSECURSOR_TYPE_COLUMNRESIZE);
    263 COMPILE_ASSERT_MATCHING_ENUM(TypeRowResize, PP_MOUSECURSOR_TYPE_ROWRESIZE);
    264 COMPILE_ASSERT_MATCHING_ENUM(TypeMiddlePanning,
    265                              PP_MOUSECURSOR_TYPE_MIDDLEPANNING);
    266 COMPILE_ASSERT_MATCHING_ENUM(TypeEastPanning, PP_MOUSECURSOR_TYPE_EASTPANNING);
    267 COMPILE_ASSERT_MATCHING_ENUM(TypeNorthPanning,
    268                              PP_MOUSECURSOR_TYPE_NORTHPANNING);
    269 COMPILE_ASSERT_MATCHING_ENUM(TypeNorthEastPanning,
    270                              PP_MOUSECURSOR_TYPE_NORTHEASTPANNING);
    271 COMPILE_ASSERT_MATCHING_ENUM(TypeNorthWestPanning,
    272                              PP_MOUSECURSOR_TYPE_NORTHWESTPANNING);
    273 COMPILE_ASSERT_MATCHING_ENUM(TypeSouthPanning,
    274                              PP_MOUSECURSOR_TYPE_SOUTHPANNING);
    275 COMPILE_ASSERT_MATCHING_ENUM(TypeSouthEastPanning,
    276                              PP_MOUSECURSOR_TYPE_SOUTHEASTPANNING);
    277 COMPILE_ASSERT_MATCHING_ENUM(TypeSouthWestPanning,
    278                              PP_MOUSECURSOR_TYPE_SOUTHWESTPANNING);
    279 COMPILE_ASSERT_MATCHING_ENUM(TypeWestPanning, PP_MOUSECURSOR_TYPE_WESTPANNING);
    280 COMPILE_ASSERT_MATCHING_ENUM(TypeMove, PP_MOUSECURSOR_TYPE_MOVE);
    281 COMPILE_ASSERT_MATCHING_ENUM(TypeVerticalText,
    282                              PP_MOUSECURSOR_TYPE_VERTICALTEXT);
    283 COMPILE_ASSERT_MATCHING_ENUM(TypeCell, PP_MOUSECURSOR_TYPE_CELL);
    284 COMPILE_ASSERT_MATCHING_ENUM(TypeContextMenu, PP_MOUSECURSOR_TYPE_CONTEXTMENU);
    285 COMPILE_ASSERT_MATCHING_ENUM(TypeAlias, PP_MOUSECURSOR_TYPE_ALIAS);
    286 COMPILE_ASSERT_MATCHING_ENUM(TypeProgress, PP_MOUSECURSOR_TYPE_PROGRESS);
    287 COMPILE_ASSERT_MATCHING_ENUM(TypeNoDrop, PP_MOUSECURSOR_TYPE_NODROP);
    288 COMPILE_ASSERT_MATCHING_ENUM(TypeCopy, PP_MOUSECURSOR_TYPE_COPY);
    289 COMPILE_ASSERT_MATCHING_ENUM(TypeNone, PP_MOUSECURSOR_TYPE_NONE);
    290 COMPILE_ASSERT_MATCHING_ENUM(TypeNotAllowed, PP_MOUSECURSOR_TYPE_NOTALLOWED);
    291 COMPILE_ASSERT_MATCHING_ENUM(TypeZoomIn, PP_MOUSECURSOR_TYPE_ZOOMIN);
    292 COMPILE_ASSERT_MATCHING_ENUM(TypeZoomOut, PP_MOUSECURSOR_TYPE_ZOOMOUT);
    293 COMPILE_ASSERT_MATCHING_ENUM(TypeGrab, PP_MOUSECURSOR_TYPE_GRAB);
    294 COMPILE_ASSERT_MATCHING_ENUM(TypeGrabbing, PP_MOUSECURSOR_TYPE_GRABBING);
    295 // Do not assert WebCursorInfo::TypeCustom == PP_CURSORTYPE_CUSTOM;
    296 // PP_CURSORTYPE_CUSTOM is pinned to allow new cursor types.
    297 
    298 COMPILE_ASSERT_PRINT_SCALING_MATCHING_ENUM(WebKit::WebPrintScalingOptionNone,
    299                                            PP_PRINTSCALINGOPTION_NONE);
    300 COMPILE_ASSERT_PRINT_SCALING_MATCHING_ENUM(
    301     WebKit::WebPrintScalingOptionFitToPrintableArea,
    302     PP_PRINTSCALINGOPTION_FIT_TO_PRINTABLE_AREA);
    303 COMPILE_ASSERT_PRINT_SCALING_MATCHING_ENUM(
    304     WebKit::WebPrintScalingOptionSourceSize, PP_PRINTSCALINGOPTION_SOURCE_SIZE);
    305 
    306 // Sets |*security_origin| to be the WebKit security origin associated with the
    307 // document containing the given plugin instance. On success, returns true. If
    308 // the instance is invalid, returns false and |*security_origin| will be
    309 // unchanged.
    310 bool SecurityOriginForInstance(PP_Instance instance_id,
    311                                WebKit::WebSecurityOrigin* security_origin) {
    312   PepperPluginInstanceImpl* instance =
    313       HostGlobals::Get()->GetInstance(instance_id);
    314   if (!instance)
    315     return false;
    316 
    317   WebElement plugin_element = instance->container()->element();
    318   *security_origin = plugin_element.document().securityOrigin();
    319   return true;
    320 }
    321 
    322 // Convert the given vector to an array of C-strings. The strings in the
    323 // returned vector are only guaranteed valid so long as the vector of strings
    324 // is not modified.
    325 scoped_ptr<const char*[]> StringVectorToArgArray(
    326     const std::vector<std::string>& vector) {
    327   scoped_ptr<const char*[]> array(new const char*[vector.size()]);
    328   for (size_t i = 0; i < vector.size(); ++i)
    329     array[i] = vector[i].c_str();
    330   return array.Pass();
    331 }
    332 
    333 class PluginInstanceLockTarget : public MouseLockDispatcher::LockTarget {
    334  public:
    335   PluginInstanceLockTarget(PepperPluginInstanceImpl* plugin)
    336       : plugin_(plugin) {}
    337 
    338   virtual void OnLockMouseACK(bool succeeded) OVERRIDE {
    339     plugin_->OnLockMouseACK(succeeded);
    340   }
    341 
    342   virtual void OnMouseLockLost() OVERRIDE {
    343     plugin_->OnMouseLockLost();
    344   }
    345 
    346   virtual bool HandleMouseLockedInputEvent(
    347       const WebKit::WebMouseEvent &event) OVERRIDE {
    348     plugin_->HandleMouseLockedInputEvent(event);
    349     return true;
    350   }
    351 
    352  private:
    353   PepperPluginInstanceImpl* plugin_;
    354 };
    355 
    356 
    357 }  // namespace
    358 
    359 // static
    360 PepperPluginInstanceImpl* PepperPluginInstanceImpl::Create(
    361     RenderViewImpl* render_view,
    362     PluginModule* module,
    363     WebPluginContainer* container,
    364     const GURL& plugin_url) {
    365   base::Callback<const void*(const char*)> get_plugin_interface_func =
    366       base::Bind(&PluginModule::GetPluginInterface, module);
    367   PPP_Instance_Combined* ppp_instance_combined =
    368       PPP_Instance_Combined::Create(get_plugin_interface_func);
    369   if (!ppp_instance_combined)
    370     return NULL;
    371   return new PepperPluginInstanceImpl(render_view, module,
    372                                       ppp_instance_combined, container,
    373                                       plugin_url);
    374 }
    375 
    376 PepperPluginInstanceImpl::ExternalDocumentLoader::ExternalDocumentLoader()
    377     : finished_loading_(false) {
    378 }
    379 
    380 PepperPluginInstanceImpl::ExternalDocumentLoader::~ExternalDocumentLoader() {
    381 }
    382 
    383 void PepperPluginInstanceImpl::ExternalDocumentLoader::ReplayReceivedData(
    384     WebURLLoaderClient* document_loader) {
    385   for (std::list<std::string>::iterator it = data_.begin();
    386        it != data_.end(); ++it) {
    387     document_loader->didReceiveData(NULL, it->c_str(), it->length(),
    388                                     0 /* encoded_data_length */);
    389   }
    390   if (finished_loading_) {
    391     document_loader->didFinishLoading(NULL,
    392                                       0 /* finish_time */);
    393   }
    394   if (error_.get()) {
    395     document_loader->didFail(NULL, *error_);
    396   }
    397 }
    398 
    399 void PepperPluginInstanceImpl::ExternalDocumentLoader::didReceiveData(
    400     WebURLLoader* loader,
    401     const char* data,
    402     int data_length,
    403     int encoded_data_length) {
    404   data_.push_back(std::string(data, data_length));
    405 }
    406 
    407 void PepperPluginInstanceImpl::ExternalDocumentLoader::didFinishLoading(
    408     WebURLLoader* loader,
    409     double finish_time) {
    410   DCHECK(!finished_loading_);
    411   finished_loading_ = true;
    412 }
    413 
    414 void PepperPluginInstanceImpl::ExternalDocumentLoader::didFail(
    415     WebURLLoader* loader,
    416     const WebURLError& error) {
    417   DCHECK(!error_.get());
    418   error_.reset(new WebURLError(error));
    419 }
    420 
    421 PepperPluginInstanceImpl::GamepadImpl::GamepadImpl()
    422     : Resource(ppapi::Resource::Untracked()) {
    423 }
    424 
    425 PepperPluginInstanceImpl::GamepadImpl::~GamepadImpl() {
    426 }
    427 
    428 PPB_Gamepad_API* PepperPluginInstanceImpl::GamepadImpl::AsPPB_Gamepad_API() {
    429   return this;
    430 }
    431 
    432 void PepperPluginInstanceImpl::GamepadImpl::Sample(
    433     PP_Instance instance,
    434     PP_GamepadsSampleData* data) {
    435   WebKit::WebGamepads webkit_data;
    436   RenderThreadImpl::current()->SampleGamepads(&webkit_data);
    437   ConvertWebKitGamepadData(
    438       *reinterpret_cast<const ppapi::WebKitGamepads*>(&webkit_data), data);
    439 }
    440 
    441 PepperPluginInstanceImpl::PepperPluginInstanceImpl(
    442     RenderViewImpl* render_view,
    443     PluginModule* module,
    444     ppapi::PPP_Instance_Combined* instance_interface,
    445     WebPluginContainer* container,
    446     const GURL& plugin_url)
    447     : render_view_(render_view),
    448       module_(module),
    449       instance_interface_(instance_interface),
    450       pp_instance_(0),
    451       container_(container),
    452       layer_bound_to_fullscreen_(false),
    453       plugin_url_(plugin_url),
    454       full_frame_(false),
    455       sent_initial_did_change_view_(false),
    456       view_change_weak_ptr_factory_(this),
    457       bound_graphics_2d_platform_(NULL),
    458       has_webkit_focus_(false),
    459       has_content_area_focus_(false),
    460       find_identifier_(-1),
    461       plugin_find_interface_(NULL),
    462       plugin_input_event_interface_(NULL),
    463       plugin_messaging_interface_(NULL),
    464       plugin_mouse_lock_interface_(NULL),
    465       plugin_pdf_interface_(NULL),
    466       plugin_private_interface_(NULL),
    467       plugin_selection_interface_(NULL),
    468       plugin_textinput_interface_(NULL),
    469       plugin_zoom_interface_(NULL),
    470       checked_for_plugin_input_event_interface_(false),
    471       checked_for_plugin_messaging_interface_(false),
    472       checked_for_plugin_pdf_interface_(false),
    473       gamepad_impl_(new GamepadImpl()),
    474       plugin_print_interface_(NULL),
    475       plugin_graphics_3d_interface_(NULL),
    476       always_on_top_(false),
    477       fullscreen_container_(NULL),
    478       flash_fullscreen_(false),
    479       desired_fullscreen_state_(false),
    480       sad_plugin_(NULL),
    481       input_event_mask_(0),
    482       filtered_input_event_mask_(0),
    483       text_input_type_(kPluginDefaultTextInputType),
    484       text_input_caret_(0, 0, 0, 0),
    485       text_input_caret_bounds_(0, 0, 0, 0),
    486       text_input_caret_set_(false),
    487       selection_caret_(0),
    488       selection_anchor_(0),
    489       pending_user_gesture_(0.0),
    490       document_loader_(NULL),
    491       external_document_load_(false),
    492       npp_(new NPP_t),
    493       isolate_(v8::Isolate::GetCurrent()) {
    494   pp_instance_ = HostGlobals::Get()->AddInstance(this);
    495 
    496   memset(&current_print_settings_, 0, sizeof(current_print_settings_));
    497   module_->InstanceCreated(this);
    498 
    499   if (render_view) {  // NULL in tests
    500     render_view->PepperInstanceCreated(this);
    501     view_data_.is_page_visible = !render_view->is_hidden();
    502 
    503     // Set the initial focus.
    504     SetContentAreaFocus(render_view_->has_focus());
    505 
    506     if (!module_->IsProxied()) {
    507       PepperBrowserConnection* browser_connection =
    508           PepperBrowserConnection::Get(render_view_);
    509       browser_connection->DidCreateInProcessInstance(
    510           pp_instance(),
    511           render_view_->GetRoutingID(),
    512           container_->element().document().url(),
    513           GetPluginURL());
    514     }
    515   }
    516 
    517   RendererPpapiHostImpl* host_impl = module_->renderer_ppapi_host();
    518   resource_creation_ = host_impl->CreateInProcessResourceCreationAPI(this);
    519 
    520   if (GetContentClient()->renderer() &&  // NULL in unit tests.
    521       GetContentClient()->renderer()->IsExternalPepperPlugin(module->name()))
    522     external_document_load_ = true;
    523 }
    524 
    525 PepperPluginInstanceImpl::~PepperPluginInstanceImpl() {
    526   DCHECK(!fullscreen_container_);
    527 
    528   // Force-unbind any Graphics. In the case of Graphics2D, if the plugin
    529   // leaks the graphics 2D, it may actually get cleaned up after our
    530   // destruction, so we need its pointers to be up-to-date.
    531   BindGraphics(pp_instance(), 0);
    532 
    533   // Free all the plugin objects. This will automatically clear the back-
    534   // pointer from the NPObject so WebKit can't call into the plugin any more.
    535   //
    536   // Swap out the set so we can delete from it (the objects will try to
    537   // unregister themselves inside the delete call).
    538   PluginObjectSet plugin_object_copy;
    539   live_plugin_objects_.swap(plugin_object_copy);
    540   for (PluginObjectSet::iterator i = plugin_object_copy.begin();
    541        i != plugin_object_copy.end(); ++i)
    542     delete *i;
    543 
    544   if (TrackedCallback::IsPending(lock_mouse_callback_))
    545     lock_mouse_callback_->Abort();
    546 
    547   if (render_view_)
    548     render_view_->PepperInstanceDeleted(this);
    549 
    550   if (!module_->IsProxied() && render_view_) {
    551     PepperBrowserConnection* browser_connection =
    552         PepperBrowserConnection::Get(render_view_);
    553     browser_connection->DidDeleteInProcessInstance(pp_instance());
    554   }
    555 
    556   UnSetAndDeleteLockTargetAdapter();
    557   module_->InstanceDeleted(this);
    558   // If we switched from the NaCl plugin module, notify it too.
    559   if (original_module_.get())
    560     original_module_->InstanceDeleted(this);
    561 
    562   // This should be last since some of the above "instance deleted" calls will
    563   // want to look up in the global map to get info off of our object.
    564   HostGlobals::Get()->InstanceDeleted(pp_instance_);
    565 }
    566 
    567 // NOTE: Any of these methods that calls into the plugin needs to take into
    568 // account that the plugin may use Var to remove the <embed> from the DOM, which
    569 // will make the PepperWebPluginImpl drop its reference, usually the last one.
    570 // If a method needs to access a member of the instance after the call has
    571 // returned, then it needs to keep its own reference on the stack.
    572 
    573 void PepperPluginInstanceImpl::Delete() {
    574   // Keep a reference on the stack. See NOTE above.
    575   scoped_refptr<PepperPluginInstanceImpl> ref(this);
    576   // Force the MessageChannel to release its "passthrough object" which should
    577   // release our last reference to the "InstanceObject" and will probably
    578   // destroy it. We want to do this prior to calling DidDestroy in case the
    579   // destructor of the instance object tries to use the instance.
    580   message_channel_->SetPassthroughObject(NULL);
    581   // If this is a NaCl plugin instance, shut down the NaCl plugin by calling
    582   // its DidDestroy. Don't call DidDestroy on the untrusted plugin instance,
    583   // since there is little that it can do at this point.
    584   if (original_instance_interface_)
    585     original_instance_interface_->DidDestroy(pp_instance());
    586   else
    587     instance_interface_->DidDestroy(pp_instance());
    588   // Ensure we don't attempt to call functions on the destroyed instance.
    589   original_instance_interface_.reset();
    590   instance_interface_.reset();
    591 
    592   if (fullscreen_container_) {
    593     fullscreen_container_->Destroy();
    594     fullscreen_container_ = NULL;
    595   }
    596   bound_graphics_3d_ = NULL;
    597   UpdateLayer();
    598   container_ = NULL;
    599 }
    600 
    601 void PepperPluginInstanceImpl::Paint(WebCanvas* canvas,
    602                                      const gfx::Rect& plugin_rect,
    603                                      const gfx::Rect& paint_rect) {
    604   TRACE_EVENT0("ppapi", "PluginInstance::Paint");
    605   if (module()->is_crashed()) {
    606     // Crashed plugin painting.
    607     if (!sad_plugin_)  // Lazily initialize bitmap.
    608       sad_plugin_ = GetContentClient()->renderer()->GetSadPluginBitmap();
    609     if (sad_plugin_)
    610       PaintSadPlugin(canvas, plugin_rect, *sad_plugin_);
    611     return;
    612   }
    613 
    614   if (bound_graphics_2d_platform_)
    615     bound_graphics_2d_platform_->Paint(canvas, plugin_rect, paint_rect);
    616 }
    617 
    618 void PepperPluginInstanceImpl::InvalidateRect(const gfx::Rect& rect) {
    619   if (fullscreen_container_) {
    620     if (rect.IsEmpty())
    621       fullscreen_container_->Invalidate();
    622     else
    623       fullscreen_container_->InvalidateRect(rect);
    624   } else {
    625     if (!container_ ||
    626         view_data_.rect.size.width == 0 || view_data_.rect.size.height == 0)
    627       return;  // Nothing to do.
    628     if (rect.IsEmpty())
    629       container_->invalidate();
    630     else
    631       container_->invalidateRect(rect);
    632   }
    633 }
    634 
    635 void PepperPluginInstanceImpl::ScrollRect(int dx,
    636                                           int dy,
    637                                           const gfx::Rect& rect) {
    638   if (fullscreen_container_) {
    639     fullscreen_container_->ScrollRect(dx, dy, rect);
    640   } else {
    641     if (full_frame_ && !IsViewAccelerated()) {
    642       container_->scrollRect(dx, dy, rect);
    643     } else {
    644       // Can't do optimized scrolling since there could be other elements on top
    645       // of us or the view renders via the accelerated compositor which is
    646       // incompatible with the move and backfill scrolling model.
    647       InvalidateRect(rect);
    648     }
    649   }
    650 }
    651 
    652 void PepperPluginInstanceImpl::CommitBackingTexture() {
    653   if (texture_layer_.get())
    654     texture_layer_->SetNeedsDisplay();
    655 }
    656 
    657 void PepperPluginInstanceImpl::InstanceCrashed() {
    658   // Force free all resources and vars.
    659   HostGlobals::Get()->InstanceCrashed(pp_instance());
    660 
    661   // Free any associated graphics.
    662   SetFullscreen(false);
    663   FlashSetFullscreen(false, false);
    664   // Unbind current 2D or 3D graphics context.
    665   BindGraphics(pp_instance(), 0);
    666   InvalidateRect(gfx::Rect());
    667 
    668   render_view_->PluginCrashed(module_->path(), module_->GetPeerProcessId());
    669   UnSetAndDeleteLockTargetAdapter();
    670 }
    671 
    672 static void SetGPUHistogram(const ppapi::Preferences& prefs,
    673                             const std::vector<std::string>& arg_names,
    674                             const std::vector<std::string>& arg_values) {
    675   // Calculate a histogram to let us determine how likely people are to try to
    676   // run Stage3D content on machines that have it blacklisted.
    677 #if defined(OS_WIN)
    678   bool needs_gpu = false;
    679   bool is_xp = base::win::GetVersion() <= base::win::VERSION_XP;
    680 
    681   for (size_t i = 0; i < arg_names.size(); i++) {
    682     if (arg_names[i] == "wmode") {
    683       // In theory content other than Flash could have a "wmode" argument,
    684       // but that's pretty unlikely.
    685       if (arg_values[i] == "direct" || arg_values[i] == "gpu")
    686         needs_gpu = true;
    687       break;
    688     }
    689   }
    690   // 0 : No 3D content and GPU is blacklisted
    691   // 1 : No 3D content and GPU is not blacklisted
    692   // 2 : 3D content but GPU is blacklisted
    693   // 3 : 3D content and GPU is not blacklisted
    694   // 4 : No 3D content and GPU is blacklisted on XP
    695   // 5 : No 3D content and GPU is not blacklisted on XP
    696   // 6 : 3D content but GPU is blacklisted on XP
    697   // 7 : 3D content and GPU is not blacklisted on XP
    698   UMA_HISTOGRAM_ENUMERATION("Flash.UsesGPU",
    699       is_xp * 4 + needs_gpu * 2 + prefs.is_webgl_supported, 8);
    700 #endif
    701 }
    702 
    703 bool PepperPluginInstanceImpl::Initialize(
    704     const std::vector<std::string>& arg_names,
    705     const std::vector<std::string>& arg_values,
    706     bool full_frame) {
    707   message_channel_.reset(new MessageChannel(this));
    708 
    709   full_frame_ = full_frame;
    710 
    711   UpdateTouchEventRequest();
    712   container_->setWantsWheelEvents(IsAcceptingWheelEvents());
    713 
    714   SetGPUHistogram(ppapi::Preferences(render_view_->webkit_preferences()),
    715                   arg_names, arg_values);
    716 
    717   argn_ = arg_names;
    718   argv_ = arg_values;
    719   scoped_ptr<const char*[]> argn_array(StringVectorToArgArray(argn_));
    720   scoped_ptr<const char*[]> argv_array(StringVectorToArgArray(argv_));
    721   bool success =  PP_ToBool(instance_interface_->DidCreate(pp_instance(),
    722                                                            argn_.size(),
    723                                                            argn_array.get(),
    724                                                            argv_array.get()));
    725   if (success)
    726     message_channel_->StopQueueingJavaScriptMessages();
    727   return success;
    728 }
    729 
    730 bool PepperPluginInstanceImpl::HandleDocumentLoad(
    731     const WebKit::WebURLResponse& response) {
    732   DCHECK(!document_loader_);
    733   if (external_document_load_) {
    734     // The external proxy isn't available, so save the response and record
    735     // document load notifications for later replay.
    736     external_document_response_ = response;
    737     external_document_loader_.reset(new ExternalDocumentLoader());
    738     document_loader_ = external_document_loader_.get();
    739     return true;
    740   }
    741 
    742   if (module()->is_crashed()) {
    743     // Don't create a resource for a crashed plugin.
    744     container()->element().document().frame()->stopLoading();
    745     return false;
    746   }
    747 
    748   DCHECK(!document_loader_);
    749 
    750   // Create a loader resource host for this load. Note that we have to set
    751   // the document_loader before issuing the in-process
    752   // PPP_Instance.HandleDocumentLoad call below, since this may reentrantly
    753   // call into the instance and expect it to be valid.
    754   RendererPpapiHostImpl* host_impl = module_->renderer_ppapi_host();
    755   PepperURLLoaderHost* loader_host =
    756       new PepperURLLoaderHost(host_impl, true, pp_instance(), 0);
    757   // TODO(teravest): Remove set_document_loader() from instance and clean up
    758   // this relationship.
    759   set_document_loader(loader_host);
    760   loader_host->didReceiveResponse(NULL, response);
    761 
    762   // This host will be pending until the resource object attaches to it.
    763   //
    764   // PpapiHost now owns the pointer to loader_host, so we don't have to worry
    765   // about managing it.
    766   int pending_host_id = host_impl->GetPpapiHost()->AddPendingResourceHost(
    767       scoped_ptr<ppapi::host::ResourceHost>(loader_host));
    768   DCHECK(pending_host_id);
    769 
    770   DataFromWebURLResponse(
    771       pp_instance(),
    772       response,
    773       base::Bind(&PepperPluginInstanceImpl::DidDataFromWebURLResponse,
    774                  AsWeakPtr(),
    775                  response,
    776                  pending_host_id));
    777 
    778   // If the load was not abandoned, document_loader_ will now be set. It's
    779   // possible that the load was canceled by now and document_loader_ was
    780   // already nulled out.
    781   return true;
    782 }
    783 
    784 bool PepperPluginInstanceImpl::SendCompositionEventToPlugin(
    785     PP_InputEvent_Type type, const base::string16& text) {
    786   std::vector<WebKit::WebCompositionUnderline> empty;
    787   return SendCompositionEventWithUnderlineInformationToPlugin(
    788       type, text, empty, static_cast<int>(text.size()),
    789       static_cast<int>(text.size()));
    790 }
    791 
    792 bool PepperPluginInstanceImpl::
    793     SendCompositionEventWithUnderlineInformationToPlugin(
    794         PP_InputEvent_Type type,
    795         const base::string16& text,
    796         const std::vector<WebKit::WebCompositionUnderline>& underlines,
    797         int selection_start,
    798         int selection_end) {
    799   // Keep a reference on the stack. See NOTE above.
    800   scoped_refptr<PepperPluginInstanceImpl> ref(this);
    801 
    802   if (!LoadInputEventInterface())
    803     return false;
    804 
    805   PP_InputEvent_Class event_class = PP_INPUTEVENT_CLASS_IME;
    806   if (!(filtered_input_event_mask_ & event_class) &&
    807       !(input_event_mask_ & event_class))
    808     return false;
    809 
    810   ppapi::InputEventData event;
    811   event.event_type = type;
    812   event.event_time_stamp = ppapi::TimeTicksToPPTimeTicks(
    813       base::TimeTicks::Now());
    814 
    815   // Convert UTF16 text to UTF8 with offset conversion.
    816   std::vector<size_t> utf16_offsets;
    817   utf16_offsets.push_back(selection_start);
    818   utf16_offsets.push_back(selection_end);
    819   for (size_t i = 0; i < underlines.size(); ++i) {
    820     utf16_offsets.push_back(underlines[i].startOffset);
    821     utf16_offsets.push_back(underlines[i].endOffset);
    822   }
    823   std::vector<size_t> utf8_offsets(utf16_offsets);
    824   event.character_text = base::UTF16ToUTF8AndAdjustOffsets(text, &utf8_offsets);
    825 
    826   // Set the converted selection range.
    827   event.composition_selection_start = (utf8_offsets[0] == std::string::npos ?
    828       event.character_text.size() : utf8_offsets[0]);
    829   event.composition_selection_end = (utf8_offsets[1] == std::string::npos ?
    830       event.character_text.size() : utf8_offsets[1]);
    831 
    832   // Set the converted segmentation points.
    833   // Be sure to add 0 and size(), and remove duplication or errors.
    834   std::set<size_t> offset_set(utf8_offsets.begin()+2, utf8_offsets.end());
    835   offset_set.insert(0);
    836   offset_set.insert(event.character_text.size());
    837   offset_set.erase(std::string::npos);
    838   event.composition_segment_offsets.assign(offset_set.begin(),
    839                                            offset_set.end());
    840 
    841   // Set the composition target.
    842   for (size_t i = 0; i < underlines.size(); ++i) {
    843     if (underlines[i].thick) {
    844       std::vector<uint32_t>::iterator it =
    845           std::find(event.composition_segment_offsets.begin(),
    846                     event.composition_segment_offsets.end(),
    847                     utf8_offsets[2*i+2]);
    848       if (it != event.composition_segment_offsets.end()) {
    849         event.composition_target_segment =
    850             it - event.composition_segment_offsets.begin();
    851         break;
    852       }
    853     }
    854   }
    855 
    856   // Send the event.
    857   bool handled = false;
    858   if (filtered_input_event_mask_ & event_class)
    859     event.is_filtered = true;
    860   else
    861     handled = true;  // Unfiltered events are assumed to be handled.
    862   scoped_refptr<PPB_InputEvent_Shared> event_resource(
    863       new PPB_InputEvent_Shared(ppapi::OBJECT_IS_IMPL, pp_instance(), event));
    864   handled |= PP_ToBool(plugin_input_event_interface_->HandleInputEvent(
    865       pp_instance(), event_resource->pp_resource()));
    866   return handled;
    867 }
    868 
    869 void PepperPluginInstanceImpl::RequestInputEventsHelper(
    870     uint32_t event_classes) {
    871   if (event_classes & PP_INPUTEVENT_CLASS_TOUCH)
    872     UpdateTouchEventRequest();
    873   if (event_classes & PP_INPUTEVENT_CLASS_WHEEL)
    874     container_->setWantsWheelEvents(IsAcceptingWheelEvents());
    875 }
    876 
    877 bool PepperPluginInstanceImpl::HandleCompositionStart(
    878     const base::string16& text) {
    879   return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_COMPOSITION_START,
    880                                       text);
    881 }
    882 
    883 bool PepperPluginInstanceImpl::HandleCompositionUpdate(
    884     const base::string16& text,
    885     const std::vector<WebKit::WebCompositionUnderline>& underlines,
    886     int selection_start,
    887     int selection_end) {
    888   return SendCompositionEventWithUnderlineInformationToPlugin(
    889       PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE,
    890       text, underlines, selection_start, selection_end);
    891 }
    892 
    893 bool PepperPluginInstanceImpl::HandleCompositionEnd(
    894     const base::string16& text) {
    895   return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_COMPOSITION_END,
    896                                       text);
    897 }
    898 
    899 bool PepperPluginInstanceImpl::HandleTextInput(const base::string16& text) {
    900   return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_TEXT,
    901                                       text);
    902 }
    903 
    904 void PepperPluginInstanceImpl::GetSurroundingText(base::string16* text,
    905                                                   ui::Range* range) const {
    906   std::vector<size_t> offsets;
    907   offsets.push_back(selection_anchor_);
    908   offsets.push_back(selection_caret_);
    909   *text = base::UTF8ToUTF16AndAdjustOffsets(surrounding_text_, &offsets);
    910   range->set_start(offsets[0] == base::string16::npos ? text->size()
    911                                                       : offsets[0]);
    912   range->set_end(offsets[1] == base::string16::npos ? text->size()
    913                                                     : offsets[1]);
    914 }
    915 
    916 bool PepperPluginInstanceImpl::IsPluginAcceptingCompositionEvents() const {
    917   return (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_IME) ||
    918       (input_event_mask_ & PP_INPUTEVENT_CLASS_IME);
    919 }
    920 
    921 gfx::Rect PepperPluginInstanceImpl::GetCaretBounds() const {
    922   if (!text_input_caret_set_) {
    923     // If it is never set by the plugin, use the bottom left corner.
    924     return gfx::Rect(view_data_.rect.point.x,
    925                      view_data_.rect.point.y + view_data_.rect.size.height,
    926                      0, 0);
    927   }
    928 
    929   // TODO(kinaba) Take CSS transformation into accont.
    930   // TODO(kinaba) Take bounding_box into account. On some platforms, an
    931   // "exclude rectangle" where candidate window must avoid the region can be
    932   // passed to IME. Currently, we pass only the caret rectangle because
    933   // it is the only information supported uniformly in Chromium.
    934   gfx::Rect caret(text_input_caret_);
    935   caret.Offset(view_data_.rect.point.x, view_data_.rect.point.y);
    936   return caret;
    937 }
    938 
    939 bool PepperPluginInstanceImpl::HandleInputEvent(
    940     const WebKit::WebInputEvent& event,
    941     WebCursorInfo* cursor_info) {
    942   TRACE_EVENT0("ppapi", "PepperPluginInstanceImpl::HandleInputEvent");
    943 
    944   if (WebInputEvent::isMouseEventType(event.type)) {
    945     render_view_->PepperDidReceiveMouseEvent(this);
    946   }
    947 
    948   // Don't dispatch input events to crashed plugins.
    949   if (module()->is_crashed())
    950     return false;
    951 
    952   // Keep a reference on the stack. See NOTE above.
    953   scoped_refptr<PepperPluginInstanceImpl> ref(this);
    954 
    955   bool rv = false;
    956   if (LoadInputEventInterface()) {
    957     PP_InputEvent_Class event_class = ClassifyInputEvent(event.type);
    958     if (!event_class)
    959       return false;
    960 
    961     if ((filtered_input_event_mask_ & event_class) ||
    962         (input_event_mask_ & event_class)) {
    963       // Actually send the event.
    964       std::vector< ppapi::InputEventData > events;
    965       CreateInputEventData(event, &events);
    966 
    967       // Allow the user gesture to be pending after the plugin handles the
    968       // event. This allows out-of-process plugins to respond to the user
    969       // gesture after processing has finished here.
    970       if (WebUserGestureIndicator::isProcessingUserGesture()) {
    971         pending_user_gesture_ =
    972             ppapi::EventTimeToPPTimeTicks(event.timeStampSeconds);
    973         pending_user_gesture_token_ =
    974             WebUserGestureIndicator::currentUserGestureToken();
    975         pending_user_gesture_token_.setOutOfProcess();
    976       }
    977 
    978       // Each input event may generate more than one PP_InputEvent.
    979       for (size_t i = 0; i < events.size(); i++) {
    980         if (filtered_input_event_mask_ & event_class)
    981           events[i].is_filtered = true;
    982         else
    983           rv = true;  // Unfiltered events are assumed to be handled.
    984         scoped_refptr<PPB_InputEvent_Shared> event_resource(
    985             new PPB_InputEvent_Shared(ppapi::OBJECT_IS_IMPL,
    986                                       pp_instance(), events[i]));
    987 
    988         rv |= PP_ToBool(plugin_input_event_interface_->HandleInputEvent(
    989             pp_instance(), event_resource->pp_resource()));
    990       }
    991     }
    992   }
    993 
    994   if (cursor_)
    995     *cursor_info = *cursor_;
    996   return rv;
    997 }
    998 
    999 void PepperPluginInstanceImpl::HandleMessage(PP_Var message) {
   1000   TRACE_EVENT0("ppapi", "PepperPluginInstanceImpl::HandleMessage");
   1001   // Keep a reference on the stack. See NOTE above.
   1002   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1003   if (!LoadMessagingInterface())
   1004     return;
   1005   plugin_messaging_interface_->HandleMessage(pp_instance(), message);
   1006 }
   1007 
   1008 PP_Var PepperPluginInstanceImpl::GetInstanceObject() {
   1009   // Keep a reference on the stack. See NOTE above.
   1010   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1011 
   1012   // If the plugin supports the private instance interface, try to retrieve its
   1013   // instance object.
   1014   if (LoadPrivateInterface())
   1015     return plugin_private_interface_->GetInstanceObject(pp_instance());
   1016   return PP_MakeUndefined();
   1017 }
   1018 
   1019 void PepperPluginInstanceImpl::ViewChanged(
   1020     const gfx::Rect& position,
   1021     const gfx::Rect& clip,
   1022     const std::vector<gfx::Rect>& cut_outs_rects) {
   1023   // WebKit can give weird (x,y) positions for empty clip rects (since the
   1024   // position technically doesn't matter). But we want to make these
   1025   // consistent since this is given to the plugin, so force everything to 0
   1026   // in the "everything is clipped" case.
   1027   gfx::Rect new_clip;
   1028   if (!clip.IsEmpty())
   1029     new_clip = clip;
   1030 
   1031   cut_outs_rects_ = cut_outs_rects;
   1032 
   1033   view_data_.rect = PP_FromGfxRect(position);
   1034   view_data_.clip_rect = PP_FromGfxRect(clip);
   1035   view_data_.device_scale = container_->deviceScaleFactor();
   1036   view_data_.css_scale = container_->pageZoomFactor() *
   1037                          container_->pageScaleFactor();
   1038 
   1039   if (desired_fullscreen_state_ || view_data_.is_fullscreen) {
   1040     WebElement element = container_->element();
   1041     WebDocument document = element.document();
   1042     bool is_fullscreen_element = (element == document.fullScreenElement());
   1043     if (!view_data_.is_fullscreen && desired_fullscreen_state_ &&
   1044         render_view_->is_fullscreen() && is_fullscreen_element) {
   1045       // Entered fullscreen. Only possible via SetFullscreen().
   1046       view_data_.is_fullscreen = true;
   1047     } else if (view_data_.is_fullscreen && !is_fullscreen_element) {
   1048       // Exited fullscreen. Possible via SetFullscreen() or F11/link,
   1049       // so desired_fullscreen_state might be out-of-date.
   1050       desired_fullscreen_state_ = false;
   1051       view_data_.is_fullscreen = false;
   1052 
   1053       // This operation will cause the plugin to re-layout which will send more
   1054       // DidChangeView updates. Schedule an asynchronous update and suppress
   1055       // notifications until that completes to avoid sending intermediate sizes
   1056       // to the plugins.
   1057       ScheduleAsyncDidChangeView();
   1058 
   1059       // Reset the size attributes that we hacked to fill in the screen and
   1060       // retrigger ViewChanged. Make sure we don't forward duplicates of
   1061       // this view to the plugin.
   1062       ResetSizeAttributesAfterFullscreen();
   1063       return;
   1064     }
   1065   }
   1066 
   1067   UpdateFlashFullscreenState(fullscreen_container_ != NULL);
   1068 
   1069   SendDidChangeView();
   1070 }
   1071 
   1072 void PepperPluginInstanceImpl::SetWebKitFocus(bool has_focus) {
   1073   if (has_webkit_focus_ == has_focus)
   1074     return;
   1075 
   1076   bool old_plugin_focus = PluginHasFocus();
   1077   has_webkit_focus_ = has_focus;
   1078   if (PluginHasFocus() != old_plugin_focus)
   1079     SendFocusChangeNotification();
   1080 }
   1081 
   1082 void PepperPluginInstanceImpl::SetContentAreaFocus(bool has_focus) {
   1083   if (has_content_area_focus_ == has_focus)
   1084     return;
   1085 
   1086   bool old_plugin_focus = PluginHasFocus();
   1087   has_content_area_focus_ = has_focus;
   1088   if (PluginHasFocus() != old_plugin_focus)
   1089     SendFocusChangeNotification();
   1090 }
   1091 
   1092 void PepperPluginInstanceImpl::PageVisibilityChanged(bool is_visible) {
   1093   if (is_visible == view_data_.is_page_visible)
   1094     return;  // Nothing to do.
   1095   view_data_.is_page_visible = is_visible;
   1096 
   1097   // If the initial DidChangeView notification hasn't been sent to the plugin,
   1098   // let it pass the visibility state for us, instead of sending a notification
   1099   // immediately. It is possible that PepperPluginInstanceImpl::ViewChanged()
   1100   // hasn't been called for the first time. In that case, most of the fields in
   1101   // |view_data_| haven't been properly initialized.
   1102   if (sent_initial_did_change_view_)
   1103     SendDidChangeView();
   1104 }
   1105 
   1106 void PepperPluginInstanceImpl::ViewWillInitiatePaint() {
   1107   if (bound_graphics_2d_platform_)
   1108     bound_graphics_2d_platform_->ViewWillInitiatePaint();
   1109   else if (bound_graphics_3d_.get())
   1110     bound_graphics_3d_->ViewWillInitiatePaint();
   1111 }
   1112 
   1113 void PepperPluginInstanceImpl::ViewInitiatedPaint() {
   1114   if (bound_graphics_2d_platform_)
   1115     bound_graphics_2d_platform_->ViewInitiatedPaint();
   1116   else if (bound_graphics_3d_.get())
   1117     bound_graphics_3d_->ViewInitiatedPaint();
   1118 }
   1119 
   1120 void PepperPluginInstanceImpl::ViewFlushedPaint() {
   1121   // Keep a reference on the stack. See NOTE above.
   1122   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1123   if (bound_graphics_2d_platform_)
   1124     bound_graphics_2d_platform_->ViewFlushedPaint();
   1125   else if (bound_graphics_3d_.get())
   1126     bound_graphics_3d_->ViewFlushedPaint();
   1127 }
   1128 
   1129 bool PepperPluginInstanceImpl::GetBitmapForOptimizedPluginPaint(
   1130     const gfx::Rect& paint_bounds,
   1131     TransportDIB** dib,
   1132     gfx::Rect* location,
   1133     gfx::Rect* clip,
   1134     float* scale_factor) {
   1135   if (!always_on_top_)
   1136     return false;
   1137   if (!bound_graphics_2d_platform_ ||
   1138       !bound_graphics_2d_platform_->IsAlwaysOpaque()) {
   1139     return false;
   1140   }
   1141 
   1142   // We specifically want to compare against the area covered by the backing
   1143   // store when seeing if we cover the given paint bounds, since the backing
   1144   // store could be smaller than the declared plugin area.
   1145   PPB_ImageData_Impl* image_data = bound_graphics_2d_platform_->ImageData();
   1146   // ImageDatas created by NaCl don't have a TransportDIB, so can't be
   1147   // optimized this way.
   1148   if (!image_data->GetTransportDIB())
   1149     return false;
   1150 
   1151   gfx::Point plugin_origin = PP_ToGfxPoint(view_data_.rect.point);
   1152   gfx::Vector2d plugin_offset = plugin_origin.OffsetFromOrigin();
   1153   // Convert |paint_bounds| to be relative to the left-top corner of the plugin.
   1154   gfx::Rect relative_paint_bounds(paint_bounds);
   1155   relative_paint_bounds.Offset(-plugin_offset);
   1156 
   1157   gfx::Rect pixel_plugin_backing_store_rect(
   1158       0, 0, image_data->width(), image_data->height());
   1159   float scale = bound_graphics_2d_platform_->GetScale();
   1160   gfx::Rect plugin_backing_store_rect = gfx::ToEnclosedRect(
   1161       gfx::ScaleRect(pixel_plugin_backing_store_rect, scale));
   1162 
   1163   gfx::Rect clip_page = PP_ToGfxRect(view_data_.clip_rect);
   1164   gfx::Rect plugin_paint_rect =
   1165       gfx::IntersectRects(plugin_backing_store_rect, clip_page);
   1166   if (!plugin_paint_rect.Contains(relative_paint_bounds))
   1167     return false;
   1168 
   1169   // Don't do optimized painting if the area to paint intersects with the
   1170   // cut-out rects, otherwise we will paint over them.
   1171   for (std::vector<gfx::Rect>::const_iterator iter = cut_outs_rects_.begin();
   1172        iter != cut_outs_rects_.end(); ++iter) {
   1173     if (relative_paint_bounds.Intersects(*iter))
   1174       return false;
   1175   }
   1176 
   1177   *dib = image_data->GetTransportDIB();
   1178   plugin_backing_store_rect.Offset(plugin_offset);
   1179   *location = plugin_backing_store_rect;
   1180   clip_page.Offset(plugin_offset);
   1181   *clip = clip_page;
   1182   // The plugin scale factor is inverted, e.g. for a device scale factor of 2x
   1183   // the plugin scale factor is 0.5.
   1184   *scale_factor = 1.0 / scale;
   1185   return true;
   1186 }
   1187 
   1188 base::string16 PepperPluginInstanceImpl::GetSelectedText(bool html) {
   1189   // Keep a reference on the stack. See NOTE above.
   1190   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1191   if (!LoadSelectionInterface())
   1192     return base::string16();
   1193 
   1194   PP_Var rv = plugin_selection_interface_->GetSelectedText(pp_instance(),
   1195                                                            PP_FromBool(html));
   1196   StringVar* string = StringVar::FromPPVar(rv);
   1197   base::string16 selection;
   1198   if (string)
   1199     selection = UTF8ToUTF16(string->value());
   1200   // Release the ref the plugin transfered to us.
   1201   HostGlobals::Get()->GetVarTracker()->ReleaseVar(rv);
   1202   return selection;
   1203 }
   1204 
   1205 base::string16 PepperPluginInstanceImpl::GetLinkAtPosition(
   1206     const gfx::Point& point) {
   1207   // Keep a reference on the stack. See NOTE above.
   1208   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1209   if (!LoadPdfInterface())
   1210     return base::string16();
   1211 
   1212   PP_Point p;
   1213   p.x = point.x();
   1214   p.y = point.y();
   1215   PP_Var rv = plugin_pdf_interface_->GetLinkAtPosition(pp_instance(), p);
   1216   StringVar* string = StringVar::FromPPVar(rv);
   1217   base::string16 link;
   1218   if (string)
   1219     link = UTF8ToUTF16(string->value());
   1220   // Release the ref the plugin transfered to us.
   1221   PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(rv);
   1222   return link;
   1223 }
   1224 
   1225 void PepperPluginInstanceImpl::RequestSurroundingText(
   1226     size_t desired_number_of_characters) {
   1227   // Keep a reference on the stack. See NOTE above.
   1228   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1229   if (!LoadTextInputInterface())
   1230     return;
   1231   plugin_textinput_interface_->RequestSurroundingText(
   1232       pp_instance(), desired_number_of_characters);
   1233 }
   1234 
   1235 void PepperPluginInstanceImpl::Zoom(double factor, bool text_only) {
   1236   // Keep a reference on the stack. See NOTE above.
   1237   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1238   if (!LoadZoomInterface())
   1239     return;
   1240   plugin_zoom_interface_->Zoom(pp_instance(), factor, PP_FromBool(text_only));
   1241 }
   1242 
   1243 bool PepperPluginInstanceImpl::StartFind(const base::string16& search_text,
   1244                                          bool case_sensitive,
   1245                                          int identifier) {
   1246   // Keep a reference on the stack. See NOTE above.
   1247   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1248   if (!LoadFindInterface())
   1249     return false;
   1250   find_identifier_ = identifier;
   1251   return PP_ToBool(
   1252       plugin_find_interface_->StartFind(
   1253           pp_instance(),
   1254           UTF16ToUTF8(search_text.c_str()).c_str(),
   1255           PP_FromBool(case_sensitive)));
   1256 }
   1257 
   1258 void PepperPluginInstanceImpl::SelectFindResult(bool forward) {
   1259   // Keep a reference on the stack. See NOTE above.
   1260   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1261   if (LoadFindInterface())
   1262     plugin_find_interface_->SelectFindResult(pp_instance(),
   1263                                              PP_FromBool(forward));
   1264 }
   1265 
   1266 void PepperPluginInstanceImpl::StopFind() {
   1267   // Keep a reference on the stack. See NOTE above.
   1268   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1269   if (!LoadFindInterface())
   1270     return;
   1271   find_identifier_ = -1;
   1272   plugin_find_interface_->StopFind(pp_instance());
   1273 }
   1274 
   1275 bool PepperPluginInstanceImpl::LoadFindInterface() {
   1276   if (!plugin_find_interface_) {
   1277     plugin_find_interface_ =
   1278         static_cast<const PPP_Find_Dev*>(module_->GetPluginInterface(
   1279             PPP_FIND_DEV_INTERFACE));
   1280   }
   1281 
   1282   return !!plugin_find_interface_;
   1283 }
   1284 
   1285 bool PepperPluginInstanceImpl::LoadInputEventInterface() {
   1286   if (!checked_for_plugin_input_event_interface_) {
   1287     checked_for_plugin_input_event_interface_ = true;
   1288     plugin_input_event_interface_ =
   1289         static_cast<const PPP_InputEvent*>(module_->GetPluginInterface(
   1290             PPP_INPUT_EVENT_INTERFACE));
   1291   }
   1292   return !!plugin_input_event_interface_;
   1293 }
   1294 
   1295 bool PepperPluginInstanceImpl::LoadMessagingInterface() {
   1296   if (!checked_for_plugin_messaging_interface_) {
   1297     checked_for_plugin_messaging_interface_ = true;
   1298     plugin_messaging_interface_ =
   1299         static_cast<const PPP_Messaging*>(module_->GetPluginInterface(
   1300             PPP_MESSAGING_INTERFACE));
   1301   }
   1302   return !!plugin_messaging_interface_;
   1303 }
   1304 
   1305 bool PepperPluginInstanceImpl::LoadMouseLockInterface() {
   1306   if (!plugin_mouse_lock_interface_) {
   1307     plugin_mouse_lock_interface_ =
   1308         static_cast<const PPP_MouseLock*>(module_->GetPluginInterface(
   1309             PPP_MOUSELOCK_INTERFACE));
   1310   }
   1311 
   1312   return !!plugin_mouse_lock_interface_;
   1313 }
   1314 
   1315 bool PepperPluginInstanceImpl::LoadPdfInterface() {
   1316   if (!checked_for_plugin_pdf_interface_) {
   1317     checked_for_plugin_pdf_interface_ = true;
   1318     plugin_pdf_interface_ =
   1319         static_cast<const PPP_Pdf_1*>(module_->GetPluginInterface(
   1320             PPP_PDF_INTERFACE_1));
   1321   }
   1322 
   1323   return !!plugin_pdf_interface_;
   1324 }
   1325 
   1326 bool PepperPluginInstanceImpl::LoadPrintInterface() {
   1327   // Only check for the interface if the plugin has dev permission.
   1328   if (!module_->permissions().HasPermission(ppapi::PERMISSION_DEV))
   1329     return false;
   1330   if (!plugin_print_interface_) {
   1331     plugin_print_interface_ = static_cast<const PPP_Printing_Dev*>(
   1332         module_->GetPluginInterface(PPP_PRINTING_DEV_INTERFACE));
   1333   }
   1334   return !!plugin_print_interface_;
   1335 }
   1336 
   1337 bool PepperPluginInstanceImpl::LoadPrivateInterface() {
   1338   // Only check for the interface if the plugin has private permission.
   1339   if (!module_->permissions().HasPermission(ppapi::PERMISSION_PRIVATE))
   1340     return false;
   1341   if (!plugin_private_interface_) {
   1342     plugin_private_interface_ = static_cast<const PPP_Instance_Private*>(
   1343         module_->GetPluginInterface(PPP_INSTANCE_PRIVATE_INTERFACE));
   1344   }
   1345 
   1346   return !!plugin_private_interface_;
   1347 }
   1348 
   1349 bool PepperPluginInstanceImpl::LoadSelectionInterface() {
   1350   if (!plugin_selection_interface_) {
   1351     plugin_selection_interface_ =
   1352         static_cast<const PPP_Selection_Dev*>(module_->GetPluginInterface(
   1353             PPP_SELECTION_DEV_INTERFACE));
   1354   }
   1355   return !!plugin_selection_interface_;
   1356 }
   1357 
   1358 bool PepperPluginInstanceImpl::LoadTextInputInterface() {
   1359   if (!plugin_textinput_interface_) {
   1360     plugin_textinput_interface_ =
   1361         static_cast<const PPP_TextInput_Dev*>(module_->GetPluginInterface(
   1362             PPP_TEXTINPUT_DEV_INTERFACE));
   1363   }
   1364 
   1365   return !!plugin_textinput_interface_;
   1366 }
   1367 
   1368 bool PepperPluginInstanceImpl::LoadZoomInterface() {
   1369   if (!plugin_zoom_interface_) {
   1370     plugin_zoom_interface_ =
   1371         static_cast<const PPP_Zoom_Dev*>(module_->GetPluginInterface(
   1372             PPP_ZOOM_DEV_INTERFACE));
   1373   }
   1374 
   1375   return !!plugin_zoom_interface_;
   1376 }
   1377 
   1378 bool PepperPluginInstanceImpl::PluginHasFocus() const {
   1379   return flash_fullscreen_ || (has_webkit_focus_ && has_content_area_focus_);
   1380 }
   1381 
   1382 void PepperPluginInstanceImpl::SendFocusChangeNotification() {
   1383   // This call can happen during PepperPluginIn>stanceImpl destruction, because
   1384   // WebKit informs the plugin it's losing focus. See crbug.com/236574
   1385   if (!instance_interface_)
   1386     return;
   1387   bool has_focus = PluginHasFocus();
   1388   render_view_->PepperFocusChanged(this, has_focus);
   1389   instance_interface_->DidChangeFocus(pp_instance(), PP_FromBool(has_focus));
   1390 }
   1391 
   1392 void PepperPluginInstanceImpl::UpdateTouchEventRequest() {
   1393   bool raw_touch = (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_TOUCH) ||
   1394                    (input_event_mask_ & PP_INPUTEVENT_CLASS_TOUCH);
   1395   container_->requestTouchEventType(raw_touch ?
   1396       WebKit::WebPluginContainer::TouchEventRequestTypeRaw :
   1397       WebKit::WebPluginContainer::TouchEventRequestTypeSynthesizedMouse);
   1398 }
   1399 
   1400 bool PepperPluginInstanceImpl::IsAcceptingWheelEvents() const {
   1401   return (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_WHEEL) ||
   1402       (input_event_mask_ & PP_INPUTEVENT_CLASS_WHEEL);
   1403 }
   1404 
   1405 void PepperPluginInstanceImpl::ScheduleAsyncDidChangeView() {
   1406   if (view_change_weak_ptr_factory_.HasWeakPtrs())
   1407     return;  // Already scheduled.
   1408   base::MessageLoop::current()->PostTask(
   1409       FROM_HERE,
   1410       base::Bind(&PepperPluginInstanceImpl::SendAsyncDidChangeView,
   1411                  view_change_weak_ptr_factory_.GetWeakPtr()));
   1412 }
   1413 
   1414 void PepperPluginInstanceImpl::SendAsyncDidChangeView() {
   1415   // The bound callback that owns the weak pointer is still valid until after
   1416   // this function returns. SendDidChangeView checks HasWeakPtrs, so we need to
   1417   // invalidate them here.
   1418   // NOTE: If we ever want to have more than one pending callback, it should
   1419   // use a different factory, or we should have a different strategy here.
   1420   view_change_weak_ptr_factory_.InvalidateWeakPtrs();
   1421   SendDidChangeView();
   1422 }
   1423 
   1424 void PepperPluginInstanceImpl::SendDidChangeView() {
   1425   // Don't send DidChangeView to crashed plugins.
   1426   if (module()->is_crashed())
   1427     return;
   1428 
   1429   if (view_change_weak_ptr_factory_.HasWeakPtrs() ||
   1430       (sent_initial_did_change_view_ &&
   1431        last_sent_view_data_.Equals(view_data_)))
   1432     return;  // Nothing to update.
   1433 
   1434   const PP_Size& size = view_data_.rect.size;
   1435   // Avoid sending a notification with a huge rectangle.
   1436   if (size.width < 0  || size.width > kMaxPluginSideLength ||
   1437       size.height < 0 || size.height > kMaxPluginSideLength ||
   1438       // We know this won't overflow due to above checks.
   1439       static_cast<uint32>(size.width) * static_cast<uint32>(size.height) >
   1440           kMaxPluginSize) {
   1441     return;
   1442   }
   1443 
   1444   sent_initial_did_change_view_ = true;
   1445   last_sent_view_data_ = view_data_;
   1446   ScopedPPResource resource(
   1447       ScopedPPResource::PassRef(),
   1448       (new PPB_View_Shared(ppapi::OBJECT_IS_IMPL,
   1449                            pp_instance(), view_data_))->GetReference());
   1450 
   1451   instance_interface_->DidChangeView(pp_instance(), resource,
   1452                                      &view_data_.rect,
   1453                                      &view_data_.clip_rect);
   1454 }
   1455 
   1456 void PepperPluginInstanceImpl::ReportGeometry() {
   1457   // If this call was delayed, we may have transitioned back to fullscreen in
   1458   // the mean time, so only report the geometry if we are actually in normal
   1459   // mode.
   1460   if (container_ && !fullscreen_container_ && !flash_fullscreen_)
   1461     container_->reportGeometry();
   1462 }
   1463 
   1464 bool PepperPluginInstanceImpl::GetPreferredPrintOutputFormat(
   1465     PP_PrintOutputFormat_Dev* format) {
   1466   // Keep a reference on the stack. See NOTE above.
   1467   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1468   if (!LoadPrintInterface())
   1469     return false;
   1470   uint32_t supported_formats =
   1471       plugin_print_interface_->QuerySupportedFormats(pp_instance());
   1472   if (supported_formats & PP_PRINTOUTPUTFORMAT_PDF) {
   1473     *format = PP_PRINTOUTPUTFORMAT_PDF;
   1474     return true;
   1475   }
   1476   return false;
   1477 }
   1478 
   1479 bool PepperPluginInstanceImpl::SupportsPrintInterface() {
   1480   PP_PrintOutputFormat_Dev format;
   1481   return GetPreferredPrintOutputFormat(&format);
   1482 }
   1483 
   1484 bool PepperPluginInstanceImpl::IsPrintScalingDisabled() {
   1485   DCHECK(plugin_print_interface_);
   1486   if (!plugin_print_interface_)
   1487     return false;
   1488   return plugin_print_interface_->IsScalingDisabled(pp_instance()) == PP_TRUE;
   1489 }
   1490 
   1491 int PepperPluginInstanceImpl::PrintBegin(const WebPrintParams& print_params) {
   1492   // Keep a reference on the stack. See NOTE above.
   1493   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1494   PP_PrintOutputFormat_Dev format;
   1495   if (!GetPreferredPrintOutputFormat(&format)) {
   1496     // PrintBegin should not have been called since SupportsPrintInterface
   1497     // would have returned false;
   1498     NOTREACHED();
   1499     return 0;
   1500   }
   1501   int num_pages = 0;
   1502   PP_PrintSettings_Dev print_settings;
   1503   print_settings.printable_area = PP_FromGfxRect(print_params.printableArea);
   1504   print_settings.content_area = PP_FromGfxRect(print_params.printContentArea);
   1505   print_settings.paper_size = PP_FromGfxSize(print_params.paperSize);
   1506   print_settings.dpi = print_params.printerDPI;
   1507   print_settings.orientation = PP_PRINTORIENTATION_NORMAL;
   1508   print_settings.grayscale = PP_FALSE;
   1509   print_settings.print_scaling_option = static_cast<PP_PrintScalingOption_Dev>(
   1510       print_params.printScalingOption);
   1511   print_settings.format = format;
   1512   num_pages = plugin_print_interface_->Begin(pp_instance(),
   1513                                              &print_settings);
   1514   if (!num_pages)
   1515     return 0;
   1516   current_print_settings_ = print_settings;
   1517   canvas_.clear();
   1518   ranges_.clear();
   1519   return num_pages;
   1520 }
   1521 
   1522 bool PepperPluginInstanceImpl::PrintPage(int page_number,
   1523                                          WebKit::WebCanvas* canvas) {
   1524 #if defined(ENABLE_FULL_PRINTING)
   1525   DCHECK(plugin_print_interface_);
   1526   PP_PrintPageNumberRange_Dev page_range;
   1527   page_range.first_page_number = page_range.last_page_number = page_number;
   1528   // The canvas only has a metafile on it for print preview.
   1529   bool save_for_later =
   1530       (printing::MetafileSkiaWrapper::GetMetafileFromCanvas(*canvas) != NULL);
   1531 #if defined(OS_MACOSX) || defined(OS_WIN)
   1532   save_for_later = save_for_later && skia::IsPreviewMetafile(*canvas);
   1533 #endif
   1534   if (save_for_later) {
   1535     ranges_.push_back(page_range);
   1536     canvas_ = skia::SharePtr(canvas);
   1537     return true;
   1538   } else {
   1539     return PrintPageHelper(&page_range, 1, canvas);
   1540   }
   1541 #else  // defined(ENABLED_PRINTING)
   1542   return false;
   1543 #endif
   1544 }
   1545 
   1546 bool PepperPluginInstanceImpl::PrintPageHelper(
   1547     PP_PrintPageNumberRange_Dev* page_ranges,
   1548     int num_ranges,
   1549     WebKit::WebCanvas* canvas) {
   1550   // Keep a reference on the stack. See NOTE above.
   1551   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1552   DCHECK(plugin_print_interface_);
   1553   if (!plugin_print_interface_)
   1554     return false;
   1555   PP_Resource print_output = plugin_print_interface_->PrintPages(
   1556       pp_instance(), page_ranges, num_ranges);
   1557   if (!print_output)
   1558     return false;
   1559 
   1560   bool ret = false;
   1561 
   1562   if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF)
   1563     ret = PrintPDFOutput(print_output, canvas);
   1564 
   1565   // Now we need to release the print output resource.
   1566   PluginModule::GetCore()->ReleaseResource(print_output);
   1567 
   1568   return ret;
   1569 }
   1570 
   1571 void PepperPluginInstanceImpl::PrintEnd() {
   1572   // Keep a reference on the stack. See NOTE above.
   1573   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1574   if (!ranges_.empty())
   1575     PrintPageHelper(&(ranges_.front()), ranges_.size(), canvas_.get());
   1576   canvas_.clear();
   1577   ranges_.clear();
   1578 
   1579   DCHECK(plugin_print_interface_);
   1580   if (plugin_print_interface_)
   1581     plugin_print_interface_->End(pp_instance());
   1582 
   1583   memset(&current_print_settings_, 0, sizeof(current_print_settings_));
   1584 #if defined(OS_MACOSX)
   1585   last_printed_page_ = NULL;
   1586 #endif  // defined(OS_MACOSX)
   1587 }
   1588 
   1589 bool PepperPluginInstanceImpl::CanRotateView() {
   1590   if (!LoadPdfInterface())
   1591     return false;
   1592 
   1593   return true;
   1594 }
   1595 
   1596 void PepperPluginInstanceImpl::RotateView(WebPlugin::RotationType type) {
   1597   if (!LoadPdfInterface())
   1598     return;
   1599   PP_PrivatePageTransformType transform_type =
   1600       type == WebPlugin::RotationType90Clockwise ?
   1601       PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW :
   1602       PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW;
   1603   plugin_pdf_interface_->Transform(pp_instance(), transform_type);
   1604   // NOTE: plugin instance may have been deleted.
   1605 }
   1606 
   1607 bool PepperPluginInstanceImpl::FlashIsFullscreenOrPending() {
   1608   return fullscreen_container_ != NULL;
   1609 }
   1610 
   1611 bool PepperPluginInstanceImpl::IsFullscreenOrPending() {
   1612   return desired_fullscreen_state_;
   1613 }
   1614 
   1615 bool PepperPluginInstanceImpl::SetFullscreen(bool fullscreen) {
   1616   // Keep a reference on the stack. See NOTE above.
   1617   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   1618 
   1619   // Check whether we are trying to switch to the state we're already going
   1620   // to (i.e. if we're already switching to fullscreen but the fullscreen
   1621   // container isn't ready yet, don't do anything more).
   1622   if (fullscreen == IsFullscreenOrPending())
   1623     return false;
   1624 
   1625   // Check whether we are trying to switch while the state is in transition.
   1626   // The 2nd request gets dropped while messing up the internal state, so
   1627   // disallow this.
   1628   if (view_data_.is_fullscreen != desired_fullscreen_state_)
   1629     return false;
   1630 
   1631   if (fullscreen && !IsProcessingUserGesture())
   1632     return false;
   1633 
   1634   VLOG(1) << "Setting fullscreen to " << (fullscreen ? "on" : "off");
   1635   desired_fullscreen_state_ = fullscreen;
   1636 
   1637   if (fullscreen) {
   1638     // Create the user gesture in case we're processing one that's pending.
   1639     WebScopedUserGesture user_gesture(CurrentUserGestureToken());
   1640     // WebKit does not resize the plugin to fill the screen in fullscreen mode,
   1641     // so we will tweak plugin's attributes to support the expected behavior.
   1642     KeepSizeAttributesBeforeFullscreen();
   1643     SetSizeAttributesForFullscreen();
   1644     container_->element().requestFullScreen();
   1645   } else {
   1646     container_->element().document().cancelFullScreen();
   1647   }
   1648   return true;
   1649 }
   1650 
   1651 void PepperPluginInstanceImpl::UpdateFlashFullscreenState(
   1652     bool flash_fullscreen) {
   1653   bool is_mouselock_pending = TrackedCallback::IsPending(lock_mouse_callback_);
   1654 
   1655   if (flash_fullscreen == flash_fullscreen_) {
   1656     // Manually clear callback when fullscreen fails with mouselock pending.
   1657     if (!flash_fullscreen && is_mouselock_pending)
   1658       lock_mouse_callback_->Run(PP_ERROR_FAILED);
   1659     return;
   1660   }
   1661 
   1662   PPB_Graphics3D_Impl* graphics_3d  = bound_graphics_3d_.get();
   1663   if (graphics_3d)
   1664     UpdateLayer();
   1665 
   1666   bool old_plugin_focus = PluginHasFocus();
   1667   flash_fullscreen_ = flash_fullscreen;
   1668   if (is_mouselock_pending && !IsMouseLocked()) {
   1669     if (!IsProcessingUserGesture() &&
   1670         !module_->permissions().HasPermission(
   1671             ppapi::PERMISSION_BYPASS_USER_GESTURE)) {
   1672       lock_mouse_callback_->Run(PP_ERROR_NO_USER_GESTURE);
   1673     } else {
   1674       // Open a user gesture here so the Webkit user gesture checks will succeed
   1675       // for out-of-process plugins.
   1676       WebScopedUserGesture user_gesture(CurrentUserGestureToken());
   1677       if (!LockMouse())
   1678         lock_mouse_callback_->Run(PP_ERROR_FAILED);
   1679     }
   1680   }
   1681 
   1682   if (PluginHasFocus() != old_plugin_focus)
   1683     SendFocusChangeNotification();
   1684 }
   1685 
   1686 bool PepperPluginInstanceImpl::IsViewAccelerated() {
   1687   if (!container_)
   1688     return false;
   1689 
   1690   WebDocument document = container_->element().document();
   1691   WebFrame* frame = document.frame();
   1692   if (!frame)
   1693     return false;
   1694   WebView* view = frame->view();
   1695   if (!view)
   1696     return false;
   1697 
   1698   return view->isAcceleratedCompositingActive();
   1699 }
   1700 
   1701 bool PepperPluginInstanceImpl::PrintPDFOutput(PP_Resource print_output,
   1702                                               WebKit::WebCanvas* canvas) {
   1703 #if defined(ENABLE_FULL_PRINTING)
   1704   ppapi::thunk::EnterResourceNoLock<PPB_Buffer_API> enter(print_output, true);
   1705   if (enter.failed())
   1706     return false;
   1707 
   1708   BufferAutoMapper mapper(enter.object());
   1709   if (!mapper.data() || !mapper.size()) {
   1710     NOTREACHED();
   1711     return false;
   1712   }
   1713 #if defined(OS_WIN)
   1714   // For Windows, we need the PDF DLL to render the output PDF to a DC.
   1715   HMODULE pdf_module = GetModuleHandle(L"pdf.dll");
   1716   if (!pdf_module)
   1717     return false;
   1718   RenderPDFPageToDCProc render_proc =
   1719       reinterpret_cast<RenderPDFPageToDCProc>(
   1720           GetProcAddress(pdf_module, "RenderPDFPageToDC"));
   1721   if (!render_proc)
   1722     return false;
   1723 #endif  // defined(OS_WIN)
   1724 
   1725   bool ret = false;
   1726 #if defined(OS_LINUX) || defined(OS_MACOSX)
   1727   // On Linux we just set the final bits in the native metafile
   1728   // (NativeMetafile and PreviewMetafile must have compatible formats,
   1729   // i.e. both PDF for this to work).
   1730   printing::Metafile* metafile =
   1731       printing::MetafileSkiaWrapper::GetMetafileFromCanvas(*canvas);
   1732   DCHECK(metafile != NULL);
   1733   if (metafile)
   1734     ret = metafile->InitFromData(mapper.data(), mapper.size());
   1735 #elif defined(OS_WIN)
   1736   printing::Metafile* metafile =
   1737     printing::MetafileSkiaWrapper::GetMetafileFromCanvas(*canvas);
   1738   if (metafile) {
   1739     // We only have a metafile when doing print preview, so we just want to
   1740     // pass the PDF off to preview.
   1741     ret = metafile->InitFromData(mapper.data(), mapper.size());
   1742   } else {
   1743     // On Windows, we now need to render the PDF to the DC that backs the
   1744     // supplied canvas.
   1745     HDC dc = skia::BeginPlatformPaint(canvas);
   1746     DrawEmptyRectangle(dc);
   1747     gfx::Size size_in_pixels;
   1748     size_in_pixels.set_width(printing::ConvertUnit(
   1749         current_print_settings_.printable_area.size.width,
   1750         static_cast<int>(printing::kPointsPerInch),
   1751         current_print_settings_.dpi));
   1752     size_in_pixels.set_height(printing::ConvertUnit(
   1753         current_print_settings_.printable_area.size.height,
   1754         static_cast<int>(printing::kPointsPerInch),
   1755         current_print_settings_.dpi));
   1756     // We need to scale down DC to fit an entire page into DC available area.
   1757     // First, we'll try to use default scaling based on the 72dpi that is
   1758     // used in webkit for printing.
   1759     // If default scaling is not enough to fit the entire PDF without
   1760     // Current metafile is based on screen DC and have current screen size.
   1761     // Writing outside of those boundaries will result in the cut-off output.
   1762     // On metafiles (this is the case here), scaling down will still record
   1763     // original coordinates and we'll be able to print in full resolution.
   1764     // Before playback we'll need to counter the scaling up that will happen
   1765     // in the browser (printed_document_win.cc).
   1766     double dynamic_scale = gfx::CalculatePageScale(dc, size_in_pixels.width(),
   1767                                                    size_in_pixels.height());
   1768     double page_scale = static_cast<double>(printing::kPointsPerInch) /
   1769         static_cast<double>(current_print_settings_.dpi);
   1770 
   1771     if (dynamic_scale < page_scale) {
   1772       page_scale = dynamic_scale;
   1773       printing::MetafileSkiaWrapper::SetCustomScaleOnCanvas(*canvas,
   1774                                                             page_scale);
   1775     }
   1776 
   1777     gfx::ScaleDC(dc, page_scale);
   1778 
   1779     ret = render_proc(static_cast<unsigned char*>(mapper.data()), mapper.size(),
   1780                       0, dc, current_print_settings_.dpi,
   1781                       current_print_settings_.dpi, 0, 0, size_in_pixels.width(),
   1782                       size_in_pixels.height(), true, false, true, true, true);
   1783     skia::EndPlatformPaint(canvas);
   1784   }
   1785 #endif  // defined(OS_WIN)
   1786 
   1787   return ret;
   1788 #else  // defined(ENABLE_FULL_PRINTING)
   1789   return false;
   1790 #endif
   1791 }
   1792 
   1793 static void IgnoreCallback(unsigned, bool) {}
   1794 
   1795 void PepperPluginInstanceImpl::UpdateLayer() {
   1796   if (!container_)
   1797     return;
   1798 
   1799   gpu::Mailbox mailbox;
   1800   if (bound_graphics_3d_.get()) {
   1801     PlatformContext3D* context = bound_graphics_3d_->platform_context();
   1802     context->GetBackingMailbox(&mailbox);
   1803   }
   1804   bool want_layer = !mailbox.IsZero();
   1805 
   1806   if (want_layer == !!texture_layer_.get() &&
   1807       layer_bound_to_fullscreen_ == !!fullscreen_container_)
   1808     return;
   1809 
   1810   if (texture_layer_.get()) {
   1811     if (!layer_bound_to_fullscreen_)
   1812       container_->setWebLayer(NULL);
   1813     else if (fullscreen_container_)
   1814       fullscreen_container_->SetLayer(NULL);
   1815     web_layer_.reset();
   1816     texture_layer_ = NULL;
   1817   }
   1818   if (want_layer) {
   1819     DCHECK(bound_graphics_3d_.get());
   1820     texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL);
   1821     web_layer_.reset(new webkit::WebLayerImpl(texture_layer_));
   1822     if (fullscreen_container_) {
   1823       fullscreen_container_->SetLayer(web_layer_.get());
   1824       // Ignore transparency in fullscreen, since that's what Flash always
   1825       // wants to do, and that lets it not recreate a context if
   1826       // wmode=transparent was specified.
   1827       texture_layer_->SetContentsOpaque(true);
   1828     } else {
   1829       container_->setWebLayer(web_layer_.get());
   1830       texture_layer_->SetContentsOpaque(bound_graphics_3d_->IsOpaque());
   1831     }
   1832     texture_layer_->SetTextureMailbox(
   1833         cc::TextureMailbox(mailbox, base::Bind(&IgnoreCallback), 0));
   1834   }
   1835   layer_bound_to_fullscreen_ = !!fullscreen_container_;
   1836 }
   1837 
   1838 void PepperPluginInstanceImpl::AddPluginObject(PluginObject* plugin_object) {
   1839   DCHECK(live_plugin_objects_.find(plugin_object) ==
   1840          live_plugin_objects_.end());
   1841   live_plugin_objects_.insert(plugin_object);
   1842 }
   1843 
   1844 void PepperPluginInstanceImpl::RemovePluginObject(PluginObject* plugin_object) {
   1845   // Don't actually verify that the object is in the set since during module
   1846   // deletion we'll be in the process of freeing them.
   1847   live_plugin_objects_.erase(plugin_object);
   1848 }
   1849 
   1850 bool PepperPluginInstanceImpl::IsProcessingUserGesture() {
   1851   PP_TimeTicks now = ppapi::TimeTicksToPPTimeTicks(base::TimeTicks::Now());
   1852   // Give a lot of slack so tests won't be flaky.
   1853   const PP_TimeTicks kUserGestureDurationInSeconds = 10.0;
   1854   return pending_user_gesture_token_.hasGestures() &&
   1855          (now - pending_user_gesture_ < kUserGestureDurationInSeconds);
   1856 }
   1857 
   1858 WebUserGestureToken PepperPluginInstanceImpl::CurrentUserGestureToken() {
   1859   if (!IsProcessingUserGesture())
   1860     pending_user_gesture_token_ = WebUserGestureToken();
   1861   return pending_user_gesture_token_;
   1862 }
   1863 
   1864 void PepperPluginInstanceImpl::OnLockMouseACK(bool succeeded) {
   1865   if (TrackedCallback::IsPending(lock_mouse_callback_))
   1866     lock_mouse_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED);
   1867 }
   1868 
   1869 void PepperPluginInstanceImpl::OnMouseLockLost() {
   1870   if (LoadMouseLockInterface())
   1871     plugin_mouse_lock_interface_->MouseLockLost(pp_instance());
   1872 }
   1873 
   1874 void PepperPluginInstanceImpl::HandleMouseLockedInputEvent(
   1875     const WebKit::WebMouseEvent& event) {
   1876   // |cursor_info| is ignored since it is hidden when the mouse is locked.
   1877   WebKit::WebCursorInfo cursor_info;
   1878   HandleInputEvent(event, &cursor_info);
   1879 }
   1880 
   1881 void PepperPluginInstanceImpl::SimulateInputEvent(
   1882     const InputEventData& input_event) {
   1883   WebView* web_view = container()->element().document().frame()->view();
   1884   if (!web_view) {
   1885     NOTREACHED();
   1886     return;
   1887   }
   1888 
   1889   bool handled = SimulateIMEEvent(input_event);
   1890   if (handled)
   1891     return;
   1892 
   1893   std::vector<linked_ptr<WebInputEvent> > events =
   1894       CreateSimulatedWebInputEvents(
   1895           input_event,
   1896           view_data_.rect.point.x + view_data_.rect.size.width / 2,
   1897           view_data_.rect.point.y + view_data_.rect.size.height / 2);
   1898   for (std::vector<linked_ptr<WebInputEvent> >::iterator it = events.begin();
   1899       it != events.end(); ++it) {
   1900     web_view->handleInputEvent(*it->get());
   1901   }
   1902 }
   1903 
   1904 bool PepperPluginInstanceImpl::SimulateIMEEvent(
   1905     const InputEventData& input_event) {
   1906   switch (input_event.event_type) {
   1907     case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
   1908     case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
   1909       SimulateImeSetCompositionEvent(input_event);
   1910       break;
   1911     case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
   1912       DCHECK(input_event.character_text.empty());
   1913       SimulateImeSetCompositionEvent(input_event);
   1914       break;
   1915     case PP_INPUTEVENT_TYPE_IME_TEXT:
   1916       render_view_->SimulateImeConfirmComposition(
   1917           UTF8ToUTF16(input_event.character_text), ui::Range());
   1918       break;
   1919     default:
   1920       return false;
   1921   }
   1922   return true;
   1923 }
   1924 
   1925 void PepperPluginInstanceImpl::SimulateImeSetCompositionEvent(
   1926     const InputEventData& input_event) {
   1927   std::vector<size_t> offsets;
   1928   offsets.push_back(input_event.composition_selection_start);
   1929   offsets.push_back(input_event.composition_selection_end);
   1930   offsets.insert(offsets.end(),
   1931                  input_event.composition_segment_offsets.begin(),
   1932                  input_event.composition_segment_offsets.end());
   1933 
   1934   base::string16 utf16_text =
   1935       base::UTF8ToUTF16AndAdjustOffsets(input_event.character_text, &offsets);
   1936 
   1937   std::vector<WebKit::WebCompositionUnderline> underlines;
   1938   for (size_t i = 2; i + 1 < offsets.size(); ++i) {
   1939     WebKit::WebCompositionUnderline underline;
   1940     underline.startOffset = offsets[i];
   1941     underline.endOffset = offsets[i + 1];
   1942     if (input_event.composition_target_segment == static_cast<int32_t>(i - 2))
   1943       underline.thick = true;
   1944     underlines.push_back(underline);
   1945   }
   1946 
   1947   render_view_->SimulateImeSetComposition(
   1948       utf16_text, underlines, offsets[0], offsets[1]);
   1949 }
   1950 
   1951 ContentDecryptorDelegate*
   1952     PepperPluginInstanceImpl::GetContentDecryptorDelegate() {
   1953   if (content_decryptor_delegate_)
   1954     return content_decryptor_delegate_.get();
   1955 
   1956   const PPP_ContentDecryptor_Private* plugin_decryption_interface =
   1957       static_cast<const PPP_ContentDecryptor_Private*>(
   1958           module_->GetPluginInterface(
   1959               PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE));
   1960   if (!plugin_decryption_interface)
   1961     return NULL;
   1962 
   1963   content_decryptor_delegate_.reset(
   1964       new ContentDecryptorDelegate(pp_instance_, plugin_decryption_interface));
   1965   return content_decryptor_delegate_.get();
   1966 }
   1967 
   1968 PP_Bool PepperPluginInstanceImpl::BindGraphics(PP_Instance instance,
   1969                                                PP_Resource device) {
   1970   TRACE_EVENT0("ppapi", "PepperPluginInstanceImpl::BindGraphics");
   1971   // The Graphics3D instance can't be destroyed until we call
   1972   // UpdateLayer().
   1973   scoped_refptr<ppapi::Resource> old_graphics = bound_graphics_3d_.get();
   1974   if (bound_graphics_3d_.get()) {
   1975     bound_graphics_3d_->BindToInstance(false);
   1976     bound_graphics_3d_ = NULL;
   1977   }
   1978   if (bound_graphics_2d_platform_) {
   1979     bound_graphics_2d_platform_->BindToInstance(NULL);
   1980     bound_graphics_2d_platform_ = NULL;
   1981   }
   1982 
   1983   // Special-case clearing the current device.
   1984   if (!device) {
   1985     UpdateLayer();
   1986     InvalidateRect(gfx::Rect());
   1987     return PP_TRUE;
   1988   }
   1989 
   1990   // Refuse to bind if in transition to fullscreen with PPB_FlashFullscreen or
   1991   // to/from fullscreen with PPB_Fullscreen.
   1992   if ((fullscreen_container_ && !flash_fullscreen_) ||
   1993       desired_fullscreen_state_ != view_data_.is_fullscreen)
   1994     return PP_FALSE;
   1995 
   1996   const ppapi::host::PpapiHost* ppapi_host =
   1997       RendererPpapiHost::GetForPPInstance(instance)->GetPpapiHost();
   1998   ppapi::host::ResourceHost* host = ppapi_host->GetResourceHost(device);
   1999   PepperGraphics2DHost* graphics_2d = NULL;
   2000   if (host) {
   2001     if (host->IsGraphics2DHost())
   2002       graphics_2d = static_cast<PepperGraphics2DHost*>(host);
   2003     DLOG_IF(ERROR, !graphics_2d) << "Resource is not PepperGraphics2DHost.";
   2004   }
   2005 
   2006   EnterResourceNoLock<PPB_Graphics3D_API> enter_3d(device, false);
   2007   PPB_Graphics3D_Impl* graphics_3d = enter_3d.succeeded() ?
   2008       static_cast<PPB_Graphics3D_Impl*>(enter_3d.object()) : NULL;
   2009 
   2010   if (graphics_2d) {
   2011     if (graphics_2d->BindToInstance(this)) {
   2012       bound_graphics_2d_platform_ = graphics_2d;
   2013       UpdateLayer();
   2014       return PP_TRUE;
   2015     }
   2016   } else if (graphics_3d) {
   2017     // Make sure graphics can only be bound to the instance it is
   2018     // associated with.
   2019     if (graphics_3d->pp_instance() == pp_instance() &&
   2020         graphics_3d->BindToInstance(true)) {
   2021       bound_graphics_3d_ = graphics_3d;
   2022       UpdateLayer();
   2023       return PP_TRUE;
   2024     }
   2025   }
   2026 
   2027   // The instance cannot be bound or the device is not a valid resource type.
   2028   return PP_FALSE;
   2029 }
   2030 
   2031 PP_Bool PepperPluginInstanceImpl::IsFullFrame(PP_Instance instance) {
   2032   return PP_FromBool(full_frame());
   2033 }
   2034 
   2035 const ViewData* PepperPluginInstanceImpl::GetViewData(PP_Instance instance) {
   2036   return &view_data_;
   2037 }
   2038 
   2039 PP_Bool PepperPluginInstanceImpl::FlashIsFullscreen(PP_Instance instance) {
   2040   return PP_FromBool(flash_fullscreen_);
   2041 }
   2042 
   2043 PP_Var PepperPluginInstanceImpl::GetWindowObject(PP_Instance instance) {
   2044   if (!container_)
   2045     return PP_MakeUndefined();
   2046 
   2047   WebFrame* frame = container_->element().document().frame();
   2048   if (!frame)
   2049     return PP_MakeUndefined();
   2050 
   2051   return NPObjectToPPVar(this, frame->windowObject());
   2052 }
   2053 
   2054 PP_Var PepperPluginInstanceImpl::GetOwnerElementObject(PP_Instance instance) {
   2055   if (!container_)
   2056     return PP_MakeUndefined();
   2057   return NPObjectToPPVar(this, container_->scriptableObjectForElement());
   2058 }
   2059 
   2060 PP_Var PepperPluginInstanceImpl::ExecuteScript(PP_Instance instance,
   2061                                                PP_Var script,
   2062                                                PP_Var* exception) {
   2063   // Executing the script may remove the plugin from the DOM, so we need to keep
   2064   // a reference to ourselves so that we can still process the result after the
   2065   // WebBindings::evaluate() below.
   2066   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   2067   TryCatch try_catch(exception);
   2068   if (try_catch.has_exception())
   2069     return PP_MakeUndefined();
   2070 
   2071   // Convert the script into an inconvenient NPString object.
   2072   StringVar* script_string = StringVar::FromPPVar(script);
   2073   if (!script_string) {
   2074     try_catch.SetException("Script param to ExecuteScript must be a string.");
   2075     return PP_MakeUndefined();
   2076   }
   2077   NPString np_script;
   2078   np_script.UTF8Characters = script_string->value().c_str();
   2079   np_script.UTF8Length = script_string->value().length();
   2080 
   2081   // Get the current frame to pass to the evaluate function.
   2082   WebFrame* frame = container_->element().document().frame();
   2083   if (!frame) {
   2084     try_catch.SetException("No frame to execute script in.");
   2085     return PP_MakeUndefined();
   2086   }
   2087 
   2088   NPVariant result;
   2089   bool ok = false;
   2090   if (IsProcessingUserGesture()) {
   2091     WebKit::WebScopedUserGesture user_gesture(CurrentUserGestureToken());
   2092     ok = WebBindings::evaluate(NULL, frame->windowObject(), &np_script,
   2093                                &result);
   2094   } else {
   2095     ok = WebBindings::evaluate(NULL, frame->windowObject(), &np_script,
   2096                                &result);
   2097   }
   2098   if (!ok) {
   2099     // TryCatch doesn't catch the exceptions properly. Since this is only for
   2100     // a trusted API, just set to a general exception message.
   2101     try_catch.SetException("Exception caught");
   2102     WebBindings::releaseVariantValue(&result);
   2103     return PP_MakeUndefined();
   2104   }
   2105 
   2106   PP_Var ret = NPVariantToPPVar(this, &result);
   2107   WebBindings::releaseVariantValue(&result);
   2108   return ret;
   2109 }
   2110 
   2111 uint32_t PepperPluginInstanceImpl::GetAudioHardwareOutputSampleRate(
   2112     PP_Instance instance) {
   2113   RenderThreadImpl* thread = RenderThreadImpl::current();
   2114   return thread->GetAudioHardwareConfig()->GetOutputSampleRate();
   2115 }
   2116 
   2117 uint32_t PepperPluginInstanceImpl::GetAudioHardwareOutputBufferSize(
   2118     PP_Instance instance) {
   2119   RenderThreadImpl* thread = RenderThreadImpl::current();
   2120   return thread->GetAudioHardwareConfig()->GetOutputBufferSize();
   2121 }
   2122 
   2123 PP_Var PepperPluginInstanceImpl::GetDefaultCharSet(PP_Instance instance) {
   2124   return StringVar::StringToPPVar(
   2125       render_view_->webkit_preferences().default_encoding);
   2126 }
   2127 
   2128 // These PPB_ContentDecryptor_Private calls are responses to
   2129 // PPP_ContentDecryptor_Private calls made on |content_decryptor_delegate_|.
   2130 // Therefore, |content_decryptor_delegate_| must have been initialized when
   2131 // the following methods are called.
   2132 void PepperPluginInstanceImpl::NeedKey(PP_Instance instance,
   2133                                        PP_Var key_system_var,
   2134                                        PP_Var session_id_var,
   2135                                        PP_Var init_data_var) {
   2136   content_decryptor_delegate_->NeedKey(
   2137       key_system_var, session_id_var, init_data_var);
   2138 }
   2139 
   2140 void PepperPluginInstanceImpl::KeyAdded(PP_Instance instance,
   2141                                         PP_Var key_system_var,
   2142                                         PP_Var session_id_var) {
   2143   content_decryptor_delegate_->KeyAdded(key_system_var, session_id_var);
   2144 }
   2145 
   2146 void PepperPluginInstanceImpl::KeyMessage(PP_Instance instance,
   2147                                           PP_Var key_system_var,
   2148                                           PP_Var session_id_var,
   2149                                           PP_Var message_var,
   2150                                           PP_Var default_url_var) {
   2151   content_decryptor_delegate_->KeyMessage(
   2152       key_system_var, session_id_var, message_var, default_url_var);
   2153 }
   2154 
   2155 void PepperPluginInstanceImpl::KeyError(PP_Instance instance,
   2156                                         PP_Var key_system_var,
   2157                                         PP_Var session_id_var,
   2158                                         int32_t media_error,
   2159                                         int32_t system_code) {
   2160   content_decryptor_delegate_->KeyError(
   2161       key_system_var, session_id_var, media_error, system_code);
   2162 }
   2163 
   2164 void PepperPluginInstanceImpl::DeliverBlock(
   2165     PP_Instance instance,
   2166     PP_Resource decrypted_block,
   2167     const PP_DecryptedBlockInfo* block_info) {
   2168   content_decryptor_delegate_->DeliverBlock(decrypted_block, block_info);
   2169 }
   2170 
   2171 void PepperPluginInstanceImpl::DecoderInitializeDone(
   2172     PP_Instance instance,
   2173     PP_DecryptorStreamType decoder_type,
   2174     uint32_t request_id,
   2175     PP_Bool success) {
   2176   content_decryptor_delegate_->DecoderInitializeDone(
   2177       decoder_type, request_id, success);
   2178 }
   2179 
   2180 void PepperPluginInstanceImpl::DecoderDeinitializeDone(
   2181     PP_Instance instance,
   2182     PP_DecryptorStreamType decoder_type,
   2183     uint32_t request_id) {
   2184   content_decryptor_delegate_->DecoderDeinitializeDone(decoder_type,
   2185                                                        request_id);
   2186 }
   2187 
   2188 void PepperPluginInstanceImpl::DecoderResetDone(
   2189     PP_Instance instance,
   2190     PP_DecryptorStreamType decoder_type,
   2191     uint32_t request_id) {
   2192   content_decryptor_delegate_->DecoderResetDone(decoder_type, request_id);
   2193 }
   2194 
   2195 
   2196 void PepperPluginInstanceImpl::DeliverFrame(
   2197     PP_Instance instance,
   2198     PP_Resource decrypted_frame,
   2199     const PP_DecryptedFrameInfo* frame_info) {
   2200   content_decryptor_delegate_->DeliverFrame(decrypted_frame, frame_info);
   2201 }
   2202 
   2203 void PepperPluginInstanceImpl::DeliverSamples(
   2204     PP_Instance instance,
   2205     PP_Resource audio_frames,
   2206     const PP_DecryptedBlockInfo* block_info) {
   2207   content_decryptor_delegate_->DeliverSamples(audio_frames, block_info);
   2208 }
   2209 
   2210 void PepperPluginInstanceImpl::NumberOfFindResultsChanged(
   2211     PP_Instance instance,
   2212     int32_t total,
   2213     PP_Bool final_result) {
   2214   DCHECK_NE(find_identifier_, -1);
   2215   render_view_->reportFindInPageMatchCount(
   2216       find_identifier_, total, PP_ToBool(final_result));
   2217 }
   2218 
   2219 void PepperPluginInstanceImpl::SelectedFindResultChanged(PP_Instance instance,
   2220                                                          int32_t index) {
   2221   DCHECK_NE(find_identifier_, -1);
   2222   render_view_->reportFindInPageSelection(
   2223       find_identifier_, index + 1, WebKit::WebRect());
   2224 }
   2225 
   2226 PP_Bool PepperPluginInstanceImpl::IsFullscreen(PP_Instance instance) {
   2227   return PP_FromBool(view_data_.is_fullscreen);
   2228 }
   2229 
   2230 PP_Bool PepperPluginInstanceImpl::SetFullscreen(PP_Instance instance,
   2231                                                 PP_Bool fullscreen) {
   2232   return PP_FromBool(SetFullscreen(PP_ToBool(fullscreen)));
   2233 }
   2234 
   2235 PP_Bool PepperPluginInstanceImpl::GetScreenSize(PP_Instance instance,
   2236                                                 PP_Size* size) {
   2237   WebKit::WebScreenInfo info = render_view_->screenInfo();
   2238   *size = PP_MakeSize(info.rect.width, info.rect.height);
   2239   return PP_TRUE;
   2240 }
   2241 
   2242 ppapi::Resource* PepperPluginInstanceImpl::GetSingletonResource(
   2243     PP_Instance instance,
   2244     ppapi::SingletonResourceID id) {
   2245   // Flash APIs and some others aren't implemented in-process.
   2246   switch (id) {
   2247     case ppapi::BROKER_SINGLETON_ID:
   2248     case ppapi::BROWSER_FONT_SINGLETON_ID:
   2249     case ppapi::CRX_FILESYSTEM_SINGLETON_ID:
   2250     case ppapi::EXTENSIONS_COMMON_SINGLETON_ID:
   2251     case ppapi::FLASH_CLIPBOARD_SINGLETON_ID:
   2252     case ppapi::FLASH_FILE_SINGLETON_ID:
   2253     case ppapi::FLASH_FULLSCREEN_SINGLETON_ID:
   2254     case ppapi::FLASH_SINGLETON_ID:
   2255     case ppapi::NETWORK_PROXY_SINGLETON_ID:
   2256     case ppapi::PDF_SINGLETON_ID:
   2257     case ppapi::TRUETYPE_FONT_SINGLETON_ID:
   2258       NOTIMPLEMENTED();
   2259       return NULL;
   2260     case ppapi::GAMEPAD_SINGLETON_ID:
   2261       return gamepad_impl_.get();
   2262   }
   2263 
   2264   NOTREACHED();
   2265   return NULL;
   2266 }
   2267 
   2268 int32_t PepperPluginInstanceImpl::RequestInputEvents(PP_Instance instance,
   2269                                                      uint32_t event_classes) {
   2270   input_event_mask_ |= event_classes;
   2271   filtered_input_event_mask_ &= ~(event_classes);
   2272   RequestInputEventsHelper(event_classes);
   2273   return ValidateRequestInputEvents(false, event_classes);
   2274 }
   2275 
   2276 int32_t PepperPluginInstanceImpl::RequestFilteringInputEvents(
   2277     PP_Instance instance,
   2278     uint32_t event_classes) {
   2279   filtered_input_event_mask_ |= event_classes;
   2280   input_event_mask_ &= ~(event_classes);
   2281   RequestInputEventsHelper(event_classes);
   2282   return ValidateRequestInputEvents(true, event_classes);
   2283 }
   2284 
   2285 void PepperPluginInstanceImpl::ClearInputEventRequest(PP_Instance instance,
   2286                                                       uint32_t event_classes) {
   2287   input_event_mask_ &= ~(event_classes);
   2288   filtered_input_event_mask_ &= ~(event_classes);
   2289   RequestInputEventsHelper(event_classes);
   2290 }
   2291 
   2292 void PepperPluginInstanceImpl::ZoomChanged(PP_Instance instance,
   2293                                            double factor) {
   2294   // We only want to tell the page to change its zoom if the whole page is the
   2295   // plugin.  If we're in an iframe, then don't do anything.
   2296   if (!IsFullPagePlugin())
   2297     return;
   2298   container()->zoomLevelChanged(content::ZoomFactorToZoomLevel(factor));
   2299 }
   2300 
   2301 void PepperPluginInstanceImpl::ZoomLimitsChanged(PP_Instance instance,
   2302                                                  double minimum_factor,
   2303                                                  double maximum_factor) {
   2304   if (minimum_factor > maximum_factor) {
   2305     NOTREACHED();
   2306     return;
   2307   }
   2308   double minimum_level = ZoomFactorToZoomLevel(minimum_factor);
   2309   double maximum_level = ZoomFactorToZoomLevel(maximum_factor);
   2310   render_view_->webview()->zoomLimitsChanged(minimum_level, maximum_level);
   2311 }
   2312 
   2313 void PepperPluginInstanceImpl::PostMessage(PP_Instance instance,
   2314                                            PP_Var message) {
   2315   message_channel_->PostMessageToJavaScript(message);
   2316 }
   2317 
   2318 PP_Bool PepperPluginInstanceImpl::SetCursor(PP_Instance instance,
   2319                                             PP_MouseCursor_Type type,
   2320                                             PP_Resource image,
   2321                                             const PP_Point* hot_spot) {
   2322   if (!ValidateSetCursorParams(type, image, hot_spot))
   2323     return PP_FALSE;
   2324 
   2325   if (type != PP_MOUSECURSOR_TYPE_CUSTOM) {
   2326     DoSetCursor(new WebCursorInfo(static_cast<WebCursorInfo::Type>(type)));
   2327     return PP_TRUE;
   2328   }
   2329 
   2330   EnterResourceNoLock<PPB_ImageData_API> enter(image, true);
   2331   if (enter.failed())
   2332     return PP_FALSE;
   2333   PPB_ImageData_Impl* image_data =
   2334       static_cast<PPB_ImageData_Impl*>(enter.object());
   2335 
   2336   ImageDataAutoMapper auto_mapper(image_data);
   2337   if (!auto_mapper.is_valid())
   2338     return PP_FALSE;
   2339 
   2340   scoped_ptr<WebCursorInfo> custom_cursor(
   2341       new WebCursorInfo(WebCursorInfo::TypeCustom));
   2342   custom_cursor->hotSpot.x = hot_spot->x;
   2343   custom_cursor->hotSpot.y = hot_spot->y;
   2344 
   2345   const SkBitmap* bitmap = image_data->GetMappedBitmap();
   2346   // Make a deep copy, so that the cursor remains valid even after the original
   2347   // image data gets freed.
   2348   if (!bitmap->copyTo(&custom_cursor->customImage.getSkBitmap(),
   2349                       bitmap->config())) {
   2350     return PP_FALSE;
   2351   }
   2352 
   2353   DoSetCursor(custom_cursor.release());
   2354   return PP_TRUE;
   2355 }
   2356 
   2357 int32_t PepperPluginInstanceImpl::LockMouse(
   2358     PP_Instance instance,
   2359     scoped_refptr<TrackedCallback> callback) {
   2360   if (TrackedCallback::IsPending(lock_mouse_callback_))
   2361     return PP_ERROR_INPROGRESS;
   2362 
   2363   if (IsMouseLocked())
   2364     return PP_OK;
   2365 
   2366   if (!CanAccessMainFrame())
   2367     return PP_ERROR_NOACCESS;
   2368 
   2369   if (!IsProcessingUserGesture())
   2370     return PP_ERROR_NO_USER_GESTURE;
   2371 
   2372   // Attempt mouselock only if Flash isn't waiting on fullscreen, otherwise
   2373   // we wait and call LockMouse() in UpdateFlashFullscreenState().
   2374   if (!FlashIsFullscreenOrPending() || flash_fullscreen_) {
   2375     // Open a user gesture here so the Webkit user gesture checks will succeed
   2376     // for out-of-process plugins.
   2377     WebScopedUserGesture user_gesture(CurrentUserGestureToken());
   2378     if (!LockMouse())
   2379       return PP_ERROR_FAILED;
   2380   }
   2381 
   2382   // Either mouselock succeeded or a Flash fullscreen is pending.
   2383   lock_mouse_callback_ = callback;
   2384   return PP_OK_COMPLETIONPENDING;
   2385 }
   2386 
   2387 void PepperPluginInstanceImpl::UnlockMouse(PP_Instance instance) {
   2388   GetMouseLockDispatcher()->UnlockMouse(GetOrCreateLockTargetAdapter());
   2389 }
   2390 
   2391 void PepperPluginInstanceImpl::SetTextInputType(PP_Instance instance,
   2392                                                 PP_TextInput_Type type) {
   2393   int itype = type;
   2394   if (itype < 0 || itype > ui::TEXT_INPUT_TYPE_URL)
   2395     itype = ui::TEXT_INPUT_TYPE_NONE;
   2396   text_input_type_ = static_cast<ui::TextInputType>(itype);
   2397   render_view_->PepperTextInputTypeChanged(this);
   2398 }
   2399 
   2400 void PepperPluginInstanceImpl::UpdateCaretPosition(
   2401     PP_Instance instance,
   2402     const PP_Rect& caret,
   2403     const PP_Rect& bounding_box) {
   2404   text_input_caret_ = PP_ToGfxRect(caret);
   2405   text_input_caret_bounds_ = PP_ToGfxRect(bounding_box);
   2406   text_input_caret_set_ = true;
   2407   render_view_->PepperCaretPositionChanged(this);
   2408 }
   2409 
   2410 void PepperPluginInstanceImpl::CancelCompositionText(PP_Instance instance) {
   2411   render_view_->PepperCancelComposition(this);
   2412 }
   2413 
   2414 void PepperPluginInstanceImpl::SelectionChanged(PP_Instance instance) {
   2415   // TODO(kinaba): currently the browser always calls RequestSurroundingText.
   2416   // It can be optimized so that it won't call it back until the information
   2417   // is really needed.
   2418 
   2419   // Avoid calling in nested context or else this will reenter the plugin. This
   2420   // uses a weak pointer rather than exploiting the fact that this class is
   2421   // refcounted because we don't actually want this operation to affect the
   2422   // lifetime of the instance.
   2423   base::MessageLoop::current()->PostTask(
   2424       FROM_HERE,
   2425       base::Bind(&PepperPluginInstanceImpl::RequestSurroundingText,
   2426                  AsWeakPtr(),
   2427                  static_cast<size_t>(kExtraCharsForTextInput)));
   2428 }
   2429 
   2430 void PepperPluginInstanceImpl::UpdateSurroundingText(PP_Instance instance,
   2431                                                      const char* text,
   2432                                                      uint32_t caret,
   2433                                                      uint32_t anchor) {
   2434   surrounding_text_ = text;
   2435   selection_caret_ = caret;
   2436   selection_anchor_ = anchor;
   2437   render_view_->PepperSelectionChanged(this);
   2438 }
   2439 
   2440 PP_Var PepperPluginInstanceImpl::ResolveRelativeToDocument(
   2441     PP_Instance instance,
   2442     PP_Var relative,
   2443     PP_URLComponents_Dev* components) {
   2444   StringVar* relative_string = StringVar::FromPPVar(relative);
   2445   if (!relative_string)
   2446     return PP_MakeNull();
   2447 
   2448   WebElement plugin_element = container()->element();
   2449   GURL document_url = plugin_element.document().baseURL();
   2450   return ppapi::PPB_URLUtil_Shared::GenerateURLReturn(
   2451       document_url.Resolve(relative_string->value()),
   2452       components);
   2453 }
   2454 
   2455 PP_Bool PepperPluginInstanceImpl::DocumentCanRequest(PP_Instance instance,
   2456                                                      PP_Var url) {
   2457   StringVar* url_string = StringVar::FromPPVar(url);
   2458   if (!url_string)
   2459     return PP_FALSE;
   2460 
   2461   WebKit::WebSecurityOrigin security_origin;
   2462   if (!SecurityOriginForInstance(instance, &security_origin))
   2463     return PP_FALSE;
   2464 
   2465   GURL gurl(url_string->value());
   2466   if (!gurl.is_valid())
   2467     return PP_FALSE;
   2468 
   2469   return BoolToPPBool(security_origin.canRequest(gurl));
   2470 }
   2471 
   2472 PP_Bool PepperPluginInstanceImpl::DocumentCanAccessDocument(
   2473     PP_Instance instance,
   2474     PP_Instance target) {
   2475   WebKit::WebSecurityOrigin our_origin;
   2476   if (!SecurityOriginForInstance(instance, &our_origin))
   2477     return PP_FALSE;
   2478 
   2479   WebKit::WebSecurityOrigin target_origin;
   2480   if (!SecurityOriginForInstance(instance, &target_origin))
   2481     return PP_FALSE;
   2482 
   2483   return BoolToPPBool(our_origin.canAccess(target_origin));
   2484 }
   2485 
   2486 PP_Var PepperPluginInstanceImpl::GetDocumentURL(
   2487     PP_Instance instance,
   2488     PP_URLComponents_Dev* components) {
   2489   WebKit::WebDocument document = container()->element().document();
   2490   return ppapi::PPB_URLUtil_Shared::GenerateURLReturn(document.url(),
   2491                                                       components);
   2492 }
   2493 
   2494 PP_Var PepperPluginInstanceImpl::GetPluginInstanceURL(
   2495     PP_Instance instance,
   2496     PP_URLComponents_Dev* components) {
   2497   return ppapi::PPB_URLUtil_Shared::GenerateURLReturn(plugin_url_,
   2498                                                       components);
   2499 }
   2500 
   2501 PP_ExternalPluginResult PepperPluginInstanceImpl::ResetAsProxied(
   2502     scoped_refptr<PluginModule> module) {
   2503   // Save the original module and switch over to the new one now that this
   2504   // plugin is using the IPC-based proxy.
   2505   original_module_ = module_;
   2506   module_ = module;
   2507 
   2508   // Don't send any messages to the plugin until DidCreate() has finished.
   2509   message_channel_->QueueJavaScriptMessages();
   2510 
   2511   // For NaCl instances, remember the NaCl plugin instance interface, so we
   2512   // can shut it down by calling its DidDestroy in our Delete() method.
   2513   original_instance_interface_.reset(instance_interface_.release());
   2514 
   2515   base::Callback<const void*(const char*)> get_plugin_interface_func =
   2516       base::Bind(&PluginModule::GetPluginInterface, module_.get());
   2517   PPP_Instance_Combined* ppp_instance_combined =
   2518       PPP_Instance_Combined::Create(get_plugin_interface_func);
   2519   if (!ppp_instance_combined) {
   2520     // The proxy must support at least one usable PPP_Instance interface.
   2521     // While this could be a failure to implement the interface in the NaCl
   2522     // module, it is more likely that the NaCl process has crashed. Either
   2523     // way, report that module initialization failed.
   2524     return PP_EXTERNAL_PLUGIN_ERROR_MODULE;
   2525   }
   2526 
   2527   instance_interface_.reset(ppp_instance_combined);
   2528   // Clear all PPP interfaces we may have cached.
   2529   plugin_find_interface_ = NULL;
   2530   plugin_input_event_interface_ = NULL;
   2531   checked_for_plugin_input_event_interface_ = false;
   2532   plugin_messaging_interface_ = NULL;
   2533   checked_for_plugin_messaging_interface_ = false;
   2534   plugin_mouse_lock_interface_ = NULL;
   2535   plugin_pdf_interface_ = NULL;
   2536   checked_for_plugin_pdf_interface_ = false;
   2537   plugin_private_interface_ = NULL;
   2538   plugin_selection_interface_ = NULL;
   2539   plugin_textinput_interface_ = NULL;
   2540   plugin_zoom_interface_ = NULL;
   2541 
   2542   // Re-send the DidCreate event via the proxy.
   2543   scoped_ptr<const char*[]> argn_array(StringVectorToArgArray(argn_));
   2544   scoped_ptr<const char*[]> argv_array(StringVectorToArgArray(argv_));
   2545   if (!instance_interface_->DidCreate(pp_instance(), argn_.size(),
   2546                                       argn_array.get(), argv_array.get()))
   2547     return PP_EXTERNAL_PLUGIN_ERROR_INSTANCE;
   2548   message_channel_->StopQueueingJavaScriptMessages();
   2549 
   2550   // Clear sent_initial_did_change_view_ and cancel any pending DidChangeView
   2551   // event. This way, SendDidChangeView will send the "current" view
   2552   // immediately (before other events like HandleDocumentLoad).
   2553   sent_initial_did_change_view_ = false;
   2554   view_change_weak_ptr_factory_.InvalidateWeakPtrs();
   2555   SendDidChangeView();
   2556 
   2557   DCHECK(external_document_load_);
   2558   external_document_load_ = false;
   2559   if (!external_document_response_.isNull()) {
   2560     document_loader_ = NULL;
   2561     // Pass the response to the new proxy.
   2562     HandleDocumentLoad(external_document_response_);
   2563     external_document_response_ = WebKit::WebURLResponse();
   2564     // Replay any document load events we've received to the real loader.
   2565     external_document_loader_->ReplayReceivedData(document_loader_);
   2566     external_document_loader_.reset(NULL);
   2567   }
   2568 
   2569   return PP_EXTERNAL_PLUGIN_OK;
   2570 }
   2571 
   2572 bool PepperPluginInstanceImpl::IsValidInstanceOf(PluginModule* module) {
   2573   DCHECK(module);
   2574   return module == module_.get() ||
   2575          module == original_module_.get();
   2576 }
   2577 
   2578 NPP PepperPluginInstanceImpl::instanceNPP() {
   2579   return npp_.get();
   2580 }
   2581 
   2582 v8::Isolate* PepperPluginInstanceImpl::GetIsolate() const {
   2583   return isolate_;
   2584 }
   2585 
   2586 PepperPluginInstance* PepperPluginInstance::Get(PP_Instance instance_id) {
   2587   return HostGlobals::Get()->GetInstance(instance_id);
   2588 }
   2589 
   2590 RenderView* PepperPluginInstanceImpl::GetRenderView() {
   2591   return render_view_;
   2592 }
   2593 
   2594 WebKit::WebPluginContainer* PepperPluginInstanceImpl::GetContainer() {
   2595   return container_;
   2596 }
   2597 
   2598 ppapi::VarTracker* PepperPluginInstanceImpl::GetVarTracker() {
   2599   return HostGlobals::Get()->GetVarTracker();
   2600 }
   2601 
   2602 const GURL& PepperPluginInstanceImpl::GetPluginURL() {
   2603   return plugin_url_;
   2604 }
   2605 
   2606 base::FilePath PepperPluginInstanceImpl::GetModulePath() {
   2607   return module_->path();
   2608 }
   2609 
   2610 PP_Resource PepperPluginInstanceImpl::CreateExternalFileReference(
   2611     const base::FilePath& external_file_path) {
   2612   PPB_FileRef_Impl* ref = PPB_FileRef_Impl::CreateExternal(
   2613       pp_instance(), external_file_path, "");
   2614   return ref->GetReference();
   2615 }
   2616 
   2617 PP_Resource PepperPluginInstanceImpl::CreateImage(gfx::ImageSkia* source_image,
   2618                                                   float scale) {
   2619   ui::ScaleFactor scale_factor = ui::GetScaleFactorFromScale(scale);
   2620   gfx::ImageSkiaRep image_skia_rep = source_image->GetRepresentation(
   2621       scale_factor);
   2622 
   2623   if (image_skia_rep.is_null() || image_skia_rep.scale_factor() != scale_factor)
   2624     return 0;
   2625 
   2626   scoped_refptr<PPB_ImageData_Impl> image_data(new PPB_ImageData_Impl(
   2627       pp_instance(),
   2628       PPB_ImageData_Impl::PLATFORM));
   2629   if (!image_data->Init(
   2630           PPB_ImageData_Impl::GetNativeImageDataFormat(),
   2631           image_skia_rep.pixel_width(),
   2632           image_skia_rep.pixel_height(),
   2633           false)) {
   2634     return 0;
   2635   }
   2636 
   2637   ImageDataAutoMapper mapper(image_data.get());
   2638   if (!mapper.is_valid())
   2639     return 0;
   2640 
   2641   skia::PlatformCanvas* canvas = image_data->GetPlatformCanvas();
   2642   // Note: Do not SkBitmap::copyTo the canvas bitmap directly because it will
   2643   // ignore the allocated pixels in shared memory and re-allocate a new buffer.
   2644   canvas->writePixels(image_skia_rep.sk_bitmap(), 0, 0);
   2645 
   2646   return image_data->GetReference();
   2647 }
   2648 
   2649 PP_ExternalPluginResult PepperPluginInstanceImpl::SwitchToOutOfProcessProxy(
   2650     const base::FilePath& file_path,
   2651     ppapi::PpapiPermissions permissions,
   2652     const IPC::ChannelHandle& channel_handle,
   2653     base::ProcessId plugin_pid,
   2654     int plugin_child_id) {
   2655   // Create a new module for each instance of the external plugin that is using
   2656   // the IPC based out-of-process proxy. We can't use the existing module,
   2657   // because it is configured for the in-process plugin, and we must keep it
   2658   // that way to allow the page to create other instances.
   2659   scoped_refptr<PluginModule> external_plugin_module(
   2660       module_->CreateModuleForExternalPluginInstance());
   2661 
   2662   RendererPpapiHostImpl* renderer_ppapi_host =
   2663       external_plugin_module->CreateOutOfProcessModule(
   2664           render_view_,
   2665           file_path,
   2666           permissions,
   2667           channel_handle,
   2668           plugin_pid,
   2669           plugin_child_id,
   2670           true);
   2671   if (!renderer_ppapi_host) {
   2672     DLOG(ERROR) << "CreateExternalPluginModule() failed";
   2673     return PP_EXTERNAL_PLUGIN_ERROR_MODULE;
   2674   }
   2675 
   2676   // Finally, switch the instance to the proxy.
   2677   return external_plugin_module->InitAsProxiedExternalPlugin(this);
   2678 }
   2679 
   2680 void PepperPluginInstanceImpl::SetAlwaysOnTop(bool on_top) {
   2681   always_on_top_ = on_top;
   2682 }
   2683 
   2684 void PepperPluginInstanceImpl::DoSetCursor(WebCursorInfo* cursor) {
   2685   cursor_.reset(cursor);
   2686   if (fullscreen_container_) {
   2687     fullscreen_container_->DidChangeCursor(*cursor);
   2688   } else {
   2689     render_view_->PepperDidChangeCursor(this, *cursor);
   2690   }
   2691 }
   2692 
   2693 bool PepperPluginInstanceImpl::IsFullPagePlugin() {
   2694   WebFrame* frame = container()->element().document().frame();
   2695   return frame->view()->mainFrame()->document().isPluginDocument();
   2696 }
   2697 
   2698 void PepperPluginInstanceImpl::FlashSetFullscreen(bool fullscreen,
   2699                                                   bool delay_report) {
   2700   TRACE_EVENT0("ppapi", "PepperPluginInstanceImpl::FlashSetFullscreen");
   2701   // Keep a reference on the stack. See NOTE above.
   2702   scoped_refptr<PepperPluginInstanceImpl> ref(this);
   2703 
   2704   // We check whether we are trying to switch to the state we're already going
   2705   // to (i.e. if we're already switching to fullscreen but the fullscreen
   2706   // container isn't ready yet, don't do anything more).
   2707   if (fullscreen == FlashIsFullscreenOrPending())
   2708     return;
   2709 
   2710   // Unbind current 2D or 3D graphics context.
   2711   VLOG(1) << "Setting fullscreen to " << (fullscreen ? "on" : "off");
   2712   if (fullscreen) {
   2713     DCHECK(!fullscreen_container_);
   2714     fullscreen_container_ = render_view_->CreatePepperFullscreenContainer(this);
   2715     UpdateLayer();
   2716   } else {
   2717     DCHECK(fullscreen_container_);
   2718     fullscreen_container_->Destroy();
   2719     fullscreen_container_ = NULL;
   2720     UpdateFlashFullscreenState(false);
   2721     if (!delay_report) {
   2722       ReportGeometry();
   2723     } else {
   2724       base::MessageLoop::current()->PostTask(
   2725           FROM_HERE,
   2726           base::Bind(&PepperPluginInstanceImpl::ReportGeometry, this));
   2727     }
   2728   }
   2729 }
   2730 
   2731 bool PepperPluginInstanceImpl::IsRectTopmost(const gfx::Rect& rect) {
   2732   if (flash_fullscreen_)
   2733     return true;
   2734 
   2735   return container_->isRectTopmost(rect);
   2736 }
   2737 
   2738 int32_t PepperPluginInstanceImpl::Navigate(
   2739     const ppapi::URLRequestInfoData& request,
   2740     const char* target,
   2741     bool from_user_action) {
   2742   if (!container_)
   2743     return PP_ERROR_FAILED;
   2744 
   2745   WebDocument document = container_->element().document();
   2746   WebFrame* frame = document.frame();
   2747   if (!frame)
   2748     return PP_ERROR_FAILED;
   2749 
   2750   ppapi::URLRequestInfoData completed_request = request;
   2751 
   2752   WebURLRequest web_request;
   2753   if (!CreateWebURLRequest(&completed_request, frame, &web_request))
   2754     return PP_ERROR_FAILED;
   2755   web_request.setFirstPartyForCookies(document.firstPartyForCookies());
   2756   web_request.setHasUserGesture(from_user_action);
   2757 
   2758   GURL gurl(web_request.url());
   2759   if (gurl.SchemeIs("javascript")) {
   2760     // In imitation of the NPAPI implementation, only |target_frame == frame| is
   2761     // allowed for security reasons.
   2762     WebFrame* target_frame =
   2763         frame->view()->findFrameByName(WebString::fromUTF8(target), frame);
   2764     if (target_frame != frame)
   2765       return PP_ERROR_NOACCESS;
   2766 
   2767     // TODO(viettrungluu): NPAPI sends the result back to the plugin -- do we
   2768     // need that?
   2769     WebString result = container_->executeScriptURL(gurl, from_user_action);
   2770     return result.isNull() ? PP_ERROR_FAILED : PP_OK;
   2771   }
   2772 
   2773   // Only GETs and POSTs are supported.
   2774   if (web_request.httpMethod() != "GET" &&
   2775       web_request.httpMethod() != "POST")
   2776     return PP_ERROR_BADARGUMENT;
   2777 
   2778   WebString target_str = WebString::fromUTF8(target);
   2779   container_->loadFrameRequest(web_request, target_str, false, NULL);
   2780   return PP_OK;
   2781 }
   2782 
   2783 bool PepperPluginInstanceImpl::CanAccessMainFrame() const {
   2784   if (!container_)
   2785     return false;
   2786   WebKit::WebDocument containing_document = container_->element().document();
   2787 
   2788   if (!containing_document.frame() ||
   2789       !containing_document.frame()->view() ||
   2790       !containing_document.frame()->view()->mainFrame()) {
   2791     return false;
   2792   }
   2793   WebKit::WebDocument main_document =
   2794       containing_document.frame()->view()->mainFrame()->document();
   2795 
   2796   return containing_document.securityOrigin().canAccess(
   2797       main_document.securityOrigin());
   2798 }
   2799 
   2800 void PepperPluginInstanceImpl::KeepSizeAttributesBeforeFullscreen() {
   2801   WebElement element = container_->element();
   2802   width_before_fullscreen_ = element.getAttribute(WebString::fromUTF8(kWidth));
   2803   height_before_fullscreen_ =
   2804       element.getAttribute(WebString::fromUTF8(kHeight));
   2805   border_before_fullscreen_ =
   2806       element.getAttribute(WebString::fromUTF8(kBorder));
   2807   style_before_fullscreen_ = element.getAttribute(WebString::fromUTF8(kStyle));
   2808 }
   2809 
   2810 void PepperPluginInstanceImpl::SetSizeAttributesForFullscreen() {
   2811   WebKit::WebScreenInfo info = render_view_->screenInfo();
   2812   screen_size_for_fullscreen_ = gfx::Size(info.rect.width, info.rect.height);
   2813   std::string width = StringPrintf("%d", screen_size_for_fullscreen_.width());
   2814   std::string height = StringPrintf("%d", screen_size_for_fullscreen_.height());
   2815 
   2816   WebElement element = container_->element();
   2817   element.setAttribute(WebString::fromUTF8(kWidth), WebString::fromUTF8(width));
   2818   element.setAttribute(WebString::fromUTF8(kHeight),
   2819                        WebString::fromUTF8(height));
   2820   element.setAttribute(WebString::fromUTF8(kBorder), WebString::fromUTF8("0"));
   2821 
   2822   // There should be no style settings that matter in fullscreen mode,
   2823   // so just replace them instead of appending.
   2824   // NOTE: "position: fixed" and "display: block" reset the plugin and
   2825   // using %% settings might not work without them (e.g. if the plugin is a
   2826   // child of a container element).
   2827   std::string style;
   2828   style += StringPrintf("width: %s !important; ", width.c_str());
   2829   style += StringPrintf("height: %s !important; ", height.c_str());
   2830   style += "margin: 0 !important; padding: 0 !important; border: 0 !important";
   2831   container_->element().setAttribute(kStyle, WebString::fromUTF8(style));
   2832 }
   2833 
   2834 void PepperPluginInstanceImpl::ResetSizeAttributesAfterFullscreen() {
   2835   screen_size_for_fullscreen_ = gfx::Size();
   2836   WebElement element = container_->element();
   2837   element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_);
   2838   element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_);
   2839   element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_);
   2840   element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_);
   2841 }
   2842 
   2843 bool PepperPluginInstanceImpl::IsMouseLocked() {
   2844   return GetMouseLockDispatcher()->IsMouseLockedTo(
   2845       GetOrCreateLockTargetAdapter());
   2846 }
   2847 
   2848 bool PepperPluginInstanceImpl::LockMouse() {
   2849   return GetMouseLockDispatcher()->LockMouse(GetOrCreateLockTargetAdapter());
   2850 }
   2851 
   2852 MouseLockDispatcher::LockTarget*
   2853     PepperPluginInstanceImpl::GetOrCreateLockTargetAdapter() {
   2854   if (!lock_target_.get()) {
   2855     lock_target_.reset(new PluginInstanceLockTarget(this));
   2856   }
   2857   return lock_target_.get();
   2858 }
   2859 
   2860 MouseLockDispatcher* PepperPluginInstanceImpl::GetMouseLockDispatcher() {
   2861   if (flash_fullscreen_) {
   2862     RenderWidgetFullscreenPepper* container =
   2863         static_cast<RenderWidgetFullscreenPepper*>(fullscreen_container_);
   2864     return container->mouse_lock_dispatcher();
   2865   } else {
   2866     return render_view_->mouse_lock_dispatcher();
   2867   }
   2868 }
   2869 
   2870 void PepperPluginInstanceImpl::UnSetAndDeleteLockTargetAdapter() {
   2871   if (lock_target_.get()) {
   2872     GetMouseLockDispatcher()->OnLockTargetDestroyed(lock_target_.get());
   2873     lock_target_.reset();
   2874   }
   2875 }
   2876 
   2877 void PepperPluginInstanceImpl::DidDataFromWebURLResponse(
   2878     const WebKit::WebURLResponse& response,
   2879     int pending_host_id,
   2880     const ppapi::URLResponseInfoData& data) {
   2881   RendererPpapiHostImpl* host_impl = module_->renderer_ppapi_host();
   2882 
   2883   if (host_impl->in_process_router()) {
   2884     // Running in-process, we can just create the resource and call the
   2885     // PPP_Instance function directly.
   2886     scoped_refptr<ppapi::proxy::URLLoaderResource> loader_resource(
   2887         new ppapi::proxy::URLLoaderResource(
   2888             host_impl->in_process_router()->GetPluginConnection(pp_instance()),
   2889             pp_instance(), pending_host_id, data));
   2890 
   2891     PP_Resource loader_pp_resource = loader_resource->GetReference();
   2892     if (!instance_interface_->HandleDocumentLoad(
   2893             pp_instance(), loader_pp_resource))
   2894       loader_resource->Close();
   2895     // We don't pass a ref into the plugin, if it wants one, it will have taken
   2896     // an additional one.
   2897     ppapi::PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(
   2898         loader_pp_resource);
   2899   } else {
   2900     // Running out-of-process. Initiate an IPC call to notify the plugin
   2901     // process.
   2902     ppapi::proxy::HostDispatcher* dispatcher =
   2903         ppapi::proxy::HostDispatcher::GetForInstance(pp_instance());
   2904     dispatcher->Send(new PpapiMsg_PPPInstance_HandleDocumentLoad(
   2905         ppapi::API_ID_PPP_INSTANCE, pp_instance(), pending_host_id, data));
   2906   }
   2907 }
   2908 
   2909 }  // namespace content
   2910