1736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov// Use of this source code is governed by a BSD-style license that can be
3736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov// found in the LICENSE file.
4736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
5736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "content/child/npapi/plugin_instance.h"
6736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
7736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "base/bind.h"
8736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "base/command_line.h"
9736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "base/files/file_util.h"
10736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "base/message_loop/message_loop.h"
11736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "base/strings/string_number_conversions.h"
12736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "base/strings/utf_string_conversions.h"
13736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "build/build_config.h"
14736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "content/child/npapi/plugin_host.h"
15736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "content/child/npapi/plugin_lib.h"
16736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "content/child/npapi/plugin_stream_url.h"
17736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "content/child/npapi/plugin_string_stream.h"
18736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "content/child/npapi/webplugin.h"
19736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "content/child/npapi/webplugin_delegate.h"
204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#include "content/child/npapi/webplugin_resource_client.h"
214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#include "content/public/common/content_constants.h"
224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#include "content/public/common/content_switches.h"
234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#include "net/base/escape.h"
24ea6fbc0981564f7bbf4c6fbb63af0175415121ceCasey Burkhardt
254213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#if defined(OS_MACOSX)
264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#include <ApplicationServices/ApplicationServices.h>
27e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#endif
28736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
29e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovnamespace content {
30736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
31736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav GanovPluginInstance::PluginInstance(PluginLib* plugin, const std::string& mime_type)
32e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    : plugin_(plugin),
33e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      npp_(0),
344213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov      host_(PluginHost::Singleton()),
35f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov      npp_functions_(plugin->functions()),
36f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov      window_handle_(0),
3786783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov      windowless_(false),
38736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      transparent_(true),
394213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov      webplugin_(0),
40f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov      mime_type_(mime_type),
414213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov      get_notify_data_(0),
42736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      use_mozilla_user_agent_(false),
43736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#if defined (OS_MACOSX)
44736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#ifdef NP_NO_QUICKDRAW
45736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      drawing_model_(NPDrawingModelCoreGraphics),
46736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#else
47736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      drawing_model_(NPDrawingModelQuickDraw),
48736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif
49736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#ifdef NP_NO_CARBON
50e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      event_model_(NPEventModelCocoa),
51e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#else
52e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      event_model_(NPEventModelCarbon),
53e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#endif
54e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      currently_handled_event_(NULL),
55736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif
56e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      message_loop_(base::MessageLoop::current()),
57e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      load_manually_(false),
58e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      in_close_streams_(false),
59e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      next_timer_id_(1),
60e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      next_notify_id_(0),
61e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      next_range_request_id_(0),
62736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      handles_url_redirects_(false) {
63736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  npp_ = new NPP_t();
64736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  npp_->ndata = 0;
65736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  npp_->pdata = 0;
661cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  if (mime_type_ == kFlashPluginSwfMimeType)
68736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    transparent_ = false;
69736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
70736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  memset(&zero_padding_, 0, sizeof(zero_padding_));
714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  DCHECK(message_loop_);
72736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
73736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
74736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav GanovPluginInstance::~PluginInstance() {
75736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  CloseStreams();
76736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
774213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  if (npp_ != 0) {
78736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    delete npp_;
79736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    npp_ = 0;
80736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
8112a024ca681d877fe16b7e087356f7aff175a218Svetoslav Ganov
82736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  if (plugin_.get())
83f804420d6e37748b75478406e989c69303756980Svetoslav Ganov    plugin_->CloseInstance();
84f804420d6e37748b75478406e989c69303756980Svetoslav Ganov}
85736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
864213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav GanovPluginStreamUrl* PluginInstance::CreateStream(unsigned long resource_id,
874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                                              const GURL& url,
884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                                              const std::string& mime_type,
89e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                              int notify_id) {
904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  bool notify;
92e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  void* notify_data;
93e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  GetNotifyData(notify_id, &notify, &notify_data);
94e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  PluginStreamUrl* stream = new PluginStreamUrl(
95e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      resource_id, url, this, notify, notify_data);
96e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
97e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  AddStream(stream);
98e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return stream;
99e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
1004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
10195068e5d1bea47091e97955f271c789264994550Svetoslav Ganovvoid PluginInstance::AddStream(PluginStream* stream) {
10295068e5d1bea47091e97955f271c789264994550Svetoslav Ganov  open_streams_.push_back(make_scoped_refptr(stream));
10395068e5d1bea47091e97955f271c789264994550Svetoslav Ganov}
104736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
105736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovvoid PluginInstance::RemoveStream(PluginStream* stream) {
106736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  if (in_close_streams_)
107e47957a0bbe2164467ff6e7a566b0c9e4689cdc9Svetoslav Ganov    return;
108e47957a0bbe2164467ff6e7a566b0c9e4689cdc9Svetoslav Ganov
109e47957a0bbe2164467ff6e7a566b0c9e4689cdc9Svetoslav Ganov  std::vector<scoped_refptr<PluginStream> >::iterator stream_index;
110e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  for (stream_index = open_streams_.begin();
111e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov       stream_index != open_streams_.end(); ++stream_index) {
112e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    if (stream_index->get() == stream) {
113e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      open_streams_.erase(stream_index);
114e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      break;
115e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    }
116e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
117e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
118e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
119e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovbool PluginInstance::IsValidStream(const NPStream* stream) {
120e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  std::vector<scoped_refptr<PluginStream> >::iterator stream_index;
121736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  for (stream_index = open_streams_.begin();
122736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov          stream_index != open_streams_.end(); ++stream_index) {
123736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    if ((*stream_index)->stream() == stream)
124736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      return true;
125736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
126736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
127736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  return false;
128736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
129736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
130736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovvoid PluginInstance::CloseStreams() {
131e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  in_close_streams_ = true;
132e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  for (unsigned int index = 0; index < open_streams_.size(); ++index) {
133e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    // Close all streams on the way down.
134e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    open_streams_[index]->Close(NPRES_USER_BREAK);
135e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
136736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  open_streams_.clear();
137f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov  in_close_streams_ = false;
138f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov}
139f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov
14095068e5d1bea47091e97955f271c789264994550Svetoslav GanovWebPluginResourceClient* PluginInstance::GetRangeRequest(
14195068e5d1bea47091e97955f271c789264994550Svetoslav Ganov    int id) {
14295068e5d1bea47091e97955f271c789264994550Svetoslav Ganov  PendingRangeRequestMap::iterator iter = pending_range_requests_.find(id);
143e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (iter == pending_range_requests_.end()) {
144e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    NOTREACHED();
145e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    return NULL;
146e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
147e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
148e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  WebPluginResourceClient* rv = iter->second->AsResourceClient();
149e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  pending_range_requests_.erase(iter);
150e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return rv;
151e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
152e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1531cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganovbool PluginInstance::Start(const GURL& url,
1541cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov                           char** const param_names,
1551cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov                           char** const param_values,
156e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                           int param_count,
1574213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                           bool load_manually) {
1584213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  load_manually_ = load_manually;
159e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  unsigned short mode = load_manually_ ? NP_FULL : NP_EMBED;
1604213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  npp_->ndata = this;
1614213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
162e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  NPError err = NPP_New(mode, param_count,
1634213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov      const_cast<char **>(param_names), const_cast<char **>(param_values));
1644213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
165e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (err == NPERR_NO_ERROR) {
166e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    handles_url_redirects_ =
1674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        ((npp_functions_->version >= NPVERS_HAS_URL_REDIRECT_HANDLING) &&
168e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov         (npp_functions_->urlredirectnotify));
169e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
1704213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  return err == NPERR_NO_ERROR;
171e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
172e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
173e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav GanovNPObject *PluginInstance::GetPluginScriptableObject() {
174e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  NPObject *value = NULL;
175e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  NPError error = NPP_GetValue(NPPVpluginScriptableNPObject, &value);
176e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (error != NPERR_NO_ERROR || value == NULL)
177e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    return NULL;
178e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return value;
179e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
180e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
181e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovbool PluginInstance::GetFormValue(base::string16* value) {
182e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  // Plugins will allocate memory for the return value by using NPN_MemAlloc().
183e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  char *plugin_value = NULL;
184e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  NPError error = NPP_GetValue(NPPVformValue, &plugin_value);
185e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (error != NPERR_NO_ERROR || !plugin_value) {
186e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    return false;
187e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
188e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  // Assumes the result is UTF8 text, as Firefox does.
189e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  *value = base::UTF8ToUTF16(plugin_value);
190e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  host_->host_functions()->memfree(plugin_value);
191e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return true;
192e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
193e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
194e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov// WebPluginLoadDelegate methods
195e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::DidFinishLoadWithReason(const GURL& url,
196e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                             NPReason reason,
1974213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                                             int notify_id) {
198385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov  bool notify;
199385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov  void* notify_data;
200385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov  GetNotifyData(notify_id, &notify, &notify_data);
201736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  if (!notify) {
202736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    NOTREACHED();
203736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    return;
204736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
205736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
206736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  NPP_URLNotify(url.spec().c_str(), reason, notify_data);
2071cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov}
208e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2094213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovunsigned PluginInstance::GetBackingTextureId() {
2104213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  // By default the plugin instance is not backed by an OpenGL texture.
211e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return 0;
212e47957a0bbe2164467ff6e7a566b0c9e4689cdc9Svetoslav Ganov}
213e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
214e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov// NPAPI methods
215e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav GanovNPError PluginInstance::NPP_New(unsigned short mode,
216736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                short argc,
217f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov                                char* argn[],
21895068e5d1bea47091e97955f271c789264994550Svetoslav Ganov                                char* argv[]) {
2194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  DCHECK(npp_functions_ != 0);
220ea6fbc0981564f7bbf4c6fbb63af0175415121ceCasey Burkhardt  DCHECK(npp_functions_->newp != 0);
221ea6fbc0981564f7bbf4c6fbb63af0175415121ceCasey Burkhardt  DCHECK(argc >= 0);
2224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
223e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (npp_functions_->newp != 0) {
224e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    return npp_functions_->newp(
225e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        (NPMIMEType)mime_type_.c_str(), npp_, mode,  argc, argn, argv, NULL);
226e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
227e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return NPERR_INVALID_FUNCTABLE_ERROR;
228e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
229e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
230e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::NPP_Destroy() {
231e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_ != 0);
232e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_->destroy != 0);
233e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
234e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (npp_functions_->destroy != 0) {
235e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    NPSavedData *savedData = 0;
236e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    npp_functions_->destroy(npp_, &savedData);
237e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
238e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    // TODO: Support savedData.  Technically, these need to be
239736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    //       saved on a per-URL basis, and then only passed
240736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    //       to new instances of the plugin at the same URL.
2411cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    //       Sounds like a huge security risk.  When we do support
2421cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    //       these, we should pass them back to the PluginLib
2431cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    //       to be stored there.
2441cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    DCHECK(savedData == 0);
2451cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov  }
246e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
247e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  for (unsigned int file_index = 0; file_index < files_created_.size();
248e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov       file_index++) {
249e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    base::DeleteFile(files_created_[file_index], false);
250e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
251e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
252e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  // Ensure that no timer callbacks are invoked after NPP_Destroy.
253e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  timers_.clear();
254e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
255e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
256e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav GanovNPError PluginInstance::NPP_SetWindow(NPWindow* window) {
257e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_ != 0);
258e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_->setwindow != 0);
259e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
260e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (npp_functions_->setwindow != 0) {
261e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    return npp_functions_->setwindow(npp_, window);
262e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
263e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return NPERR_INVALID_FUNCTABLE_ERROR;
264e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
265e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
266e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav GanovNPError PluginInstance::NPP_NewStream(NPMIMEType type,
267e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                      NPStream* stream,
268e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                      NPBool seekable,
26995068e5d1bea47091e97955f271c789264994550Svetoslav Ganov                                      unsigned short* stype) {
270e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_ != 0);
271e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_->newstream != 0);
272e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (npp_functions_->newstream != 0) {
273e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      return npp_functions_->newstream(npp_, type, stream, seekable, stype);
274e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
275e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return NPERR_INVALID_FUNCTABLE_ERROR;
276e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
277e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
278e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav GanovNPError PluginInstance::NPP_DestroyStream(NPStream* stream, NPReason reason) {
279e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_ != 0);
280e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_->destroystream != 0);
2811cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
2821cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov  if (stream == NULL || !IsValidStream(stream) || (stream->ndata == NULL))
2831cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    return NPERR_INVALID_INSTANCE_ERROR;
2841cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
2851cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov  if (npp_functions_->destroystream != 0) {
2861cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    NPError result = npp_functions_->destroystream(npp_, stream, reason);
2871cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    stream->ndata = NULL;
2881cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    return result;
289736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
290736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  return NPERR_INVALID_FUNCTABLE_ERROR;
2911cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov}
292736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
293736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovint PluginInstance::NPP_WriteReady(NPStream* stream) {
2944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  DCHECK(npp_functions_ != 0);
295736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  DCHECK(npp_functions_->writeready != 0);
2964213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  if (npp_functions_->writeready != 0) {
297736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    return npp_functions_->writeready(npp_, stream);
298736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
2994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  return 0;
300736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
301736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
302736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovint PluginInstance::NPP_Write(NPStream* stream,
303736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                              int offset,
304736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                              int len,
305736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                              void* buffer) {
306736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  DCHECK(npp_functions_ != 0);
307736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  DCHECK(npp_functions_->write != 0);
308736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  if (npp_functions_->write != 0) {
309736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    return npp_functions_->write(npp_, stream, offset, len, buffer);
310736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
3114213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  return 0;
3124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
3134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
3144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovvoid PluginInstance::NPP_StreamAsFile(NPStream* stream, const char* fname) {
315736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  DCHECK(npp_functions_ != 0);
316736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  DCHECK(npp_functions_->asfile != 0);
317736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  if (npp_functions_->asfile != 0) {
318736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    npp_functions_->asfile(npp_, stream, fname);
31986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov  }
32086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
32186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov  // Creating a temporary FilePath instance on the stack as the explicit
32286783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov  // FilePath constructor with StringType as an argument causes a compiler
32386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov  // error when invoked via vector push back.
32486783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov  base::FilePath file_name = base::FilePath::FromUTF8Unsafe(fname);
32586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov  files_created_.push_back(file_name);
3265d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov}
3275d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov
3285d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganovvoid PluginInstance::NPP_URLNotify(const char* url,
32986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov                                   NPReason reason,
330385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov                                   void* notifyData) {
331385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov  DCHECK(npp_functions_ != 0);
332385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov  DCHECK(npp_functions_->urlnotify != 0);
333385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov  if (npp_functions_->urlnotify != 0) {
334385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov    npp_functions_->urlnotify(npp_, url, reason, notifyData);
33586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov  }
33686783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov}
3371cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
3381cf70bbf96930662cab0e699d70b62865766ff52Svetoslav GanovNPError PluginInstance::NPP_GetValue(NPPVariable variable, void* value) {
3391cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov  DCHECK(npp_functions_ != 0);
34086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov  // getvalue is NULL for Shockwave
34186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov  if (npp_functions_->getvalue != 0) {
342736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    return npp_functions_->getvalue(npp_, variable, value);
343736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
344736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  return NPERR_INVALID_FUNCTABLE_ERROR;
345736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
346736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
347736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav GanovNPError PluginInstance::NPP_SetValue(NPNVariable variable, void* value) {
348736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  DCHECK(npp_functions_ != 0);
3494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  if (npp_functions_->setvalue != 0) {
3504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    return npp_functions_->setvalue(npp_, variable, value);
3514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  }
3524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  return NPERR_INVALID_FUNCTABLE_ERROR;
3534213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
3544213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
3554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovshort PluginInstance::NPP_HandleEvent(void* event) {
356736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  DCHECK(npp_functions_ != 0);
357e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_->event != 0);
358e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (npp_functions_->event != 0) {
359736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    return npp_functions_->event(npp_, (void*)event);
360f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov  }
361e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return false;
362e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
363e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
364e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovbool PluginInstance::NPP_Print(NPPrint* platform_print) {
365e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_ != 0);
366e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (npp_functions_->print != 0) {
367736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    npp_functions_->print(npp_, platform_print);
368736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    return true;
369736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
370736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  return false;
371736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
372736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
373736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovvoid PluginInstance::NPP_URLRedirectNotify(const char* url, int32_t status,
374e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                           void* notify_data) {
375e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(npp_functions_ != 0);
376e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (npp_functions_->urlredirectnotify != 0) {
377e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    npp_functions_->urlredirectnotify(npp_, url, status, notify_data);
378e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
379e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
380736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
381736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovvoid PluginInstance::SendJavaScriptStream(const GURL& url,
382ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov                                          const std::string& result,
383ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov                                          bool success,
384e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                          int notify_id) {
385e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  bool notify;
386e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  void* notify_data;
387e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  GetNotifyData(notify_id, &notify, &notify_data);
388e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
389e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (success) {
390e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    PluginStringStream *stream =
391e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        new PluginStringStream(this, url, notify, notify_data);
392e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    AddStream(stream);
393f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov    stream->SendToPlugin(result, "text/html");
394736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  } else {
395e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    // NOTE: Sending an empty stream here will crash MacroMedia
396e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    // Flash 9.  Just send the URL Notify.
397e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    if (notify)
398e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      NPP_URLNotify(url.spec().c_str(), NPRES_DONE, notify_data);
399e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
400736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
401736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
402736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovvoid PluginInstance::DidReceiveManualResponse(const GURL& url,
403736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                              const std::string& mime_type,
404736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                              const std::string& headers,
405736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                              uint32 expected_length,
406736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                              uint32 last_modified) {
4074213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  DCHECK(load_manually_);
40891feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov
40991feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov  plugin_data_stream_ =
410736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      CreateStream(static_cast<unsigned long>(-1), url, mime_type, 0);
411736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  plugin_data_stream_->DidReceiveResponse(mime_type, headers, expected_length,
412736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                          last_modified, true);
413736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
414736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
415e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::DidReceiveManualData(const char* buffer, int length) {
416e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(load_manually_);
417e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (plugin_data_stream_.get() != NULL) {
418e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    plugin_data_stream_->DidReceiveData(buffer, length, 0);
419e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
420e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
421e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
422e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::DidFinishManualLoading() {
423e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(load_manually_);
4244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  if (plugin_data_stream_.get() != NULL) {
425736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    plugin_data_stream_->DidFinishLoading(plugin_data_stream_->ResourceId());
4264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    plugin_data_stream_->Close(NPRES_DONE);
427736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    plugin_data_stream_ = NULL;
428736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
429e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
430e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
431e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::DidManualLoadFail() {
432e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(load_manually_);
433e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (plugin_data_stream_.get() != NULL) {
4344213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    plugin_data_stream_->DidFail(plugin_data_stream_->ResourceId());
4354213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    plugin_data_stream_ = NULL;
4364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  }
4374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
438e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
439e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::PluginThreadAsyncCall(void (*func)(void*),
440e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                           void* user_data) {
4414213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  message_loop_->PostTask(
442e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      FROM_HERE, base::Bind(&PluginInstance::OnPluginThreadAsyncCall, this,
443e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                            func, user_data));
444e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
44595068e5d1bea47091e97955f271c789264994550Svetoslav Ganov
446e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::OnPluginThreadAsyncCall(void (*func)(void*),
447e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                             void* user_data) {
448e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  // Do not invoke the callback if NPP_Destroy has already been invoked.
449e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (webplugin_)
450e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    func(user_data);
451ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov}
452e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
45391feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganovuint32 PluginInstance::ScheduleTimer(uint32 interval,
45491feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov                                     NPBool repeat,
455e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                     void (*func)(NPP id, uint32 timer_id)) {
456736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  // Use next timer id.
457736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  uint32 timer_id;
458e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  timer_id = next_timer_id_;
459e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  ++next_timer_id_;
460e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  DCHECK(next_timer_id_ != 0);
461e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
462e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  // Record timer interval and repeat.
463e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  TimerInfo info;
46491feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov  info.interval = interval;
465736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  info.repeat = repeat ? true : false;
466736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  timers_[timer_id] = info;
467e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
468e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  // Schedule the callback.
469e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  base::MessageLoop::current()->PostDelayedTask(
470e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      FROM_HERE,
471e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      base::Bind(&PluginInstance::OnTimerCall, this, func, npp_, timer_id),
472e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      base::TimeDelta::FromMilliseconds(interval));
473e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return timer_id;
474e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
475e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
476e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::UnscheduleTimer(uint32 timer_id) {
477e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  // Remove info about the timer.
478ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov  TimerMap::iterator it = timers_.find(timer_id);
479e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (it != timers_.end())
480e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    timers_.erase(it);
481e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
482e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
483736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#if !defined(OS_MACOSX)
484e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav GanovNPError PluginInstance::PopUpContextMenu(NPMenu* menu) {
485736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  NOTIMPLEMENTED();
486e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  return NPERR_GENERIC_ERROR;
487e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
48847e02711d78ecac9112aa7f66e5664cdc46fb3d1Svetoslav Ganov#endif
489736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
490e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::OnTimerCall(void (*func)(NPP id, uint32 timer_id),
491e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                 NPP id,
492e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                 uint32 timer_id) {
493736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  // Do not invoke callback if the timer has been unscheduled.
494e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  TimerMap::iterator it = timers_.find(timer_id);
495e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  if (it == timers_.end())
496e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    return;
497e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
498e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  // Get all information about the timer before invoking the callback. The
499736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  // callback might unschedule the timer.
500736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  TimerInfo info = it->second;
501736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
502736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  func(id, timer_id);
50300f7b3f76515d1c6fbe5cf9fee9d3760787c03cdSvetoslav Ganov
50491feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov  // If the timer was unscheduled by the callback, just free up the timer id.
50591feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov  if (timers_.find(timer_id) == timers_.end())
50691feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov    return;
507736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
508736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  // Reschedule repeating timers after invoking the callback so callback is not
509736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  // re-entered if it pumps the message loop.
510736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  if (info.repeat) {
511736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    base::MessageLoop::current()->PostDelayedTask(
512736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        FROM_HERE,
513736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        base::Bind(&PluginInstance::OnTimerCall, this, func, npp_, timer_id),
514e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        base::TimeDelta::FromMilliseconds(info.interval));
515e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  } else {
516e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    timers_.erase(it);
517e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
518e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
519e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
520e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::PushPopupsEnabledState(bool enabled) {
521e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  popups_enabled_stack_.push(enabled);
522e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
523ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov
524e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovvoid PluginInstance::PopPopupsEnabledState() {
525e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  popups_enabled_stack_.pop();
526e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
527e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
528736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovvoid PluginInstance::RequestRead(NPStream* stream, NPByteRange* range_list) {
529736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  std::string range_info = "bytes=";
530736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
531736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  while (range_list) {
532736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    range_info += base::IntToString(range_list->offset);
533736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    range_info.push_back('-');
534736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    range_info +=
535736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        base::IntToString(range_list->offset + range_list->length - 1);
536e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    range_list = range_list->next;
537e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    if (range_list)
538e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      range_info.push_back(',');
539e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  }
540736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
5414213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  if (plugin_data_stream_.get()) {
54291feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov    if (plugin_data_stream_->stream() == stream) {
543736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      webplugin_->CancelDocumentLoad();
544736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      plugin_data_stream_ = NULL;
545736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    }
5464213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  }
547736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
548736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  // The lifetime of a NPStream instance depends on the PluginStream instance
549736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  // which owns it. When a plugin invokes NPN_RequestRead on a seekable stream,
550f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov  // we don't want to create a new stream when the corresponding response is
551f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov  // received. We send over a cookie which represents the PluginStream
552e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  // instance which is sent back from the renderer when the response is
553e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  // received.
554e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  std::vector<scoped_refptr<PluginStream> >::iterator stream_index;
555736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  for (stream_index = open_streams_.begin();
556e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov          stream_index != open_streams_.end(); ++stream_index) {
557e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    PluginStream* plugin_stream = stream_index->get();
558736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    if (plugin_stream->stream() == stream) {
559736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      // A stream becomes seekable the first time NPN_RequestRead
560736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      // is called on it.
5614213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov      plugin_stream->set_seekable(true);
5624213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
5634213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov      if (CommandLine::ForCurrentProcess()->HasSwitch(
5644213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov              switches::kDisableDirectNPAPIRequests)) {
565736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        pending_range_requests_[++next_range_request_id_] = plugin_stream;
566736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        webplugin_->InitiateHTTPRangeRequest(
567e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            stream->url, range_info.c_str(), next_range_request_id_);
568736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        return;
569736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      } else {
570736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        PluginStreamUrl* plugin_stream_url =
571736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            static_cast<PluginStreamUrl*>(plugin_stream);
572736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        plugin_stream_url->FetchRange(range_info);
573736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        return;
574736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      }
575736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    }
576736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
577736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  NOTREACHED();
578736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
57991feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov
580736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovvoid PluginInstance::RequestURL(const char* url,
581736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                const char* method,
582736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                const char* target,
583736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                const char* buf,
584736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                unsigned int len,
585736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                bool notify,
586736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                void* notify_data) {
587736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  int notify_id = 0;
588736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  if (notify) {
58991feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov    notify_id = ++next_notify_id_;
590736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    pending_requests_[notify_id] = notify_data;
591736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
592736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
5934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  webplugin_->HandleURLRequest(
594736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      url, method, target, buf, len, notify_id, popups_allowed(),
5952e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov      notify ? handles_url_redirects_ : false);
5962e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov}
5972e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov
598736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovbool PluginInstance::ConvertPoint(double source_x, double source_y,
599736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                  NPCoordinateSpace source_space,
600e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                  double* dest_x, double* dest_y,
601e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                                  NPCoordinateSpace dest_space) {
602e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#if defined(OS_MACOSX)
603e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  CGRect main_display_bounds = CGDisplayBounds(CGMainDisplayID());
604e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
605e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  double flipped_screen_x = source_x;
606e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  double flipped_screen_y = source_y;
607e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov  switch(source_space) {
608e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    case NPCoordinateSpacePlugin:
609e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      flipped_screen_x += plugin_origin_.x();
610e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      flipped_screen_y += plugin_origin_.y();
611e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      break;
612e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    case NPCoordinateSpaceWindow:
613e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      flipped_screen_x += containing_window_frame_.x();
614e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      flipped_screen_y = containing_window_frame_.height() - source_y +
615e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov          containing_window_frame_.y();
616e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      break;
617e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    case NPCoordinateSpaceFlippedWindow:
618e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      flipped_screen_x += containing_window_frame_.x();
619e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      flipped_screen_y += containing_window_frame_.y();
620e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      break;
621e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    case NPCoordinateSpaceScreen:
622736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      flipped_screen_y = main_display_bounds.size.height - flipped_screen_y;
62391feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov      break;
62491feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov    case NPCoordinateSpaceFlippedScreen:
625736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      break;
626736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    default:
627736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      NOTREACHED();
628736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      return false;
629736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
63091feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov
63191feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov  double target_x = flipped_screen_x;
632736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  double target_y = flipped_screen_y;
633736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  switch(dest_space) {
634736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    case NPCoordinateSpacePlugin:
635736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      target_x -= plugin_origin_.x();
636736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      target_y -= plugin_origin_.y();
637736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      break;
638736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    case NPCoordinateSpaceWindow:
63991feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov      target_x -= containing_window_frame_.x();
64091feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov      target_y -= containing_window_frame_.y();
641736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      target_y = containing_window_frame_.height() - target_y;
642736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      break;
643736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    case NPCoordinateSpaceFlippedWindow:
644736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      target_x -= containing_window_frame_.x();
645736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      target_y -= containing_window_frame_.y();
646736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov      break;
6474213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    case NPCoordinateSpaceScreen:
648d8581c7a61a9db042b531ce4baca3c036316e066Svetoslav Ganov      target_y = main_display_bounds.size.height - flipped_screen_y;
649d8581c7a61a9db042b531ce4baca3c036316e066Svetoslav Ganov      break;
650d8581c7a61a9db042b531ce4baca3c036316e066Svetoslav Ganov    case NPCoordinateSpaceFlippedScreen:
651d8581c7a61a9db042b531ce4baca3c036316e066Svetoslav Ganov      break;
652d8581c7a61a9db042b531ce4baca3c036316e066Svetoslav Ganov    default:
653d8581c7a61a9db042b531ce4baca3c036316e066Svetoslav Ganov      NOTREACHED();
654d8581c7a61a9db042b531ce4baca3c036316e066Svetoslav Ganov      return false;
655d8581c7a61a9db042b531ce4baca3c036316e066Svetoslav Ganov  }
656d8581c7a61a9db042b531ce4baca3c036316e066Svetoslav Ganov
657736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  if (dest_x)
6582e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov    *dest_x = target_x;
6592e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov  if (dest_y)
6602e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov    *dest_y = target_y;
661736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  return true;
662e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#else
663736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  NOTIMPLEMENTED();
664736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  return false;
665736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif
666736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
667736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
668736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovvoid PluginInstance::GetNotifyData(int notify_id,
669736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                   bool* notify,
670736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                                   void** notify_data) {
671736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  PendingRequestMap::iterator iter = pending_requests_.find(notify_id);
672736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  if (iter != pending_requests_.end()) {
6732e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov    *notify = true;
674736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    *notify_data = iter->second;
675736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    pending_requests_.erase(iter);
676736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  } else {
677736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    *notify = false;
678736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    *notify_data = NULL;
679736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
680736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
681736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
6824213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovvoid PluginInstance::URLRedirectResponse(bool allow, void* notify_data) {
6834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov  // The notify_data passed in allows us to identify the matching stream.
684736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  std::vector<scoped_refptr<PluginStream> >::iterator stream_index;
685f804420d6e37748b75478406e989c69303756980Svetoslav Ganov  for (stream_index = open_streams_.begin();
686f804420d6e37748b75478406e989c69303756980Svetoslav Ganov          stream_index != open_streams_.end(); ++stream_index) {
687736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    PluginStream* plugin_stream = stream_index->get();
688736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    if (plugin_stream->notify_data() == notify_data) {
689e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      PluginStreamUrl* plugin_stream_url =
690736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov          static_cast<PluginStreamUrl*>(plugin_stream);
691e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      plugin_stream_url->URLRedirectResponse(allow);
692e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov      break;
693e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    }
694736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov  }
6954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
696736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
697736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}  // namespace content
698736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov