| OLD | NEW |
| (Empty) |
| 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/child/npapi/webplugin_delegate_impl.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 | |
| 9 #include <string> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "base/message_loop/message_loop.h" | |
| 14 #include "base/process/process_handle.h" | |
| 15 #include "base/strings/string_util.h" | |
| 16 #include "base/strings/utf_string_conversions.h" | |
| 17 #include "build/build_config.h" | |
| 18 #include "content/child/npapi/plugin_instance.h" | |
| 19 #include "content/child/npapi/plugin_lib.h" | |
| 20 #include "third_party/WebKit/public/web/WebInputEvent.h" | |
| 21 | |
| 22 using blink::WebCursorInfo; | |
| 23 using blink::WebInputEvent; | |
| 24 | |
| 25 namespace content { | |
| 26 | |
| 27 WebPluginDelegateImpl* WebPluginDelegateImpl::Create( | |
| 28 WebPlugin* plugin, | |
| 29 const base::FilePath& filename, | |
| 30 const std::string& mime_type) { | |
| 31 scoped_refptr<PluginLib> plugin_lib(PluginLib::CreatePluginLib(filename)); | |
| 32 if (plugin_lib.get() == NULL) | |
| 33 return NULL; | |
| 34 | |
| 35 NPError err = plugin_lib->NP_Initialize(); | |
| 36 if (err != NPERR_NO_ERROR) | |
| 37 return NULL; | |
| 38 | |
| 39 scoped_refptr<PluginInstance> instance(plugin_lib->CreateInstance(mime_type)); | |
| 40 return new WebPluginDelegateImpl(plugin, instance.get()); | |
| 41 } | |
| 42 | |
| 43 void WebPluginDelegateImpl::PluginDestroyed() { | |
| 44 if (handle_event_depth_) { | |
| 45 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | |
| 46 } else { | |
| 47 delete this; | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 bool WebPluginDelegateImpl::Initialize( | |
| 52 const GURL& url, | |
| 53 const std::vector<std::string>& arg_names, | |
| 54 const std::vector<std::string>& arg_values, | |
| 55 bool load_manually) { | |
| 56 if (instance_->plugin_lib()->plugin_info().name.find( | |
| 57 base::ASCIIToUTF16("QuickTime Plug-in")) != std::wstring::npos) { | |
| 58 quirks_ |= PLUGIN_QUIRK_COPY_STREAM_DATA; | |
| 59 } | |
| 60 | |
| 61 instance_->set_web_plugin(plugin_); | |
| 62 if (quirks_ & PLUGIN_QUIRK_DONT_ALLOW_MULTIPLE_INSTANCES) { | |
| 63 PluginLib* plugin_lib = instance()->plugin_lib(); | |
| 64 if (plugin_lib->instance_count() > 1) { | |
| 65 return false; | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 int argc = 0; | |
| 70 scoped_ptr<char*[]> argn(new char*[arg_names.size()]); | |
| 71 scoped_ptr<char*[]> argv(new char*[arg_names.size()]); | |
| 72 for (size_t i = 0; i < arg_names.size(); ++i) { | |
| 73 if (quirks_ & PLUGIN_QUIRK_NO_WINDOWLESS && | |
| 74 base::LowerCaseEqualsASCII(arg_names[i], "windowlessvideo")) { | |
| 75 continue; | |
| 76 } | |
| 77 argn[argc] = const_cast<char*>(arg_names[i].c_str()); | |
| 78 argv[argc] = const_cast<char*>(arg_values[i].c_str()); | |
| 79 argc++; | |
| 80 } | |
| 81 | |
| 82 creation_succeeded_ = instance_->Start( | |
| 83 url, argn.get(), argv.get(), argc, load_manually); | |
| 84 if (!creation_succeeded_) { | |
| 85 VLOG(1) << "Couldn't start plugin instance"; | |
| 86 return false; | |
| 87 } | |
| 88 | |
| 89 bool should_load = PlatformInitialize(); | |
| 90 | |
| 91 plugin_url_ = url.spec(); | |
| 92 | |
| 93 return should_load; | |
| 94 } | |
| 95 | |
| 96 void WebPluginDelegateImpl::DestroyInstance() { | |
| 97 if (instance_.get() && (instance_->npp()->ndata != NULL)) { | |
| 98 window_.window = NULL; | |
| 99 if (creation_succeeded_ && | |
| 100 !(quirks_ & PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY)) { | |
| 101 instance_->NPP_SetWindow(&window_); | |
| 102 } | |
| 103 | |
| 104 instance_->NPP_Destroy(); | |
| 105 | |
| 106 instance_->set_web_plugin(NULL); | |
| 107 | |
| 108 PlatformDestroyInstance(); | |
| 109 | |
| 110 instance_ = 0; | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 void WebPluginDelegateImpl::UpdateGeometry( | |
| 115 const gfx::Rect& window_rect, | |
| 116 const gfx::Rect& clip_rect) { | |
| 117 | |
| 118 if (first_set_window_call_) { | |
| 119 first_set_window_call_ = false; | |
| 120 // Plugins like media player on Windows have a bug where in they handle the | |
| 121 // first geometry update and ignore the rest resulting in painting issues. | |
| 122 // This quirk basically ignores the first set window call sequence for | |
| 123 // these plugins and has been tested for Windows plugins only. | |
| 124 if (quirks_ & PLUGIN_QUIRK_IGNORE_FIRST_SETWINDOW_CALL) | |
| 125 return; | |
| 126 } | |
| 127 | |
| 128 WindowlessUpdateGeometry(window_rect, clip_rect); | |
| 129 } | |
| 130 | |
| 131 void WebPluginDelegateImpl::SetFocus(bool focused) { | |
| 132 // This is called when internal WebKit focus (the focused element on the page) | |
| 133 // changes, but plugins need to know about OS-level focus, so we have an extra | |
| 134 // layer of focus tracking. | |
| 135 // | |
| 136 // On Windows, historically browsers did not set focus events to windowless | |
| 137 // plugins when the toplevel window focus changes. Sending such focus events | |
| 138 // breaks full screen mode in Flash because it will come out of full screen | |
| 139 // mode when it loses focus, and its full screen window causes the browser to | |
| 140 // lose focus. | |
| 141 has_webkit_focus_ = focused; | |
| 142 #if !defined(OS_WIN) | |
| 143 if (containing_view_has_focus_) | |
| 144 SetPluginHasFocus(focused); | |
| 145 #else | |
| 146 SetPluginHasFocus(focused); | |
| 147 #endif | |
| 148 } | |
| 149 | |
| 150 void WebPluginDelegateImpl::SetPluginHasFocus(bool focused) { | |
| 151 if (focused == plugin_has_focus_) | |
| 152 return; | |
| 153 if (PlatformSetPluginHasFocus(focused)) | |
| 154 plugin_has_focus_ = focused; | |
| 155 } | |
| 156 | |
| 157 void WebPluginDelegateImpl::SetContentAreaHasFocus(bool has_focus) { | |
| 158 containing_view_has_focus_ = has_focus; | |
| 159 #if !defined(OS_WIN) // See SetFocus above. | |
| 160 SetPluginHasFocus(containing_view_has_focus_ && has_webkit_focus_); | |
| 161 #endif | |
| 162 } | |
| 163 | |
| 164 int WebPluginDelegateImpl::GetProcessId() { | |
| 165 // We are in process, so the plugin pid is this current process pid. | |
| 166 return base::GetCurrentProcId(); | |
| 167 } | |
| 168 | |
| 169 base::FilePath WebPluginDelegateImpl::GetPluginPath() { | |
| 170 return instance()->plugin_lib()->plugin_info().path; | |
| 171 } | |
| 172 | |
| 173 bool WebPluginDelegateImpl::HandleInputEvent( | |
| 174 const WebInputEvent& event, | |
| 175 WebCursor::CursorInfo* cursor_info) { | |
| 176 bool pop_user_gesture = false; | |
| 177 if (IsUserGesture(event)) { | |
| 178 pop_user_gesture = true; | |
| 179 instance()->PushPopupsEnabledState(true); | |
| 180 } | |
| 181 | |
| 182 bool handled = PlatformHandleInputEvent(event, cursor_info); | |
| 183 | |
| 184 if (pop_user_gesture) { | |
| 185 instance()->PopPopupsEnabledState(); | |
| 186 } | |
| 187 | |
| 188 return handled; | |
| 189 } | |
| 190 | |
| 191 bool WebPluginDelegateImpl::IsUserGesture(const WebInputEvent& event) { | |
| 192 switch (event.type) { | |
| 193 case WebInputEvent::MouseDown: | |
| 194 case WebInputEvent::MouseUp: | |
| 195 case WebInputEvent::KeyDown: | |
| 196 case WebInputEvent::KeyUp: | |
| 197 return true; | |
| 198 default: | |
| 199 return false; | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 } // namespace content | |
| OLD | NEW |