| Index: remoting/host/host_plugin.cc
|
| diff --git a/remoting/host/host_plugin.cc b/remoting/host/host_plugin.cc
|
| index 8f8ae28c787cc27269f6389b61ca19d2ac1cd71b..5c0e3873070f579c40daf8a1b507114879e33838 100644
|
| --- a/remoting/host/host_plugin.cc
|
| +++ b/remoting/host/host_plugin.cc
|
| @@ -9,28 +9,11 @@
|
| #include <vector>
|
|
|
| #include "base/at_exit.h"
|
| -#include "base/base_paths.h"
|
| #include "base/basictypes.h"
|
| -#include "base/bind.h"
|
| -#include "base/file_path.h"
|
| #include "base/logging.h"
|
| -#include "base/message_loop.h"
|
| -#include "base/path_service.h"
|
| -#include "base/rand_util.h"
|
| #include "base/stringize_macros.h"
|
| -#include "base/task.h"
|
| -#include "base/threading/platform_thread.h"
|
| -#include "base/threading/thread.h"
|
| -#include "base/synchronization/cancellation_flag.h"
|
| -#include "remoting/base/auth_token_util.h"
|
| -#include "remoting/host/chromoting_host.h"
|
| -#include "remoting/host/chromoting_host_context.h"
|
| -#include "remoting/host/host_config.h"
|
| -#include "remoting/host/host_key_pair.h"
|
| -#include "remoting/host/host_status_observer.h"
|
| -#include "remoting/host/in_memory_host_config.h"
|
| -#include "remoting/host/register_support_host_request.h"
|
| -#include "remoting/host/support_access_verifier.h"
|
| +#include "remoting/host/host_plugin_utils.h"
|
| +#include "remoting/host/host_script_object.h"
|
| #include "third_party/npapi/bindings/npapi.h"
|
| #include "third_party/npapi/bindings/npfunctions.h"
|
| #include "third_party/npapi/bindings/npruntime.h"
|
| @@ -58,51 +41,12 @@ uint64_t __cdecl __udivdi3(uint64_t a, uint64_t b) {
|
| }
|
| #endif
|
|
|
| -// Supported Javascript interface:
|
| -// readonly attribute string accessCode;
|
| -// readonly attribute int state;
|
| -//
|
| -// state: {
|
| -// DISCONNECTED,
|
| -// REQUESTED_ACCESS_CODE,
|
| -// RECEIVED_ACCESS_CODE,
|
| -// CONNECTED,
|
| -// AFFIRMING_CONNECTION,
|
| -// ERROR,
|
| -// }
|
| -//
|
| -// attribute Function void logDebugInfo(string);
|
| -// attribute Function void onStateChanged();
|
| -//
|
| -// // The |auth_service_with_token| parameter should be in the format
|
| -// // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd".
|
| -// void connect(string uid, string auth_service_with_token);
|
| -// void disconnect();
|
| -
|
| +using remoting::g_npnetscape_funcs;
|
| +using remoting::HostNPScriptObject;
|
| +using remoting::StringFromNPIdentifier;
|
|
|
| namespace {
|
|
|
| -const char* kAttrNameAccessCode = "accessCode";
|
| -const char* kAttrNameState = "state";
|
| -const char* kAttrNameLogDebugInfo = "logDebugInfo";
|
| -const char* kAttrNameOnStateChanged = "onStateChanged";
|
| -const char* kFuncNameConnect = "connect";
|
| -const char* kFuncNameDisconnect = "disconnect";
|
| -
|
| -// States.
|
| -const char* kAttrNameDisconnected = "DISCONNECTED";
|
| -const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE";
|
| -const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE";
|
| -const char* kAttrNameConnected = "CONNECTED";
|
| -const char* kAttrNameAffirmingConnection = "AFFIRMING_CONNECTION";
|
| -const char* kAttrNameError = "ERROR";
|
| -
|
| -const int kMaxLoginAttempts = 5;
|
| -
|
| -// Global netscape functions initialized in NP_Initialize.
|
| -NPNetscapeFuncs* g_npnetscape_funcs = NULL;
|
| -
|
| -// Global AtExitManager, created in NP_Initialize and destroyed in NP_Shutdown.
|
| base::AtExitManager* g_at_exit_manager = NULL;
|
|
|
| // The name and description are returned by GetValue, but are also
|
| @@ -111,582 +55,6 @@ base::AtExitManager* g_at_exit_manager = NULL;
|
| #define HOST_PLUGIN_NAME "Remoting Host Plugin"
|
| #define HOST_PLUGIN_DESCRIPTION "Remoting Host Plugin"
|
|
|
| -// Convert an NPIdentifier into a std::string.
|
| -std::string StringFromNPIdentifier(NPIdentifier identifier) {
|
| - if (!g_npnetscape_funcs->identifierisstring(identifier))
|
| - return std::string();
|
| - NPUTF8* np_string = g_npnetscape_funcs->utf8fromidentifier(identifier);
|
| - std::string string(np_string);
|
| - g_npnetscape_funcs->memfree(np_string);
|
| - return string;
|
| -}
|
| -
|
| -// Convert an NPVariant into a std::string.
|
| -std::string StringFromNPVariant(const NPVariant& variant) {
|
| - if (!NPVARIANT_IS_STRING(variant))
|
| - return std::string();
|
| - const NPString& np_string = NPVARIANT_TO_STRING(variant);
|
| - return std::string(np_string.UTF8Characters, np_string.UTF8Length);
|
| -}
|
| -
|
| -// Convert a std::string into an NPVariant.
|
| -// Caller is responsible for making sure that NPN_ReleaseVariantValue is
|
| -// called on returned value.
|
| -NPVariant NPVariantFromString(const std::string& val) {
|
| - size_t len = val.length();
|
| - NPUTF8* chars =
|
| - reinterpret_cast<NPUTF8*>(g_npnetscape_funcs->memalloc(len + 1));
|
| - strcpy(chars, val.c_str());
|
| - NPVariant variant;
|
| - STRINGN_TO_NPVARIANT(chars, len, variant);
|
| - return variant;
|
| -}
|
| -
|
| -// Convert an NPVariant into an NSPObject.
|
| -NPObject* ObjectFromNPVariant(const NPVariant& variant) {
|
| - if (!NPVARIANT_IS_OBJECT(variant))
|
| - return NULL;
|
| - return NPVARIANT_TO_OBJECT(variant);
|
| -}
|
| -
|
| -// NPAPI plugin implementation for remoting host script object.
|
| -// HostNPScriptObject creates threads that are required to run
|
| -// ChromotingHost and starts/stops the host on those threads. When
|
| -// destroyed it sychronously shuts down the host and all threads.
|
| -class HostNPScriptObject : public remoting::HostStatusObserver {
|
| - public:
|
| - HostNPScriptObject(NPP plugin, NPObject* parent)
|
| - : plugin_(plugin),
|
| - parent_(parent),
|
| - state_(kDisconnected),
|
| - log_debug_info_func_(NULL),
|
| - on_state_changed_func_(NULL),
|
| - np_thread_id_(base::PlatformThread::CurrentId()),
|
| - failed_login_attempts_(0),
|
| - disconnected_event_(true, false) {
|
| - VLOG(2) << "HostNPScriptObject";
|
| - host_context_.SetUITaskPostFunction(base::Bind(
|
| - &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this)));
|
| - }
|
| -
|
| - ~HostNPScriptObject() {
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| -
|
| - // Disconnect synchronously. We cannot disconnect asynchronously
|
| - // here because |host_context_| needs to be stopped on the plugin
|
| - // thread, but the plugin thread may not exist after the instance
|
| - // is destroyed.
|
| - destructing_.Set();
|
| - disconnected_event_.Reset();
|
| - DisconnectInternal();
|
| - disconnected_event_.Wait();
|
| -
|
| - host_context_.Stop();
|
| - if (log_debug_info_func_) {
|
| - g_npnetscape_funcs->releaseobject(log_debug_info_func_);
|
| - }
|
| - if (on_state_changed_func_) {
|
| - g_npnetscape_funcs->releaseobject(on_state_changed_func_);
|
| - }
|
| - }
|
| -
|
| - bool Init() {
|
| - VLOG(2) << "Init";
|
| - // TODO(wez): This starts a bunch of threads, which might fail.
|
| - host_context_.Start();
|
| - return true;
|
| - }
|
| -
|
| - bool HasMethod(const std::string& method_name) {
|
| - VLOG(2) << "HasMethod " << method_name;
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| - return (method_name == kFuncNameConnect ||
|
| - method_name == kFuncNameDisconnect);
|
| - }
|
| -
|
| - bool InvokeDefault(const NPVariant* args,
|
| - uint32_t argCount,
|
| - NPVariant* result) {
|
| - VLOG(2) << "InvokeDefault";
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| - SetException("exception during default invocation");
|
| - return false;
|
| - }
|
| -
|
| - bool Invoke(const std::string& method_name,
|
| - const NPVariant* args,
|
| - uint32_t argCount,
|
| - NPVariant* result) {
|
| - VLOG(2) << "Invoke " << method_name;
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| - if (method_name == kFuncNameConnect) {
|
| - return Connect(args, argCount, result);
|
| - } else if (method_name == kFuncNameDisconnect) {
|
| - return Disconnect(args, argCount, result);
|
| - } else {
|
| - SetException("Invoke: unknown method " + method_name);
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - bool HasProperty(const std::string& property_name) {
|
| - VLOG(2) << "HasProperty " << property_name;
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| - return (property_name == kAttrNameAccessCode ||
|
| - property_name == kAttrNameState ||
|
| - property_name == kAttrNameLogDebugInfo ||
|
| - property_name == kAttrNameOnStateChanged ||
|
| - property_name == kAttrNameDisconnected ||
|
| - property_name == kAttrNameRequestedAccessCode ||
|
| - property_name == kAttrNameReceivedAccessCode ||
|
| - property_name == kAttrNameConnected ||
|
| - property_name == kAttrNameAffirmingConnection ||
|
| - property_name == kAttrNameError);
|
| - }
|
| -
|
| - bool GetProperty(const std::string& property_name, NPVariant* result) {
|
| - VLOG(2) << "GetProperty " << property_name;
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| - if (!result) {
|
| - SetException("GetProperty: NULL result");
|
| - return false;
|
| - }
|
| -
|
| - if (property_name == kAttrNameOnStateChanged) {
|
| - OBJECT_TO_NPVARIANT(on_state_changed_func_, *result);
|
| - return true;
|
| - } else if (property_name == kAttrNameLogDebugInfo) {
|
| - OBJECT_TO_NPVARIANT(log_debug_info_func_, *result);
|
| - return true;
|
| - } else if (property_name == kAttrNameState) {
|
| - INT32_TO_NPVARIANT(state_, *result);
|
| - return true;
|
| - } else if (property_name == kAttrNameAccessCode) {
|
| - *result = NPVariantFromString(access_code_);
|
| - return true;
|
| - } else if (property_name == kAttrNameDisconnected) {
|
| - INT32_TO_NPVARIANT(kDisconnected, *result);
|
| - return true;
|
| - } else if (property_name == kAttrNameRequestedAccessCode) {
|
| - INT32_TO_NPVARIANT(kRequestedAccessCode, *result);
|
| - return true;
|
| - } else if (property_name == kAttrNameReceivedAccessCode) {
|
| - INT32_TO_NPVARIANT(kReceivedAccessCode, *result);
|
| - return true;
|
| - } else if (property_name == kAttrNameConnected) {
|
| - INT32_TO_NPVARIANT(kConnected, *result);
|
| - return true;
|
| - } else if (property_name == kAttrNameAffirmingConnection) {
|
| - INT32_TO_NPVARIANT(kAffirmingConnection, *result);
|
| - return true;
|
| - } else if (property_name == kAttrNameError) {
|
| - INT32_TO_NPVARIANT(kError, *result);
|
| - return true;
|
| - } else {
|
| - SetException("GetProperty: unsupported property " + property_name);
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - bool SetProperty(const std::string& property_name, const NPVariant* value) {
|
| - VLOG(2) << "SetProperty " << property_name;
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| -
|
| - if (property_name == kAttrNameOnStateChanged) {
|
| - if (NPVARIANT_IS_OBJECT(*value)) {
|
| - if (on_state_changed_func_) {
|
| - g_npnetscape_funcs->releaseobject(on_state_changed_func_);
|
| - }
|
| - on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value);
|
| - if (on_state_changed_func_) {
|
| - g_npnetscape_funcs->retainobject(on_state_changed_func_);
|
| - }
|
| - return true;
|
| - } else {
|
| - SetException("SetProperty: unexpected type for property " +
|
| - property_name);
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - if (property_name == kAttrNameLogDebugInfo) {
|
| - if (NPVARIANT_IS_OBJECT(*value)) {
|
| - if (log_debug_info_func_) {
|
| - g_npnetscape_funcs->releaseobject(log_debug_info_func_);
|
| - }
|
| - log_debug_info_func_ = NPVARIANT_TO_OBJECT(*value);
|
| - if (log_debug_info_func_) {
|
| - g_npnetscape_funcs->retainobject(log_debug_info_func_);
|
| - }
|
| - return true;
|
| - } else {
|
| - SetException("SetProperty: unexpected type for property " +
|
| - property_name);
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - return false;
|
| - }
|
| -
|
| - bool RemoveProperty(const std::string& property_name) {
|
| - VLOG(2) << "RemoveProperty " << property_name;
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| - return false;
|
| - }
|
| -
|
| - bool Enumerate(std::vector<std::string>* values) {
|
| - VLOG(2) << "Enumerate";
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| - const char* entries[] = {
|
| - kAttrNameAccessCode,
|
| - kAttrNameState,
|
| - kAttrNameLogDebugInfo,
|
| - kAttrNameOnStateChanged,
|
| - kFuncNameConnect,
|
| - kFuncNameDisconnect,
|
| - kAttrNameDisconnected,
|
| - kAttrNameRequestedAccessCode,
|
| - kAttrNameReceivedAccessCode,
|
| - kAttrNameConnected,
|
| - kAttrNameAffirmingConnection,
|
| - kAttrNameError
|
| - };
|
| - for (size_t i = 0; i < arraysize(entries); ++i) {
|
| - values->push_back(entries[i]);
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - // remoting::HostStatusObserver implementation.
|
| - virtual void OnSignallingConnected(remoting::SignalStrategy* signal_strategy,
|
| - const std::string& full_jid) OVERRIDE {
|
| - OnStateChanged(kConnected);
|
| - }
|
| -
|
| - virtual void OnSignallingDisconnected() OVERRIDE {
|
| - }
|
| -
|
| - virtual void OnAccessDenied() OVERRIDE {
|
| - DCHECK_EQ(MessageLoop::current(), host_context_.network_message_loop());
|
| -
|
| - ++failed_login_attempts_;
|
| - if (failed_login_attempts_ == kMaxLoginAttempts)
|
| - DisconnectInternal();
|
| - }
|
| -
|
| - virtual void OnShutdown() OVERRIDE {
|
| - DCHECK_EQ(MessageLoop::current(), host_context_.main_message_loop());
|
| -
|
| - OnStateChanged(kDisconnected);
|
| - }
|
| -
|
| - private:
|
| - enum State {
|
| - kDisconnected,
|
| - kRequestedAccessCode,
|
| - kReceivedAccessCode,
|
| - kConnected,
|
| - kAffirmingConnection,
|
| - kError
|
| - };
|
| -
|
| - // Start connection. args are:
|
| - // string uid, string auth_token
|
| - // No result.
|
| - bool Connect(const NPVariant* args, uint32_t argCount, NPVariant* result);
|
| -
|
| - // Disconnect. No arguments or result.
|
| - bool Disconnect(const NPVariant* args, uint32_t argCount, NPVariant* result);
|
| -
|
| - // Call LogDebugInfo handler if there is one.
|
| - void LogDebugInfo(const std::string& message);
|
| -
|
| - // Call OnStateChanged handler if there is one.
|
| - void OnStateChanged(State state);
|
| -
|
| - // Callbacks invoked during session setup.
|
| - void OnReceivedSupportID(remoting::SupportAccessVerifier* access_verifier,
|
| - bool success,
|
| - const std::string& support_id);
|
| -
|
| - // Helper functions that run on main thread. Can be called on any
|
| - // other thread.
|
| - void ConnectInternal(const std::string& uid,
|
| - const std::string& auth_token,
|
| - const std::string& auth_service);
|
| - void DisconnectInternal();
|
| -
|
| - // Callback for ChromotingHost::Shutdown().
|
| - void OnShutdownFinished();
|
| -
|
| - // Call a JavaScript function wrapped as an NPObject.
|
| - // If result is non-null, the result of the call will be stored in it.
|
| - // Caller is responsible for releasing result if they ask for it.
|
| - static bool CallJSFunction(NPObject* func,
|
| - const NPVariant* args,
|
| - uint32_t argCount,
|
| - NPVariant* result);
|
| -
|
| - // Posts a task on the main NP thread.
|
| - void PostTaskToNPThread(const tracked_objects::Location& from_here,
|
| - Task* task);
|
| -
|
| - // Utility function for PostTaskToNPThread.
|
| - static void NPTaskSpringboard(void* task);
|
| -
|
| - // Set an exception for the current call.
|
| - void SetException(const std::string& exception_string);
|
| -
|
| - NPP plugin_;
|
| - NPObject* parent_;
|
| - int state_;
|
| - std::string access_code_;
|
| - NPObject* log_debug_info_func_;
|
| - NPObject* on_state_changed_func_;
|
| - base::PlatformThreadId np_thread_id_;
|
| -
|
| - scoped_ptr<remoting::RegisterSupportHostRequest> register_request_;
|
| - scoped_refptr<remoting::ChromotingHost> host_;
|
| - scoped_refptr<remoting::MutableHostConfig> host_config_;
|
| - remoting::ChromotingHostContext host_context_;
|
| - int failed_login_attempts_;
|
| -
|
| - base::WaitableEvent disconnected_event_;
|
| - base::CancellationFlag destructing_;
|
| -};
|
| -
|
| -// string uid, string auth_token
|
| -bool HostNPScriptObject::Connect(const NPVariant* args,
|
| - uint32_t arg_count,
|
| - NPVariant* result) {
|
| - LogDebugInfo("Connecting...");
|
| -
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| - if (arg_count != 2) {
|
| - SetException("connect: bad number of arguments");
|
| - return false;
|
| - }
|
| -
|
| - std::string uid = StringFromNPVariant(args[0]);
|
| - if (uid.empty()) {
|
| - SetException("connect: bad uid argument");
|
| - return false;
|
| - }
|
| -
|
| - std::string auth_service_with_token = StringFromNPVariant(args[1]);
|
| - std::string auth_token;
|
| - std::string auth_service;
|
| - remoting::ParseAuthTokenWithService(auth_service_with_token, &auth_token,
|
| - &auth_service);
|
| - if (auth_token.empty()) {
|
| - SetException("connect: auth_service_with_token argument has empty token");
|
| - return false;
|
| - }
|
| -
|
| - ConnectInternal(uid, auth_token, auth_service);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void HostNPScriptObject::ConnectInternal(
|
| - const std::string& uid,
|
| - const std::string& auth_token,
|
| - const std::string& auth_service) {
|
| - if (MessageLoop::current() != host_context_.main_message_loop()) {
|
| - host_context_.main_message_loop()->PostTask(
|
| - FROM_HERE,
|
| - NewRunnableMethod(this, &HostNPScriptObject::ConnectInternal,
|
| - uid, auth_token, auth_service));
|
| - return;
|
| - }
|
| - // Store the supplied user ID and token to the Host configuration.
|
| - scoped_refptr<remoting::MutableHostConfig> host_config =
|
| - new remoting::InMemoryHostConfig;
|
| - host_config->SetString(remoting::kXmppLoginConfigPath, uid);
|
| - host_config->SetString(remoting::kXmppAuthTokenConfigPath, auth_token);
|
| - host_config->SetString(remoting::kXmppAuthServiceConfigPath, auth_service);
|
| -
|
| - // Create an access verifier and fetch the host secret.
|
| - scoped_ptr<remoting::SupportAccessVerifier> access_verifier;
|
| - access_verifier.reset(new remoting::SupportAccessVerifier);
|
| -
|
| - // Generate a key pair for the Host to use.
|
| - // TODO(wez): Move this to the worker thread.
|
| - remoting::HostKeyPair host_key_pair;
|
| - host_key_pair.Generate();
|
| - host_key_pair.Save(host_config);
|
| -
|
| - // Request registration of the host for support.
|
| - scoped_ptr<remoting::RegisterSupportHostRequest> register_request(
|
| - new remoting::RegisterSupportHostRequest());
|
| - if (!register_request->Init(
|
| - host_config.get(),
|
| - base::Bind(&HostNPScriptObject::OnReceivedSupportID,
|
| - base::Unretained(this),
|
| - access_verifier.get()))) {
|
| - OnStateChanged(kDisconnected);
|
| - return;
|
| - }
|
| -
|
| - // Create the Host.
|
| - scoped_refptr<remoting::ChromotingHost> host =
|
| - remoting::ChromotingHost::Create(&host_context_, host_config,
|
| - access_verifier.release());
|
| - host->AddStatusObserver(this);
|
| - host->AddStatusObserver(register_request.get());
|
| - host->set_it2me(true);
|
| -
|
| - // Nothing went wrong, so lets save the host, config and request.
|
| - host_ = host;
|
| - host_config_ = host_config;
|
| - register_request_.reset(register_request.release());
|
| -
|
| - // Start the Host.
|
| - host_->Start();
|
| -
|
| - OnStateChanged(kRequestedAccessCode);
|
| - return;
|
| -}
|
| -
|
| -bool HostNPScriptObject::Disconnect(const NPVariant* args,
|
| - uint32_t arg_count,
|
| - NPVariant* result) {
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| - if (arg_count != 0) {
|
| - SetException("disconnect: bad number of arguments");
|
| - return false;
|
| - }
|
| -
|
| - DisconnectInternal();
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void HostNPScriptObject::DisconnectInternal() {
|
| - if (MessageLoop::current() != host_context_.main_message_loop()) {
|
| - host_context_.main_message_loop()->PostTask(
|
| - FROM_HERE,
|
| - NewRunnableMethod(this, &HostNPScriptObject::DisconnectInternal));
|
| - return;
|
| - }
|
| -
|
| - if (!host_) {
|
| - disconnected_event_.Signal();
|
| - return;
|
| - }
|
| -
|
| - host_->Shutdown(
|
| - NewRunnableMethod(this, &HostNPScriptObject::OnShutdownFinished));
|
| -}
|
| -
|
| -void HostNPScriptObject::OnShutdownFinished() {
|
| - DCHECK_EQ(MessageLoop::current(), host_context_.main_message_loop());
|
| -
|
| - host_ = NULL;
|
| - register_request_.reset();
|
| - host_config_ = NULL;
|
| - disconnected_event_.Signal();
|
| -}
|
| -
|
| -void HostNPScriptObject::OnReceivedSupportID(
|
| - remoting::SupportAccessVerifier* access_verifier,
|
| - bool success,
|
| - const std::string& support_id) {
|
| - CHECK_NE(base::PlatformThread::CurrentId(), np_thread_id_);
|
| -
|
| - if (!success) {
|
| - // TODO(wez): Replace the success/fail flag with full error reporting.
|
| - DisconnectInternal();
|
| - return;
|
| - }
|
| -
|
| - // Inform the AccessVerifier of our Support-Id, for authentication.
|
| - access_verifier->OnIT2MeHostRegistered(success, support_id);
|
| -
|
| - // Combine the Support Id with the Host Id to make the Access Code.
|
| - // TODO(wez): Locking, anyone?
|
| - access_code_ = support_id + "-" + access_verifier->host_secret();
|
| -
|
| - // Let the caller know that life is good.
|
| - OnStateChanged(kReceivedAccessCode);
|
| -}
|
| -
|
| -void HostNPScriptObject::OnStateChanged(State state) {
|
| - if (destructing_.IsSet()) {
|
| - return;
|
| - }
|
| -
|
| - if (!host_context_.IsUIThread()) {
|
| - host_context_.PostToUIThread(
|
| - FROM_HERE,
|
| - NewRunnableMethod(this, &HostNPScriptObject::OnStateChanged, state));
|
| - return;
|
| - }
|
| - state_ = state;
|
| - if (on_state_changed_func_) {
|
| - VLOG(2) << "Calling state changed " << state;
|
| - bool is_good = CallJSFunction(on_state_changed_func_, NULL, 0, NULL);
|
| - LOG_IF(ERROR, !is_good) << "OnStateChangedNP failed";
|
| - }
|
| -}
|
| -
|
| -void HostNPScriptObject::LogDebugInfo(const std::string& message) {
|
| - if (!host_context_.IsUIThread()) {
|
| - host_context_.PostToUIThread(
|
| - FROM_HERE,
|
| - NewRunnableMethod(this, &HostNPScriptObject::LogDebugInfo, message));
|
| - return;
|
| - }
|
| - if (log_debug_info_func_) {
|
| - NPVariant* arg = new NPVariant();
|
| - LOG(INFO) << "Logging: " << message;
|
| - STRINGZ_TO_NPVARIANT(message.c_str(), *arg);
|
| - bool is_good = CallJSFunction(log_debug_info_func_, arg, 1, NULL);
|
| - LOG_IF(ERROR, !is_good) << "LogDebugInfo failed";
|
| - }
|
| -}
|
| -
|
| -void HostNPScriptObject::SetException(const std::string& exception_string) {
|
| - CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
|
| - g_npnetscape_funcs->setexception(parent_, exception_string.c_str());
|
| - LogDebugInfo(exception_string);
|
| -}
|
| -
|
| -bool HostNPScriptObject::CallJSFunction(NPObject* func,
|
| - const NPVariant* args,
|
| - uint32_t argCount,
|
| - NPVariant* result) {
|
| - NPVariant np_result;
|
| - bool is_good = func->_class->invokeDefault(func, args, argCount, &np_result);
|
| - if (is_good) {
|
| - if (result) {
|
| - *result = np_result;
|
| - } else {
|
| - g_npnetscape_funcs->releasevariantvalue(&np_result);
|
| - }
|
| - }
|
| - return is_good;
|
| -}
|
| -
|
| -void HostNPScriptObject::PostTaskToNPThread(
|
| - const tracked_objects::Location& from_here, Task* task) {
|
| - // The NPAPI functions cannot make use of |from_here|, but this method is
|
| - // passed as a callback to ChromotingHostContext, so it needs to have the
|
| - // appropriate signature.
|
| -
|
| - // Can be called from any thread.
|
| - g_npnetscape_funcs->pluginthreadasynccall(plugin_,
|
| - &NPTaskSpringboard,
|
| - task);
|
| -}
|
| -
|
| -void HostNPScriptObject::NPTaskSpringboard(void* task) {
|
| - Task* real_task = reinterpret_cast<Task*>(task);
|
| - real_task->Run();
|
| - delete real_task;
|
| -}
|
| -
|
| // NPAPI plugin implementation for remoting host.
|
| // Documentation for most of the calls in this class can be found here:
|
| // https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins
|
| @@ -1004,8 +372,6 @@ NPError SetWindow(NPP instance, NPWindow* pNPWindow) {
|
|
|
| } // namespace
|
|
|
| -DISABLE_RUNNABLE_METHOD_REFCOUNT(HostNPScriptObject);
|
| -
|
| #if defined(OS_WIN)
|
| HMODULE g_hModule = NULL;
|
|
|
|
|