Home | History | Annotate | Download | only in plugin
      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 #ifndef REMOTING_HOST_PLUGIN_HOST_SCRIPT_OBJECT_H_
      6 #define REMOTING_HOST_PLUGIN_HOST_SCRIPT_OBJECT_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/compiler_specific.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "base/strings/string16.h"
     16 #include "base/synchronization/cancellation_flag.h"
     17 #include "base/synchronization/lock.h"
     18 #include "base/synchronization/waitable_event.h"
     19 #include "base/thread_task_runner_handle.h"
     20 #include "base/threading/platform_thread.h"
     21 #include "base/threading/thread.h"
     22 #include "base/time/time.h"
     23 #include "remoting/base/auto_thread_task_runner.h"
     24 #include "remoting/host/chromoting_host_context.h"
     25 #include "remoting/host/log_to_server.h"
     26 #include "remoting/host/plugin/host_plugin_utils.h"
     27 #include "remoting/host/setup/daemon_controller.h"
     28 #include "remoting/jingle_glue/xmpp_signal_strategy.h"
     29 #include "remoting/protocol/pairing_registry.h"
     30 #include "third_party/npapi/bindings/npapi.h"
     31 #include "third_party/npapi/bindings/npfunctions.h"
     32 #include "third_party/npapi/bindings/npruntime.h"
     33 
     34 namespace remoting {
     35 
     36 // NPAPI plugin implementation for remoting host script object.
     37 // HostNPScriptObject creates threads that are required to run
     38 // ChromotingHost and starts/stops the host on those threads. When
     39 // destroyed it synchronously shuts down the host and all threads.
     40 class HostNPScriptObject {
     41  public:
     42   HostNPScriptObject(NPP plugin,
     43                      NPObject* parent,
     44                      scoped_refptr<AutoThreadTaskRunner> plugin_task_runner);
     45   virtual ~HostNPScriptObject();
     46 
     47   // Implementations used to implement the NPObject interface.
     48   bool HasMethod(const std::string& method_name);
     49   bool InvokeDefault(const NPVariant* args,
     50                      uint32_t arg_count,
     51                      NPVariant* result);
     52   bool Invoke(const std::string& method_name,
     53               const NPVariant* args,
     54               uint32_t arg_count,
     55               NPVariant* result);
     56   bool HasProperty(const std::string& property_name);
     57   bool GetProperty(const std::string& property_name, NPVariant* result);
     58   bool SetProperty(const std::string& property_name, const NPVariant* value);
     59   bool RemoveProperty(const std::string& property_name);
     60   bool Enumerate(std::vector<std::string>* values);
     61 
     62   // Post LogDebugInfo to the correct proxy (and thus, on the correct thread).
     63   // This should only be called by HostLogHandler. To log to the UI, use the
     64   // standard LOG(INFO) and it will be sent to this method.
     65   void PostLogDebugInfo(const std::string& message);
     66 
     67   void SetWindow(NPWindow* np_window);
     68 
     69  private:
     70   //////////////////////////////////////////////////////////
     71   // Definitions for It2Me host.
     72 
     73   class It2MeImpl;
     74 
     75   // These state values are duplicated in host_session.js. Remember to update
     76   // both copies when making changes.
     77   enum State {
     78     kDisconnected,
     79     kStarting,
     80     kRequestedAccessCode,
     81     kReceivedAccessCode,
     82     kConnected,
     83     kDisconnecting,
     84     kError,
     85     kInvalidDomainError
     86   };
     87 
     88   //////////////////////////////////////////////////////////
     89   // Plugin methods for It2Me host.
     90 
     91   // Start connection. args are:
     92   //   string uid, string auth_token
     93   // No result.
     94   bool Connect(const NPVariant* args, uint32_t arg_count, NPVariant* result);
     95 
     96   // Disconnect. No arguments or result.
     97   bool Disconnect(const NPVariant* args, uint32_t arg_count, NPVariant* result);
     98 
     99   // Localize strings. args are:
    100   //   localize_func - a callback function which returns a localized string for
    101   //   a given tag name.
    102   // No result.
    103   bool Localize(const NPVariant* args, uint32_t arg_count, NPVariant* result);
    104 
    105   //////////////////////////////////////////////////////////
    106   // Plugin methods for Me2Me host.
    107 
    108   // Deletes all paired clients from the registry.
    109   bool ClearPairedClients(const NPVariant* args,
    110                           uint32_t arg_count,
    111                           NPVariant* result);
    112 
    113   // Deletes a paired client referenced by client id.
    114   bool DeletePairedClient(const NPVariant* args,
    115                           uint32_t arg_count,
    116                           NPVariant* result);
    117 
    118   // Fetches the host name, passing it to the supplied callback. Args are:
    119   //   function(string) callback
    120   // Returns false if the parameters are invalid.
    121   bool GetHostName(const NPVariant* args,
    122                    uint32_t arg_count,
    123                    NPVariant* result);
    124 
    125   // Calculates PIN hash value to be stored in the config. Args are:
    126   //   string hostId Host ID.
    127   //   string pin The PIN.
    128   //   function(string) callback
    129   // Passes the resulting hash value base64-encoded to the callback.
    130   // Returns false if the parameters are invalid.
    131   bool GetPinHash(const NPVariant* args,
    132                   uint32_t arg_count,
    133                   NPVariant* result);
    134 
    135   // Generates new key pair to use for the host. The specified
    136   // callback is called when when the key is generated. The key is
    137   // returned in format understood by the host (PublicKeyInfo
    138   // structure encoded with ASN.1 DER, and then BASE64). Args are:
    139   //   function(string) callback The callback to be called when done.
    140   bool GenerateKeyPair(const NPVariant* args,
    141                        uint32_t arg_count,
    142                        NPVariant* result);
    143 
    144   // Update host config for Me2Me. Args are:
    145   //   string config
    146   //   function(number) done_callback
    147   bool UpdateDaemonConfig(const NPVariant* args,
    148                           uint32_t arg_count,
    149                           NPVariant* result);
    150 
    151   // Loads daemon config. The first argument specifies the callback to be
    152   // called once the config has been loaded. The config is passed as a JSON
    153   // formatted string. Args are:
    154   //   function(string) callback
    155   bool GetDaemonConfig(const NPVariant* args,
    156                        uint32_t arg_count,
    157                        NPVariant* result);
    158 
    159   // Retrieves daemon version. The first argument specifies the callback to be
    160   // called with the obtained version. The version is passed as a dotted
    161   // version string, described in daemon_controller.h.
    162   bool GetDaemonVersion(const NPVariant* args,
    163                         uint32_t arg_count,
    164                         NPVariant* result);
    165 
    166   // Retrieves the list of paired clients as a JSON-encoded string.
    167   bool GetPairedClients(const NPVariant* args,
    168                         uint32_t arg_count,
    169                         NPVariant* result);
    170 
    171   // Retrieves the user's consent to report crash dumps. The first argument
    172   // specifies the callback to be called with the recorder consent. Possible
    173   // consent codes are defined in remoting/host/breakpad.h.
    174   bool GetUsageStatsConsent(const NPVariant* args,
    175                             uint32_t arg_count,
    176                             NPVariant* result);
    177 
    178   // Start the daemon process with the specified config. Args are:
    179   //   string config
    180   //   function(number) done_callback
    181   bool StartDaemon(const NPVariant* args,
    182                    uint32_t arg_count,
    183                    NPVariant* result);
    184 
    185   // Stop the daemon process. Args are:
    186   //   function(number) done_callback
    187   bool StopDaemon(const NPVariant* args, uint32_t arg_count, NPVariant* result);
    188 
    189   //////////////////////////////////////////////////////////
    190   // Helper methods used by the It2Me host implementation.
    191 
    192   // Notifies OnStateChanged handler of a state change.
    193   void NotifyStateChanged(State state);
    194 
    195   // If the web-app has registered a callback to be notified of changes to the
    196   // NAT traversal policy, notify it.
    197   void NotifyNatPolicyChanged(bool nat_traversal_enabled);
    198 
    199   // Stores the Access Code for the web-app to query.
    200   void StoreAccessCode(const std::string& access_code,
    201                        base::TimeDelta access_code_lifetime);
    202 
    203   // Stores the client user's name for the web-app to query.
    204   void StoreClientUsername(const std::string& client_username);
    205 
    206   // Used to generate localized strings to pass to the It2Me host core.
    207   void LocalizeStrings(NPObject* localize_func);
    208 
    209   // Helper function for executing InvokeDefault on an NPObject that performs
    210   // a string->string mapping without substitution. Stores the translation in
    211   // |result| and returns true on success, or leaves it unchanged and returns
    212   // false on failure.
    213   bool LocalizeString(NPObject* localize_func, const char* tag,
    214                       string16* result);
    215 
    216   // Helper function for executing InvokeDefault on an NPObject that performs
    217   // a string->string mapping with one substitution. Stores the translation in
    218   // |result| and returns true on success, or leaves it unchanged and returns
    219   // false on failure.
    220   bool LocalizeStringWithSubstitution(NPObject* localize_func,
    221                                       const char* tag,
    222                                       const char* substitution,
    223                                       string16* result);
    224 
    225   //////////////////////////////////////////////////////////
    226   // Helper methods for Me2Me host.
    227 
    228   // Helpers for GenerateKeyPair().
    229   void DoGenerateKeyPair(const ScopedRefNPObject& callback);
    230   void InvokeGenerateKeyPairCallback(const ScopedRefNPObject& callback,
    231                                      const std::string& private_key,
    232                                      const std::string& public_key);
    233 
    234 
    235   // Callback handler for SetConfigAndStart(), Stop(), SetPin() and
    236   // SetUsageStatsConsent() in DaemonController.
    237   void InvokeAsyncResultCallback(const ScopedRefNPObject& callback,
    238                                  DaemonController::AsyncResult result);
    239 
    240   // Callback handler for PairingRegistry methods that return a boolean
    241   // success status.
    242   void InvokeBooleanCallback(const ScopedRefNPObject& callback, bool result);
    243 
    244   // Callback handler for DaemonController::GetConfig().
    245   void InvokeGetDaemonConfigCallback(const ScopedRefNPObject& callback,
    246                                      scoped_ptr<base::DictionaryValue> config);
    247 
    248   // Callback handler for DaemonController::GetVersion().
    249   void InvokeGetDaemonVersionCallback(const ScopedRefNPObject& callback,
    250                                       const std::string& version);
    251 
    252   // Callback handler for GetPairedClients().
    253   void InvokeGetPairedClientsCallback(
    254       const ScopedRefNPObject& callback,
    255       scoped_ptr<base::ListValue> paired_clients);
    256 
    257   // Callback handler for DaemonController::GetUsageStatsConsent().
    258   void InvokeGetUsageStatsConsentCallback(const ScopedRefNPObject& callback,
    259                                           bool supported,
    260                                           bool allowed,
    261                                           bool set_by_policy);
    262 
    263   //////////////////////////////////////////////////////////
    264   // Basic helper methods used for both It2Me and Me2me.
    265 
    266   // Call LogDebugInfo handler if there is one.
    267   // This must be called on the correct thread.
    268   void LogDebugInfo(const std::string& message);
    269 
    270   // Helper function for executing InvokeDefault on an NPObject, and ignoring
    271   // the return value.
    272   bool InvokeAndIgnoreResult(NPObject* func,
    273                              const NPVariant* args,
    274                              uint32_t arg_count);
    275 
    276   // Set an exception for the current call.
    277   void SetException(const std::string& exception_string);
    278 
    279   //////////////////////////////////////////////////////////
    280   // Plugin state variables shared between It2Me and Me2Me.
    281 
    282   NPP plugin_;
    283   NPObject* parent_;
    284   scoped_refptr<AutoThreadTaskRunner> plugin_task_runner_;
    285   scoped_ptr<base::ThreadTaskRunnerHandle> plugin_task_runner_handle_;
    286 
    287   // True if we're in the middle of handling a log message.
    288   bool am_currently_logging_;
    289 
    290   ScopedRefNPObject log_debug_info_func_;
    291 
    292   //////////////////////////////////////////////////////////
    293   // It2Me host state.
    294 
    295   // Internal implementation of the It2Me host function.
    296   scoped_refptr<It2MeImpl> it2me_impl_;
    297 
    298   // Cached, read-only copies of |it2me_impl_| session state.
    299   State state_;
    300   std::string access_code_;
    301   base::TimeDelta access_code_lifetime_;
    302   std::string client_username_;
    303 
    304   // IT2Me Talk server configuration used by |it2me_impl_| to connect.
    305   XmppSignalStrategy::XmppServerConfig xmpp_server_config_;
    306 
    307   // Chromoting Bot JID used by |it2me_impl_| to register the host.
    308   std::string directory_bot_jid_;
    309 
    310   // Callbacks to notify in response to |it2me_impl_| events.
    311   ScopedRefNPObject on_nat_traversal_policy_changed_func_;
    312   ScopedRefNPObject on_state_changed_func_;
    313 
    314   //////////////////////////////////////////////////////////
    315   // Me2Me host state.
    316 
    317   // Platform-specific installation & configuration implementation.
    318   scoped_ptr<DaemonController> daemon_controller_;
    319 
    320   // TODO(sergeyu): Replace this thread with
    321   // SequencedWorkerPool. Problem is that SequencedWorkerPool relies
    322   // on MessageLoopProxy::current().
    323   scoped_refptr<AutoThreadTaskRunner> worker_thread_;
    324 
    325   // Used to load and update the paired clients for this host.
    326   scoped_refptr<protocol::PairingRegistry> pairing_registry_;
    327 
    328   //////////////////////////////////////////////////////////
    329   // Plugin state used for both Ir2Me and Me2Me.
    330 
    331   // Used to cancel pending tasks for this object when it is destroyed.
    332   base::WeakPtrFactory<HostNPScriptObject> weak_factory_;
    333   base::WeakPtr<HostNPScriptObject> weak_ptr_;
    334 
    335   DISALLOW_COPY_AND_ASSIGN(HostNPScriptObject);
    336 };
    337 
    338 }  // namespace remoting
    339 
    340 #endif  // REMOTING_HOST_PLUGIN_HOST_SCRIPT_OBJECT_H_
    341