blob: 2e92dd57ba8f1f3af534e0e7f38f47d9ba21b329 [file] [log] [blame]
[email protected]73097562012-01-12 19:38:551// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]66085312010-11-05 22:14:252// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ppapi/proxy/plugin_var_serialization_rules.h"
6
[email protected]465faa22011-02-08 16:31:467#include "base/logging.h"
[email protected]4614f192011-01-21 00:26:438#include "ppapi/proxy/plugin_dispatcher.h"
[email protected]794d83cd2011-10-20 19:09:209#include "ppapi/proxy/plugin_globals.h"
[email protected]2bbd2c672011-08-09 23:14:1310#include "ppapi/proxy/plugin_resource_tracker.h"
[email protected]66085312010-11-05 22:14:2511#include "ppapi/proxy/plugin_var_tracker.h"
[email protected]794d83cd2011-10-20 19:09:2012#include "ppapi/shared_impl/ppapi_globals.h"
[email protected]2bbd2c672011-08-09 23:14:1313#include "ppapi/shared_impl/var.h"
14
[email protected]4d2efd22011-08-18 21:58:0215namespace ppapi {
[email protected]66085312010-11-05 22:14:2516namespace proxy {
17
[email protected]4614f192011-01-21 00:26:4318PluginVarSerializationRules::PluginVarSerializationRules()
[email protected]794d83cd2011-10-20 19:09:2019 : var_tracker_(PluginGlobals::Get()->plugin_var_tracker()) {
[email protected]66085312010-11-05 22:14:2520}
21
22PluginVarSerializationRules::~PluginVarSerializationRules() {
23}
24
[email protected]4614f192011-01-21 00:26:4325PP_Var PluginVarSerializationRules::SendCallerOwned(const PP_Var& var,
26 std::string* str_val) {
27 // Objects need special translations to get the IDs valid in the host.
28 if (var.type == PP_VARTYPE_OBJECT)
29 return var_tracker_->GetHostObject(var);
30
[email protected]0925622c2011-06-08 20:22:0231 // Retrieve the string to use for IPC.
32 if (var.type == PP_VARTYPE_STRING) {
[email protected]28cfaed02011-08-22 22:15:5833 StringVar* string_var = StringVar::FromPPVar(var);
34 if (string_var)
[email protected]2bbd2c672011-08-09 23:14:1335 *str_val = string_var->value();
[email protected]0925622c2011-06-08 20:22:0236 else
37 NOTREACHED() << "Trying to send unknown string over IPC.";
38 }
[email protected]4614f192011-01-21 00:26:4339 return var;
[email protected]66085312010-11-05 22:14:2540}
41
42PP_Var PluginVarSerializationRules::BeginReceiveCallerOwned(
43 const PP_Var& var,
[email protected]4614f192011-01-21 00:26:4344 const std::string* str_val,
45 Dispatcher* dispatcher) {
[email protected]2bbd2c672011-08-09 23:14:1346 if (var.type == PP_VARTYPE_STRING)
[email protected]872caf562011-12-07 22:50:4347 return StringVar::StringToPPVar(*str_val);
[email protected]66085312010-11-05 22:14:2548
[email protected]465faa22011-02-08 16:31:4649 if (var.type == PP_VARTYPE_OBJECT) {
50 DCHECK(dispatcher->IsPlugin());
51 return var_tracker_->TrackObjectWithNoReference(
52 var, static_cast<PluginDispatcher*>(dispatcher));
53 }
[email protected]4614f192011-01-21 00:26:4354
[email protected]66085312010-11-05 22:14:2555 return var;
56}
57
58void PluginVarSerializationRules::EndReceiveCallerOwned(const PP_Var& var) {
59 if (var.type == PP_VARTYPE_STRING) {
60 // Destroy the string BeginReceiveCallerOwned created above.
[email protected]2bbd2c672011-08-09 23:14:1361 var_tracker_->ReleaseVar(var);
[email protected]4614f192011-01-21 00:26:4362 } else if (var.type == PP_VARTYPE_OBJECT) {
63 var_tracker_->StopTrackingObjectWithNoReference(var);
[email protected]66085312010-11-05 22:14:2564 }
65}
66
67PP_Var PluginVarSerializationRules::ReceivePassRef(const PP_Var& var,
[email protected]4614f192011-01-21 00:26:4368 const std::string& str_val,
69 Dispatcher* dispatcher) {
[email protected]2bbd2c672011-08-09 23:14:1370 if (var.type == PP_VARTYPE_STRING)
[email protected]872caf562011-12-07 22:50:4371 return StringVar::StringToPPVar(str_val);
[email protected]66085312010-11-05 22:14:2572
73 // Overview of sending an object with "pass ref" from the browser to the
74 // plugin:
75 // Example 1 Example 2
76 // Plugin Browser Plugin Browser
77 // Before send 3 2 0 1
78 // Browser calls BeginSendPassRef 3 2 0 1
79 // Plugin calls ReceivePassRef 4 1 1 1
80 // Browser calls EndSendPassRef 4 1 1 1
81 //
82 // In example 1 before the send, the plugin has 3 refs which are represented
83 // as one ref in the browser (since the plugin only tells the browser when
84 // it's refcount goes from 1 -> 0). The initial state is that the browser
85 // plugin code started to return a value, which means it gets another ref
86 // on behalf of the caller. This needs to be transferred to the plugin and
87 // folded in to its set of refs it maintains (with one ref representing all
[email protected]73097562012-01-12 19:38:5588 // of them in the browser).
[email protected]4614f192011-01-21 00:26:4389 if (var.type == PP_VARTYPE_OBJECT) {
[email protected]465faa22011-02-08 16:31:4690 DCHECK(dispatcher->IsPlugin());
91 return var_tracker_->ReceiveObjectPassRef(
92 var, static_cast<PluginDispatcher*>(dispatcher));
[email protected]4614f192011-01-21 00:26:4393 }
94
95 // Other types are unchanged.
[email protected]66085312010-11-05 22:14:2596 return var;
97}
98
[email protected]4614f192011-01-21 00:26:4399PP_Var PluginVarSerializationRules::BeginSendPassRef(const PP_Var& var,
100 std::string* str_val) {
[email protected]66085312010-11-05 22:14:25101 // Overview of sending an object with "pass ref" from the plugin to the
102 // browser:
103 // Example 1 Example 2
104 // Plugin Browser Plugin Browser
105 // Before send 3 1 1 1
106 // Plugin calls BeginSendPassRef 3 1 1 1
107 // Browser calls ReceivePassRef 3 2 1 2
108 // Plugin calls EndSendPassRef 2 2 0 1
109 //
110 // The plugin maintains one ref count in the browser on behalf of the
111 // entire ref count in the plugin. When the plugin refcount goes to 0, it
112 // will call the browser to deref the object. This is why in example 2
113 // transferring the object ref to the browser involves no net change in the
114 // browser's refcount.
115
[email protected]4614f192011-01-21 00:26:43116 // Objects need special translations to get the IDs valid in the host.
117 if (var.type == PP_VARTYPE_OBJECT)
118 return var_tracker_->GetHostObject(var);
119
[email protected]0925622c2011-06-08 20:22:02120 if (var.type == PP_VARTYPE_STRING) {
[email protected]28cfaed02011-08-22 22:15:58121 StringVar* string_var = StringVar::FromPPVar(var);
122 if (string_var)
[email protected]2bbd2c672011-08-09 23:14:13123 *str_val = string_var->value();
[email protected]0925622c2011-06-08 20:22:02124 else
125 NOTREACHED() << "Trying to send unknown string over IPC.";
126 }
[email protected]4614f192011-01-21 00:26:43127 return var;
[email protected]66085312010-11-05 22:14:25128}
129
[email protected]f24448db2011-01-27 20:40:39130void PluginVarSerializationRules::EndSendPassRef(const PP_Var& var,
131 Dispatcher* dispatcher) {
[email protected]66085312010-11-05 22:14:25132 // See BeginSendPassRef for an example of why we release our ref here.
[email protected]f24448db2011-01-27 20:40:39133 // The var we have in our inner class has been converted to a host object
134 // by BeginSendPassRef. This means it's not a normal var valid in the plugin,
135 // so we need to use the special ReleaseHostObject.
[email protected]465faa22011-02-08 16:31:46136 if (var.type == PP_VARTYPE_OBJECT) {
137 var_tracker_->ReleaseHostObject(
138 static_cast<PluginDispatcher*>(dispatcher), var);
[email protected]a732cec2011-12-22 08:35:52139 } else if (var.type == PP_VARTYPE_STRING) {
140 var_tracker_->ReleaseVar(var);
[email protected]465faa22011-02-08 16:31:46141 }
[email protected]66085312010-11-05 22:14:25142}
143
144void PluginVarSerializationRules::ReleaseObjectRef(const PP_Var& var) {
[email protected]2bbd2c672011-08-09 23:14:13145 var_tracker_->ReleaseVar(var);
[email protected]66085312010-11-05 22:14:25146}
147
148} // namespace proxy
[email protected]4d2efd22011-08-18 21:58:02149} // namespace ppapi