summaryrefslogtreecommitdiffstats
path: root/webkit/plugins/ppapi/message_channel.h
blob: c6470c471cd497bd66f1bb7a10f74d7339b139e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// 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.

#ifndef WEBKIT_PLUGINS_PPAPI_MESSAGE_CHANNEL_H_
#define WEBKIT_PLUGINS_PPAPI_MESSAGE_CHANNEL_H_

#include "base/task.h"
#include "ppapi/shared_impl/resource.h"
#include "third_party/npapi/bindings/npruntime.h"

struct PP_Var;

namespace webkit {
namespace ppapi {

class PluginInstance;

// MessageChannel implements bidirectional postMessage functionality, allowing
// calls from JavaScript to plugins and vice-versa. See
// PPB_Messaging::PostMessage and PPP_Messaging::HandleMessage for more
// information.
//
// Currently, only 1 MessageChannel can exist, to implement postMessage
// functionality for the instance interfaces.  In the future, when we create a
// MessagePort type in PPAPI, those may be implemented here as well with some
// refactoring.
//   - Separate message ports won't require the passthrough object.
//   - The message target won't be limited to instance, and should support
//     either plugin-provided or JS objects.
// TODO(dmichael):  Add support for separate MessagePorts.
class MessageChannel {
 public:
  // MessageChannelNPObject is a simple struct that adds a pointer back to a
  // MessageChannel instance.  This way, we can use an NPObject to allow
  // JavaScript interactions without forcing MessageChannel to inherit from
  // NPObject.
  struct MessageChannelNPObject : public NPObject {
    MessageChannelNPObject();
    ~MessageChannelNPObject();

    MessageChannel* message_channel;
  };

  explicit MessageChannel(PluginInstance* instance);
  ~MessageChannel();

  // Post a message to the onmessage handler for this channel's instance
  // asynchronously.
  void PostMessageToJavaScript(PP_Var message_data);
  // Post a message to the PPP_Instance HandleMessage function for this
  // channel's instance.
  void PostMessageToNative(PP_Var message_data);

  // Return the NPObject* to which we should forward any calls which aren't
  // related to postMessage.  Note that this can be NULL;  it only gets set if
  // there is a scriptable 'InstanceObject' associated with this channel's
  // instance.
  NPObject* passthrough_object() {
    return passthrough_object_;
  }
  void SetPassthroughObject(NPObject* passthrough);

  NPObject* np_object() { return np_object_; }

  PluginInstance* instance() {
    return instance_;
  }

 private:
  PluginInstance* instance_;

  // We pass all non-postMessage calls through to the passthrough_object_.
  // This way, a plugin can use PPB_Class or PPP_Class_Deprecated and also
  // postMessage.  This is necessary to support backwards-compatibility, and
  // also trusted plugins for which we will continue to support synchronous
  // scripting.
  NPObject* passthrough_object_;

  // The NPObject we use to expose postMessage to JavaScript.
  MessageChannelNPObject* np_object_;

  // An NPVariant referring to the JavaScript function we use to send a message
  // to a JavaScript target.
  NPVariant onmessage_invoker_;

  // Evaluates the JavaScript code for onmessage_invoker_ and makes
  // it a callable NPVariant for that function.  Returns true on success, false
  // otherwise.
  bool EvaluateOnMessageInvoker();

  // Post a message to the onmessage handler for this channel's instance
  // synchronously.  This is used by PostMessageToJavaScript.
  void PostMessageToJavaScriptImpl(PP_Var message_data);
  // Post a message to the PPP_Instance HandleMessage function for this
  // channel's instance.  This is used by PostMessageToNative.
  void PostMessageToNativeImpl(PP_Var message_data);

  // Ensure pending tasks will not fire after this object is destroyed.
  ScopedRunnableMethodFactory<MessageChannel> method_factory_;

  DISALLOW_COPY_AND_ASSIGN(MessageChannel);
};

}  // namespace ppapi
}  // namespace webkit

#endif  // WEBKIT_PLUGINS_PPAPI_MESSAGE_CHANNEL_H_