Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7699)

Unified Diff: chrome_frame/chrome_frame_npapi.cc

Issue 7276037: Remove NPAPI support from Chrome Frame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome_frame/chrome_frame_npapi.h ('k') | chrome_frame/chrome_frame_npapi_entrypoints.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome_frame/chrome_frame_npapi.cc
===================================================================
--- chrome_frame/chrome_frame_npapi.cc (revision 90713)
+++ chrome_frame/chrome_frame_npapi.cc (working copy)
@@ -1,1139 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome_frame/chrome_frame_npapi.h"
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/string_split.h"
-#include "base/string_util.h"
-#include "base/stringprintf.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/test/automation/tab_proxy.h"
-#include "chrome_frame/np_utils.h"
-#include "chrome_frame/utils.h"
-
-MessageLoop* ChromeFrameNPAPI::message_loop_ = NULL;
-int ChromeFrameNPAPI::instance_count_ = 0;
-
-NPClass ChromeFrameNPAPI::plugin_class_ = {
- NP_CLASS_STRUCT_VERSION,
- ChromeFrameNPAPI::AllocateObject,
- ChromeFrameNPAPI::DeallocateObject,
- ChromeFrameNPAPI::Invalidate,
- ChromeFrameNPAPI::HasMethod,
- ChromeFrameNPAPI::Invoke,
- NULL, // invokeDefault
- ChromeFrameNPAPI::HasProperty,
- ChromeFrameNPAPI::GetProperty,
- ChromeFrameNPAPI::SetProperty,
- NULL, // remove property
- NULL, // enumeration
- NULL, // construct
-};
-
-NPIdentifier
- ChromeFrameNPAPI::plugin_property_identifiers_[PLUGIN_PROPERTY_COUNT]
- = {0};
-
-const NPUTF8* ChromeFrameNPAPI::plugin_property_identifier_names_[] = {
- "version",
- "src",
- "onload",
- "onloaderror",
- "onmessage",
- "readystate",
- "usechromenetwork",
- "onclose",
-};
-
-const NPUTF8* ChromeFrameNPAPI::plugin_method_identifier_names_[] = {
- "postMessage",
-};
-
-ChromeFrameNPAPI::PluginMethod ChromeFrameNPAPI::plugin_methods_[] = {
- &ChromeFrameNPAPI::postMessage,
-};
-
-NPIdentifier
- ChromeFrameNPAPI::plugin_method_identifiers_[arraysize(plugin_methods_)]
- = {0};
-
-
-void ChromeFrameNPAPI::CompileAsserts() {
- NOTREACHED(); // This function should never be invoked.
-
- COMPILE_ASSERT(arraysize(plugin_method_identifier_names_) ==
- arraysize(plugin_methods_),
- you_must_add_both_plugin_method_and_name);
-
- COMPILE_ASSERT(arraysize(plugin_property_identifier_names_) ==
- arraysize(plugin_property_identifiers_),
- you_must_add_both_plugin_property_and_name);
-}
-
-static const char kPluginSrcAttribute[] = "src";
-static const char kPluginForceFullPageAttribute[] = "force_full_page";
-static const char kPluginOnloadAttribute[] = "onload";
-static const char kPluginOnErrorAttribute[] = "onloaderror";
-static const char kPluginOnMessageAttribute[] = "onmessage";
-static const char kPluginOnPrivateMessageAttribute[] = "onprivatemessage";
-static const char kPluginOnCloseAttribute[] = "onclose";
-
-// If chrome network stack is to be used
-static const char kPluginUseChromeNetwork[] = "usechromenetwork";
-
-// ChromeFrameNPAPI member defines.
-
-// TODO(tommi): remove ignore_setfocus_ since that's not how focus is
-// handled anymore.
-
-ChromeFrameNPAPI::ChromeFrameNPAPI()
- : instance_(NULL),
- mode_(NP_EMBED),
- force_full_page_plugin_(false),
- ready_state_(READYSTATE_LOADING),
- enabled_popups_(false),
- navigate_after_initialization_(false) {
-}
-
-ChromeFrameNPAPI::~ChromeFrameNPAPI() {
- if (IsWindow()) {
- if (!UnsubclassWindow()) {
- // TODO(tommi): Figure out why this can sometimes happen in the
- // WidgetModeFF_Resize unittest.
- DLOG(ERROR) << "Couldn't unsubclass safely!";
- UnsubclassWindow(TRUE);
- }
- }
- m_hWnd = NULL;
-
- instance_count_--;
- if (instance_count_ <= 0) {
- delete message_loop_;
- message_loop_ = NULL;
- }
-
- Uninitialize();
-}
-
-std::string ChromeFrameNPAPI::GetLocation() {
- // Note that GetWindowObject() will cache the window object here.
- return np_utils::GetLocation(instance_, GetWindowObject());
-}
-
-bool ChromeFrameNPAPI::Initialize(NPMIMEType mime_type, NPP instance,
- uint16 mode, int16 argc, char* argn[],
- char* argv[]) {
- if (!Base::Initialize())
- return false;
-
- instance_ = instance;
- mime_type_ = mime_type;
- mode_ = mode;
- document_url_ = GetLocation();
-
- if (instance_count_ == 0) {
- DCHECK(message_loop_ == NULL);
- message_loop_ = new MessageLoop();
- }
-
- instance_count_++;
-
- for (int i = 0; i < argc; ++i) {
- if (LowerCaseEqualsASCII(argn[i], kPluginSrcAttribute)) {
- src_ = ResolveURL(GetDocumentUrl(), argv[i]);
- } else if (LowerCaseEqualsASCII(argn[i], kPluginForceFullPageAttribute)) {
- force_full_page_plugin_ = atoi(argv[i]) ? true : false;
- } else if (LowerCaseEqualsASCII(argn[i], kPluginOnErrorAttribute)) {
- onerror_handler_ = JavascriptToNPObject(argv[i]);
- } else if (LowerCaseEqualsASCII(argn[i], kPluginOnMessageAttribute)) {
- onmessage_handler_ = JavascriptToNPObject(argv[i]);
- } else if (LowerCaseEqualsASCII(argn[i], kPluginOnCloseAttribute)) {
- onclose_handler_ = JavascriptToNPObject(argv[i]);
- }
- }
-
- std::wstring profile_name(GetHostProcessName(false));
- std::wstring extra_arguments;
-
- static const wchar_t kHandleTopLevelRequests[] = L"HandleTopLevelRequests";
- bool top_level_requests = GetConfigBool(true, kHandleTopLevelRequests);
- automation_client_->set_handle_top_level_requests(top_level_requests);
- automation_client_->set_route_all_top_level_navigations(true);
-
- // Setup Url fetcher.
- url_fetcher_.set_NPPInstance(instance_);
- url_fetcher_.set_frame_busting(!is_privileged());
- automation_client_->SetUrlFetcher(&url_fetcher_);
-
- // TODO(joshia): Initialize navigation here and send proxy config as
- // part of LaunchSettings
- /*
- if (!src_.empty())
- automation_client_->InitiateNavigation(src_, is_privileged());
-
- std::string proxy_settings;
- bool has_prefs = pref_service_->Initialize(instance_,
- automation_client_.get());
- if (has_prefs && pref_service_->GetProxyValueJSONString(&proxy_settings)) {
- automation_client_->SetProxySettings(proxy_settings);
- }
- */
-
- // We can't call SubscribeToFocusEvents here since
- // when Initialize gets called, Opera is in a state where
- // it can't handle calls back and the thread will hang.
- // Instead, we call SubscribeToFocusEvents when we initialize
- // our plugin window.
-
- // TODO(stoyan): Ask host for specific interface whether to honor
- // host's in-private mode.
- return InitializeAutomation(profile_name, extra_arguments,
- GetBrowserIncognitoMode(), true,
- GURL(src_), GURL(), true);
-}
-
-void ChromeFrameNPAPI::Uninitialize() {
- if (ready_state_ != READYSTATE_UNINITIALIZED)
- SetReadyState(READYSTATE_UNINITIALIZED);
-
- window_object_.Free();
- onerror_handler_.Free();
- onmessage_handler_.Free();
- onprivatemessage_handler_.Free();
- onclose_handler_.Free();
-
- Base::Uninitialize();
-}
-
-void ChromeFrameNPAPI::OnFinalMessage(HWND window) {
- // The automation server should be gone by now.
- Uninitialize();
-}
-
-bool ChromeFrameNPAPI::SetWindow(NPWindow* window_info) {
- if (!window_info || !automation_client_.get()) {
- NOTREACHED();
- return false;
- }
-
- HWND window = reinterpret_cast<HWND>(window_info->window);
- if (!::IsWindow(window)) {
- // No window created yet. Ignore this call.
- return false;
- }
-
- if (IsWindow()) {
- // We've already subclassed, make sure that SetWindow doesn't get called
- // with an HWND other than the one we subclassed during our lifetime.
- DCHECK(window == m_hWnd);
- return true;
- }
-
- automation_client_->SetParentWindow(window);
-
- if (force_full_page_plugin_) {
- // By default full page mode is only enabled when the plugin is loaded off
- // a separate file, i.e. it is the primary content in the window. Even if
- // we specify the width/height attributes for the plugin as 100% each, FF
- // instantiates the plugin passing in a width/height of 100px each. To
- // workaround this we resize the plugin window passed in by FF to the size
- // of its parent.
- HWND plugin_parent_window = ::GetParent(window);
- RECT plugin_parent_rect = {0};
- ::GetClientRect(plugin_parent_window, &plugin_parent_rect);
- ::SetWindowPos(window, NULL, plugin_parent_rect.left,
- plugin_parent_rect.top,
- plugin_parent_rect.right - plugin_parent_rect.left,
- plugin_parent_rect.bottom - plugin_parent_rect.top, 0);
- }
-
- // Subclass the browser's plugin window here.
- if (SubclassWindow(window)) {
- DWORD new_style_flags = WS_CLIPCHILDREN;
- ModifyStyle(0, new_style_flags, 0);
-
- if (ready_state_ < READYSTATE_INTERACTIVE) {
- SetReadyState(READYSTATE_INTERACTIVE);
- }
- }
-
- return true;
-}
-
-void ChromeFrameNPAPI::Print(NPPrint* print_info) {
- if (!print_info) {
- NOTREACHED();
- return;
- }
-
- // We dont support full tab mode yet.
- if (print_info->mode != NP_EMBED) {
- NOTREACHED();
- return;
- }
-
- NPWindow window = print_info->print.embedPrint.window;
-
- RECT print_bounds = {0};
- print_bounds.left = window.x;
- print_bounds.top = window.y;
- print_bounds.right = window.x + window.width;
- print_bounds.bottom = window.x + window.height;
-
- automation_client_->Print(
- reinterpret_cast<HDC>(print_info->print.embedPrint.platformPrint),
- print_bounds);
-}
-
-void ChromeFrameNPAPI::UrlNotify(const char* url, NPReason reason,
- void* notify_data) {
- if (enabled_popups_) {
- // We have opened the URL so tell the browser to restore popup settings
- enabled_popups_ = false;
- npapi::PopPopupsEnabledState(instance_);
- }
-
- url_fetcher_.UrlNotify(url, reason, notify_data);
-}
-
-void ChromeFrameNPAPI::OnAcceleratorPressed(const MSG& accel_message) {
- DVLOG(1) << __FUNCTION__
- << " msg:" << base::StringPrintf("0x%04X", accel_message.message)
- << " key:" << accel_message.wParam;
-
- // The host browser does call TranslateMessage on messages like WM_KEYDOWN
- // WM_KEYUP, etc, which will result in messages like WM_CHAR, WM_SYSCHAR, etc
- // being posted to the message queue. We don't post these messages here to
- // avoid these messages from getting handled twice.
- if (accel_message.message != WM_CHAR &&
- accel_message.message != WM_DEADCHAR &&
- accel_message.message != WM_SYSCHAR &&
- accel_message.message != WM_SYSDEADCHAR) {
- // A very primitive way to handle keystrokes.
- // TODO(tommi): When we've implemented a way for chrome to
- // know when keystrokes are handled (deterministically) on that side,
- // then this function should get called and not otherwise.
- ::PostMessage(::GetParent(m_hWnd), accel_message.message,
- accel_message.wParam, accel_message.lParam);
- }
-
- if (automation_client_.get()) {
- TabProxy* tab = automation_client_->tab();
- if (tab) {
- tab->ProcessUnhandledAccelerator(accel_message);
- }
- }
-}
-
-void ChromeFrameNPAPI::OnTabbedOut(bool reverse) {
- DVLOG(1) << __FUNCTION__;
-
- ignore_setfocus_ = true;
-
- // Previously we set the focus to our parent window before sending the
- // keyboard event but the browser architecture has changed, so we release
- // our focus first by calling <object>.blur() and then tabbing to the
- // next element.
- ScopedNpObject<NPObject> object;
- npapi::GetValue(instance_, NPNVPluginElementNPObject, object.Receive());
- if (object.get()) {
- ScopedNpVariant result;
- bool invoke = npapi::Invoke(instance_, object,
- npapi::GetStringIdentifier("blur"), NULL, 0, &result);
- DLOG_IF(WARNING, !invoke) << "blur failed";
- } else {
- DLOG(WARNING) << "Failed to get the plugin element";
- }
-
- INPUT input = {0};
- input.type = INPUT_KEYBOARD;
- input.ki.wVk = VK_TAB;
- SendInput(1, &input, sizeof(input));
- input.ki.dwFlags = KEYEVENTF_KEYUP;
- SendInput(1, &input, sizeof(input));
-
- ignore_setfocus_ = false;
-}
-
-void ChromeFrameNPAPI::OnOpenURL(const GURL& url,
- const GURL& referrer,
- int open_disposition) {
- std::string target;
- switch (open_disposition) {
- case NEW_FOREGROUND_TAB:
- target = "_blank";
- break;
- case NEW_BACKGROUND_TAB:
- target = "_blank";
- break;
- case NEW_WINDOW:
- case NEW_POPUP:
- target = "_new";
- break;
- default:
- break;
- }
-
- // Tell the browser to temporarily allow popups
- enabled_popups_ = true;
- npapi::PushPopupsEnabledState(instance_, TRUE);
- npapi::GetURLNotify(instance_, url.spec().c_str(), target.c_str(), NULL);
-}
-
-bool ChromeFrameNPAPI::HasMethod(NPObject* obj, NPIdentifier name) {
- for (int i = 0; i < arraysize(plugin_methods_); ++i) {
- if (name == plugin_method_identifiers_[i])
- return true;
- }
-
- DLOG(INFO) << "Do not have method: " << npapi::StringFromIdentifier(name);
-
- return false;
-}
-
-bool ChromeFrameNPAPI::Invoke(NPObject* header, NPIdentifier name,
- const NPVariant* args, uint32_t arg_count,
- NPVariant* result) {
- ChromeFrameNPAPI* plugin_instance = ChromeFrameInstanceFromNPObject(header);
- if (!plugin_instance || !plugin_instance->automation_client_.get())
- return false;
-
- bool success = false;
- for (int i = 0; i < arraysize(plugin_methods_); ++i) {
- if (name == plugin_method_identifiers_[i]) {
- PluginMethod method = plugin_methods_[i];
- success = (plugin_instance->*method)(header, args, arg_count, result);
- break;
- }
- }
-
- return success;
-}
-
-void ChromeFrameNPAPI::InitializeIdentifiers() {
- npapi::GetStringIdentifiers(plugin_method_identifier_names_,
- arraysize(plugin_methods_),
- plugin_method_identifiers_);
-
- npapi::GetStringIdentifiers(plugin_property_identifier_names_,
- PLUGIN_PROPERTY_COUNT,
- plugin_property_identifiers_);
-}
-
-NPObject* ChromeFrameNPAPI::AllocateObject(NPP instance, NPClass* class_name) {
- static bool identifiers_initialized = false;
-
- ChromeFrameNPObject* plugin_object = new ChromeFrameNPObject();
- DCHECK(plugin_object != NULL);
-
- plugin_object->chrome_frame_plugin_instance = new ChromeFrameNPAPI();
- DCHECK(plugin_object->chrome_frame_plugin_instance != NULL);
-
- plugin_object->npp = NULL;
-
- COMPILE_ASSERT(arraysize(plugin_method_identifiers_) ==
- arraysize(plugin_method_identifier_names_),
- method_count_mismatch);
-
- COMPILE_ASSERT(arraysize(plugin_method_identifiers_) ==
- arraysize(plugin_methods_),
- method_count_mismatch);
-
- if (!identifiers_initialized) {
- InitializeIdentifiers();
- identifiers_initialized = true;
- }
-
- return reinterpret_cast<NPObject*>(plugin_object);
-}
-
-void ChromeFrameNPAPI::DeallocateObject(NPObject* header) {
- ChromeFrameNPObject* plugin_object =
- reinterpret_cast<ChromeFrameNPObject*>(header);
- DCHECK(plugin_object != NULL);
-
- if (plugin_object) {
- delete plugin_object->chrome_frame_plugin_instance;
- delete plugin_object;
- }
-}
-
-void ChromeFrameNPAPI::Invalidate(NPObject* header) {
- DCHECK(header);
- ChromeFrameNPObject* plugin_object =
- reinterpret_cast<ChromeFrameNPObject*>(header);
- if (plugin_object) {
- DCHECK(plugin_object->chrome_frame_plugin_instance);
- plugin_object->chrome_frame_plugin_instance->Uninitialize();
- }
-}
-
-ChromeFrameNPAPI* ChromeFrameNPAPI::ChromeFrameInstanceFromPluginInstance(
- NPP instance) {
- if ((instance == NULL) || (instance->pdata == NULL)) {
- NOTREACHED();
- return NULL;
- }
-
- return ChromeFrameInstanceFromNPObject(instance->pdata);
-}
-
-ChromeFrameNPAPI* ChromeFrameNPAPI::ChromeFrameInstanceFromNPObject(
- void* object) {
- ChromeFrameNPObject* plugin_object =
- reinterpret_cast<ChromeFrameNPObject*>(object);
- if (!plugin_object) {
- NOTREACHED();
- return NULL;
- }
-
- DCHECK(plugin_object->chrome_frame_plugin_instance);
- return plugin_object->chrome_frame_plugin_instance;
-}
-
-bool ChromeFrameNPAPI::HasProperty(NPObject* obj, NPIdentifier name) {
- for (int i = 0; i < PLUGIN_PROPERTY_COUNT; ++i) {
- if (name == plugin_property_identifiers_[i])
- return true;
- }
- return false;
-}
-
-bool ChromeFrameNPAPI::GetProperty(NPIdentifier name,
- NPVariant* variant) {
- if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_ONERROR]) {
- if (onerror_handler_) {
- variant->type = NPVariantType_Object;
- variant->value.objectValue = onerror_handler_.Copy();
- return true;
- }
- } else if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_ONMESSAGE]) {
- if (onmessage_handler_) {
- variant->type = NPVariantType_Object;
- variant->value.objectValue = onmessage_handler_.Copy();
- return true;
- }
- } else if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_ONCLOSE]) {
- if (onclose_handler_) {
- variant->type = NPVariantType_Object;
- variant->value.objectValue = onclose_handler_.Copy();
- return true;
- }
- } else if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_SRC]) {
- AllocateStringVariant(src_, variant);
- return true;
- } else if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_VERSION]) {
- const std::wstring version =
- automation_client_->GetVersion();
- AllocateStringVariant(WideToUTF8(version), variant);
- return true;
- } else if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_READYSTATE]) {
- INT32_TO_NPVARIANT(ready_state_, *variant);
- return true;
- } else if (name ==
- plugin_property_identifiers_[PLUGIN_PROPERTY_USECHROMENETWORK]) {
- BOOLEAN_TO_NPVARIANT(automation_client_->use_chrome_network(), *variant);
- return true;
- }
-
- return false;
-}
-
-bool ChromeFrameNPAPI::GetProperty(NPObject* object, NPIdentifier name,
- NPVariant* variant) {
- if (!object || !variant) {
- NOTREACHED();
- return false;
- }
-
- ChromeFrameNPAPI* plugin_instance = ChromeFrameInstanceFromNPObject(object);
- if (!plugin_instance) {
- NOTREACHED();
- return false;
- }
-
- return plugin_instance->GetProperty(name, variant);
-}
-
-bool ChromeFrameNPAPI::SetProperty(NPIdentifier name,
- const NPVariant* variant) {
- if (NPVARIANT_IS_OBJECT(*variant)) {
- if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_ONERROR]) {
- onerror_handler_.Free();
- onerror_handler_ = variant->value.objectValue;
- return true;
- } else if (
- name == plugin_property_identifiers_[PLUGIN_PROPERTY_ONMESSAGE]) {
- onmessage_handler_.Free();
- onmessage_handler_ = variant->value.objectValue;
- return true;
- } else if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_ONCLOSE]) {
- onclose_handler_.Free();
- onclose_handler_ = variant->value.objectValue;
- return true;
- }
- } else if (NPVARIANT_IS_STRING(*variant) || NPVARIANT_IS_NULL(*variant)) {
- if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_SRC]) {
- return NavigateToURL(variant, 1, NULL);
- }
- } else if (NPVARIANT_IS_BOOLEAN(*variant)) {
- if (name ==
- plugin_property_identifiers_[PLUGIN_PROPERTY_USECHROMENETWORK]) {
- automation_client_->set_use_chrome_network(
- NPVARIANT_TO_BOOLEAN(*variant));
- }
- }
-
- return false;
-}
-
-bool ChromeFrameNPAPI::SetProperty(NPObject* object, NPIdentifier name,
- const NPVariant* variant) {
- if (!object || !variant) {
- DLOG(ERROR) << "Cannot set property: " << npapi::StringFromIdentifier(name);
- return false;
- }
-
- ChromeFrameNPAPI* plugin_instance = ChromeFrameInstanceFromNPObject(object);
- if (!plugin_instance) {
- NOTREACHED();
- return false;
- }
-
- return plugin_instance->SetProperty(name, variant);
-}
-
-LRESULT CALLBACK ChromeFrameNPAPI::DropKillFocusHook(int code, WPARAM wparam,
- LPARAM lparam) {
- LRESULT ret = 0;
- CWPSTRUCT* wp = reinterpret_cast<CWPSTRUCT*>(lparam);
- if ((code < 0) || (wp->message != WM_KILLFOCUS))
- ret = ::CallNextHookEx(NULL, code, wparam, lparam);
-
- return ret;
-}
-
-LRESULT ChromeFrameNPAPI::OnSetFocus(UINT message, WPARAM wparam,
- LPARAM lparam, BOOL& handled) { // NO_LINT
- // Opera has a WH_CALLWNDPROC hook that handles WM_KILLFOCUS and
- // prevents us from setting the focus to the tab.
- // To work around that, we set a temporary hook here that does nothing
- // (not even call other hooks) when it sees WM_KILLFOCUS.
- HHOOK hook = NULL;
- hook = ::SetWindowsHookEx(WH_CALLWNDPROC, DropKillFocusHook, NULL,
- ::GetCurrentThreadId());
- // Since we chain message maps, make sure we are not calling base class
- // twice for WM_SETFOCUS.
- BOOL handled_by_base = TRUE;
- LRESULT ret = Base::OnSetFocus(message, wparam, lparam, handled_by_base);
- if (hook)
- ::UnhookWindowsHookEx(hook);
-
- return ret;
-}
-
-void ChromeFrameNPAPI::OnLoad(const GURL& gurl) {
- DVLOG(1) << "Firing onload";
- FireEvent("load", gurl.spec());
-}
-
-void ChromeFrameNPAPI::OnLoadFailed(int error_code, const std::string& url) {
- FireEvent("loaderror", url);
-
- ScopedNpVariant result;
- InvokeDefault(onerror_handler_, url, &result);
-}
-
-void ChromeFrameNPAPI::OnMessageFromChromeFrame(const std::string& message,
- const std::string& origin,
- const std::string& target) {
- bool private_message = false;
- if (target.compare("*") != 0) {
- if (is_privileged()) {
- private_message = true;
- } else {
- if (!HaveSameOrigin(target, document_url_)) {
- DLOG(WARNING) << "Dropping posted message since target doesn't match "
- "the current document's origin. target=" << target;
- return;
- }
- }
- }
-
- // Create a MessageEvent object that contains the message and origin
- // as well as supporting other MessageEvent (see the HTML5 spec) properties.
- // Then call the onmessage handler.
- ScopedNpObject<NPObject> event;
- bool ok = CreateMessageEvent(false, true, message, origin, event.Receive());
- if (ok) {
- // Don't call FireEvent here (or we'll have an event wrapped by an event).
- DispatchEvent(event);
-
- ScopedNpVariant result;
- NPVariant params[2];
- OBJECT_TO_NPVARIANT(event, params[0]);
- bool invoke = false;
- if (private_message) {
- DCHECK(is_privileged());
- STRINGN_TO_NPVARIANT(target.c_str(), target.length(), params[1]);
- invoke = InvokeDefault(onprivatemessage_handler_,
- arraysize(params),
- params,
- &result);
- } else {
- invoke = InvokeDefault(onmessage_handler_, params[0], &result);
- }
- DLOG_IF(WARNING, !invoke) << "InvokeDefault failed";
- } else {
- DLOG(WARNING) << "CreateMessageEvent failed, probably exiting";
- }
-}
-
-void ChromeFrameNPAPI::OnAutomationServerReady() {
- Base::OnAutomationServerReady();
-
- if (navigate_after_initialization_ && !src_.empty()) {
- navigate_after_initialization_ = false;
- if (!automation_client_->InitiateNavigation(src_,
- GetDocumentUrl(),
- this)) {
- DLOG(ERROR) << "Failed to navigate to: " << src_;
- src_.clear();
- }
- }
-
- SetReadyState(READYSTATE_COMPLETE);
-}
-
-void ChromeFrameNPAPI::OnAutomationServerLaunchFailed(
- AutomationLaunchResult reason, const std::string& server_version) {
- SetReadyState(READYSTATE_UNINITIALIZED);
-
- // In IE, we don't display warnings for privileged CF instances because
- // there are 2 CFs created for each tab (so we decide on the CEEE side
- // whether to show a warning). In FF however, there is only one privileged
- // CF instance per Firefox window, so OK to show the warning there without
- // any further logic.
- if (reason == AUTOMATION_VERSION_MISMATCH) {
- UMA_HISTOGRAM_COUNTS("ChromeFrame.VersionMismatchDisplayed", 1);
- DisplayVersionMismatchWarning(m_hWnd, server_version);
- }
-}
-
-void ChromeFrameNPAPI::OnCloseTab() {
- std::string arg;
- FireEvent("close", arg);
- ScopedNpVariant result;
- InvokeDefault(onclose_handler_, arg, &result);
-}
-
-bool ChromeFrameNPAPI::InvokeDefault(NPObject* object,
- unsigned param_count,
- const NPVariant* params,
- NPVariant* result) {
- if (!object)
- return false;
-
- bool ret = npapi::InvokeDefault(instance_, object, params, param_count,
- result);
- // InvokeDefault can return false in FF even though we do see the call
- // go through. It's not clear to me what the circumstances are, so
- // we log it as a warning while tracking it down.
- DLOG_IF(WARNING, !ret) << "npapi::InvokeDefault failed";
- return ret;
-}
-
-bool ChromeFrameNPAPI::InvokeDefault(NPObject* object, const std::string& param,
- NPVariant* result) {
- NPVariant arg;
- STRINGN_TO_NPVARIANT(param.c_str(), param.length(), arg);
- return InvokeDefault(object, arg, result);
-}
-
-bool ChromeFrameNPAPI::InvokeDefault(NPObject* object, const NPVariant& param,
- NPVariant* result) {
- return InvokeDefault(object, 1, &param, result);
-}
-
-bool ChromeFrameNPAPI::CreateEvent(const std::string& type, bool bubbles,
- bool cancelable, NPObject** basic_event) {
- DCHECK(basic_event);
- NPObject* window = GetWindowObject();
- if (!window) {
- // Can fail if the browser is closing (seen in Opera).
- return false;
- }
-
- const char* identifier_names[] = {
- "document",
- "createEvent",
- "initEvent",
- };
-
- NPIdentifier identifiers[arraysize(identifier_names)];
- npapi::GetStringIdentifiers(identifier_names, arraysize(identifier_names),
- identifiers);
-
- // Fetch the document object from the window.
- ScopedNpVariant document;
- bool ok = npapi::GetProperty(instance_, window, identifiers[0], &document);
- if (!ok) {
- // This could happen if the page is being unloaded.
- DLOG(WARNING) << "Failed to fetch the document object";
- return false;
- }
-
- bool success = false;
- if (ok && NPVARIANT_IS_OBJECT(document)) {
- // Call document.createEvent("Event") to create a basic event object.
- NPVariant event_type;
- STRINGN_TO_NPVARIANT("Event", sizeof("Event") - 1, event_type);
- ScopedNpVariant result;
- success = npapi::Invoke(instance_, NPVARIANT_TO_OBJECT(document),
- identifiers[1], &event_type, 1, &result);
- if (!NPVARIANT_IS_OBJECT(result)) {
- DLOG(WARNING) << "Failed to invoke createEvent";
- success = false;
- } else {
- NPVariant init_args[3];
- STRINGN_TO_NPVARIANT(type.c_str(), type.length(), init_args[0]);
- BOOLEAN_TO_NPVARIANT(bubbles, init_args[1]);
- BOOLEAN_TO_NPVARIANT(cancelable, init_args[2]);
-
- // Now initialize the event object by calling
- // event.initEvent(type, bubbles, cancelable);
- ScopedNpVariant init_results;
- ok = npapi::Invoke(instance_, NPVARIANT_TO_OBJECT(result), identifiers[2],
- init_args, arraysize(init_args), &init_results);
- if (ok) {
- success = true;
- // Finally, pass the ownership to the caller.
- *basic_event = NPVARIANT_TO_OBJECT(result);
- VOID_TO_NPVARIANT(result); // Prevent the object from being released.
- } else {
- DLOG(ERROR) << "initEvent failed";
- success = false;
- }
- }
- }
-
- return success;
-}
-
-bool ChromeFrameNPAPI::CreateMessageEvent(bool bubbles, bool cancelable,
- const std::string& data,
- const std::string& origin,
- NPObject** message_event) {
- DCHECK(message_event);
- ScopedNpObject<NPObject> event;
- bool ok = CreateEvent("message", false, true, event.Receive());
- if (ok) {
- typedef enum {
- DATA,
- ORIGIN,
- LAST_EVENT_ID,
- SOURCE,
- MESSAGE_PORT,
- IDENTIFIER_COUNT, // Must be last.
- } StringIdentifiers;
-
- static NPIdentifier identifiers[IDENTIFIER_COUNT] = {0};
- if (!identifiers[0]) {
- const NPUTF8* identifier_names[] = {
- "data",
- "origin",
- "lastEventId",
- "source",
- "messagePort",
- };
- COMPILE_ASSERT(arraysize(identifier_names) == arraysize(identifiers),
- mismatched_array_size);
- npapi::GetStringIdentifiers(identifier_names, IDENTIFIER_COUNT,
- identifiers);
- }
-
- NPVariant arg;
- STRINGN_TO_NPVARIANT(data.c_str(), data.length(), arg);
- npapi::SetProperty(instance_, event, identifiers[DATA], &arg);
- STRINGN_TO_NPVARIANT(origin.c_str(), origin.length(), arg);
- npapi::SetProperty(instance_, event, identifiers[ORIGIN], &arg);
- STRINGN_TO_NPVARIANT("", 0, arg);
- npapi::SetProperty(instance_, event, identifiers[LAST_EVENT_ID], &arg);
- NULL_TO_NPVARIANT(arg);
- npapi::SetProperty(instance_, event, identifiers[SOURCE], &arg);
- npapi::SetProperty(instance_, event, identifiers[MESSAGE_PORT], &arg);
- *message_event = event.Detach();
- }
-
- return ok;
-}
-
-
-void ChromeFrameNPAPI::DispatchEvent(NPObject* event) {
- DCHECK(event != NULL);
-
- ScopedNpObject<NPObject> embed;
- npapi::GetValue(instance_, NPNVPluginElementNPObject, &embed);
- if (embed != NULL) {
- NPVariant param;
- OBJECT_TO_NPVARIANT(event, param);
- ScopedNpVariant result;
- bool invoke = npapi::Invoke(instance_, embed,
- npapi::GetStringIdentifier("dispatchEvent"), &param, 1, &result);
- DLOG_IF(WARNING, !invoke) << "dispatchEvent failed";
- } else {
- DLOG(WARNING) << "ChromeFrameNPAPI::DispatchEvent failed, probably exiting";
- }
-}
-
-bool ChromeFrameNPAPI::ExecuteScript(const std::string& script,
- NPVariant* result) {
- NPObject* window = GetWindowObject();
- if (!window) {
- NOTREACHED();
- return false;
- }
-
- NPString script_for_execution;
- script_for_execution.UTF8Characters = script.c_str();
- script_for_execution.UTF8Length = script.length();
-
- return npapi::Evaluate(instance_, window, &script_for_execution, result);
-}
-
-NPObject* ChromeFrameNPAPI::JavascriptToNPObject(const std::string& script) {
- // Convert the passed in script to an invocable NPObject
- // To achieve this we save away the function in a dummy window property
- // which is then read to get the script object representing the function.
-
- std::string script_code =
- "javascript:window.__cf_get_function_object =";
-
- // If we are able to look up the name in the javascript namespace, then it
- // means that the caller passed in a function name. Convert the function
- // name to a NPObject we can invoke on.
- if (IsValidJavascriptFunction(script)) {
- script_code += script;
- } else {
- script_code += "new Function(\"";
- script_code += script;
- script_code += "\");";
- }
-
- NPVariant result;
- if (!ExecuteScript(script_code, &result)) {
- NOTREACHED();
- return NULL;
- }
-
- DCHECK(result.type == NPVariantType_Object);
- DCHECK(result.value.objectValue != NULL);
- return result.value.objectValue;
-}
-
-bool ChromeFrameNPAPI::IsValidJavascriptFunction(const std::string& script) {
- std::string script_code = "javascript:window['";
- script_code += script;
- script_code += "'];";
-
- ScopedNpVariant result;
- if (!ExecuteScript(script_code, &result)) {
- NOTREACHED();
- return NULL;
- }
-
- return result.type == NPVariantType_Object;
-}
-
-bool ChromeFrameNPAPI::NavigateToURL(const NPVariant* args, uint32_t arg_count,
- NPVariant* result) {
- // Note that 'result' might be NULL.
- if (arg_count != 1 || !(NPVARIANT_IS_STRING(args[0]) ||
- NPVARIANT_IS_NULL(args[0]))) {
- NOTREACHED();
- return false;
- }
-
- if (ready_state_ == READYSTATE_UNINITIALIZED) {
- // Error(L"Chrome Frame failed to initialize.");
- // TODO(tommi): call NPN_SetException
- DLOG(WARNING) << "NavigateToURL called after failed initialization";
- return false;
- }
-
- std::string url("about:blank");
- if (!NPVARIANT_IS_NULL(args[0])) {
- const NPString& str = args[0].value.stringValue;
- if (str.UTF8Length) {
- url.assign(std::string(str.UTF8Characters, str.UTF8Length));
- }
- }
-
- GURL document_url(GetDocumentUrl());
- if (document_url.SchemeIsSecure()) {
- GURL source_url(url);
- if (!source_url.SchemeIsSecure()) {
- DLOG(WARNING) << __FUNCTION__ << " Prevnting navigation to HTTP url"
- " since the containing document is HTTPS. URL: " << source_url <<
- " Document URL: " << document_url;
- return false;
- }
- }
-
- std::string full_url = ResolveURL(GetDocumentUrl(), url);
-
- src_ = full_url;
- // Navigate only if we completed initialization i.e. proxy is set etc.
- if (ready_state_ == READYSTATE_COMPLETE) {
- if (!automation_client_->InitiateNavigation(full_url,
- GetDocumentUrl(),
- this)) {
- // TODO(tommi): call NPN_SetException.
- src_.clear();
- return false;
- }
- } else {
- navigate_after_initialization_ = true;
- }
- return true;
-}
-
-bool ChromeFrameNPAPI::postMessage(NPObject* npobject, const NPVariant* args,
- uint32_t arg_count, NPVariant* result) {
- // TODO(tommi) See if we can factor these checks out somehow.
- if (arg_count < 1 || arg_count > 2 || !NPVARIANT_IS_STRING(args[0])) {
- NOTREACHED();
- return false;
- }
-
- const NPString& str = args[0].value.stringValue;
- std::string message(str.UTF8Characters, str.UTF8Length);
- std::string target;
- if (arg_count == 2 && NPVARIANT_IS_STRING(args[1])) {
- const NPString& str = args[1].value.stringValue;
- target.assign(str.UTF8Characters, str.UTF8Length);
- if (target.compare("*") != 0) {
- GURL resolved(target);
- if (!resolved.is_valid()) {
- npapi::SetException(npobject,
- "Unable to parse the specified target URL.");
- return false;
- }
- target = resolved.spec();
- }
- } else {
- target = "*";
- }
-
- GURL url(GURL(document_url_).GetOrigin());
- std::string origin(url.is_empty() ? "null" : url.spec());
-
- automation_client_->ForwardMessageFromExternalHost(message, origin, target);
-
- return true;
-}
-
-void ChromeFrameNPAPI::FireEvent(const std::string& event_type,
- const std::string& data) {
- NPVariant arg;
- STRINGN_TO_NPVARIANT(data.c_str(), data.length(), arg);
- FireEvent(event_type, arg);
-}
-
-void ChromeFrameNPAPI::FireEvent(const std::string& event_type,
- const NPVariant& data) {
- // Check that we're not bundling an event inside an event.
- // Right now we're only expecting simple types for the data argument.
- DCHECK(NPVARIANT_IS_OBJECT(data) == false);
-
- ScopedNpObject<NPObject> ev;
- CreateEvent(event_type, false, false, ev.Receive());
- if (ev) {
- // Add the 'data' member to the event.
- bool set = npapi::SetProperty(instance_, ev,
- npapi::GetStringIdentifier("data"), const_cast<NPVariant*>(&data));
- DCHECK(set);
- DispatchEvent(ev);
- }
-}
-
-NPObject* ChromeFrameNPAPI::GetWindowObject() const {
- if (!window_object_.get() && instance_) {
- NPError ret = npapi::GetValue(instance_, NPNVWindowNPObject,
- window_object_.Receive());
- DLOG_IF(ERROR, ret != NPERR_NO_ERROR) << "NPNVWindowNPObject failed";
- }
- return window_object_;
-}
-
-bool ChromeFrameNPAPI::GetBrowserIncognitoMode() {
- bool incognito_mode = false;
-
- // Check disabled for Opera due to bug:
- // http://code.google.com/p/chromium/issues/detail?id=24287
- if (GetBrowserType() != BROWSER_OPERA) {
- // Check whether host browser is in private mode;
- NPBool private_mode = FALSE;
- NPError err = npapi::GetValue(instance_,
- NPNVprivateModeBool,
- &private_mode);
- if (err == NPERR_NO_ERROR && private_mode) {
- incognito_mode = true;
- }
- } else {
- DLOG(WARNING) << "Not checking for private mode in Opera";
- }
-
- return incognito_mode;
-}
-
-bool ChromeFrameNPAPI::PreProcessContextMenu(HMENU menu) {
- // TODO: Remove this overridden method once HandleContextMenuCommand
- // implements "About Chrome Frame" handling.
- if (!is_privileged()) {
- // Call base class (adds 'About' item).
- return ChromeFramePlugin::PreProcessContextMenu(menu);
- }
- return true;
-}
-
-bool ChromeFrameNPAPI::HandleContextMenuCommand(
- UINT cmd, const MiniContextMenuParams& params) {
- if (cmd == IDC_ABOUT_CHROME_FRAME) {
- // TODO: implement "About Chrome Frame"
- }
- return false;
-}
-
-NPError ChromeFrameNPAPI::NewStream(NPMIMEType type, NPStream* stream,
- NPBool seekable, uint16* stream_type) {
- return url_fetcher_.NewStream(type, stream, seekable, stream_type);
-}
-
-int32 ChromeFrameNPAPI::WriteReady(NPStream* stream) {
- return url_fetcher_.WriteReady(stream);
-}
-
-int32 ChromeFrameNPAPI::Write(NPStream* stream, int32 offset, int32 len,
- void* buffer) {
- return url_fetcher_.Write(stream, offset, len, buffer);
-}
-
-NPError ChromeFrameNPAPI::DestroyStream(NPStream* stream, NPReason reason) {
- return url_fetcher_.DestroyStream(stream, reason);
-}
-
-void ChromeFrameNPAPI::URLRedirectNotify(const char* url, int status,
- void* notify_data) {
- DVLOG(1) << __FUNCTION__
- << "Received redirect notification for url:"
- << url;
- // Inform chrome about the redirect and disallow the current redirect
- // attempt.
- url_fetcher_.UrlRedirectNotify(url, status, notify_data);
- npapi::URLRedirectResponse(instance_, notify_data, false);
-}
« no previous file with comments | « chrome_frame/chrome_frame_npapi.h ('k') | chrome_frame/chrome_frame_npapi_entrypoints.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698