blob: a3d82312de6de19fd02b099827e8a308133c6d55 [file] [log] [blame]
[email protected]4614f192011-01-21 00:26:431// Copyright (c) 2011 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]66085312010-11-05 22:14:259#include "ppapi/proxy/plugin_var_tracker.h"
10
11namespace pp {
12namespace proxy {
13
[email protected]4614f192011-01-21 00:26:4314PluginVarSerializationRules::PluginVarSerializationRules()
15 : var_tracker_(PluginVarTracker::GetInstance()) {
[email protected]66085312010-11-05 22:14:2516}
17
18PluginVarSerializationRules::~PluginVarSerializationRules() {
19}
20
[email protected]4614f192011-01-21 00:26:4321PP_Var PluginVarSerializationRules::SendCallerOwned(const PP_Var& var,
22 std::string* str_val) {
23 // Objects need special translations to get the IDs valid in the host.
24 if (var.type == PP_VARTYPE_OBJECT)
25 return var_tracker_->GetHostObject(var);
26
[email protected]66085312010-11-05 22:14:2527 // Nothing to do since we manage the refcount, other than retrieve the string
28 // to use for IPC.
29 if (var.type == PP_VARTYPE_STRING)
30 *str_val = var_tracker_->GetString(var);
[email protected]4614f192011-01-21 00:26:4331 return var;
[email protected]66085312010-11-05 22:14:2532}
33
34PP_Var PluginVarSerializationRules::BeginReceiveCallerOwned(
35 const PP_Var& var,
[email protected]4614f192011-01-21 00:26:4336 const std::string* str_val,
37 Dispatcher* dispatcher) {
[email protected]66085312010-11-05 22:14:2538 if (var.type == PP_VARTYPE_STRING) {
39 // Convert the string to the context of the current process.
40 PP_Var ret;
41 ret.type = PP_VARTYPE_STRING;
42 ret.value.as_id = var_tracker_->MakeString(*str_val);
43 return ret;
44 }
45
[email protected]465faa22011-02-08 16:31:4646 if (var.type == PP_VARTYPE_OBJECT) {
47 DCHECK(dispatcher->IsPlugin());
48 return var_tracker_->TrackObjectWithNoReference(
49 var, static_cast<PluginDispatcher*>(dispatcher));
50 }
[email protected]4614f192011-01-21 00:26:4351
[email protected]66085312010-11-05 22:14:2552 return var;
53}
54
55void PluginVarSerializationRules::EndReceiveCallerOwned(const PP_Var& var) {
56 if (var.type == PP_VARTYPE_STRING) {
57 // Destroy the string BeginReceiveCallerOwned created above.
58 var_tracker_->Release(var);
[email protected]4614f192011-01-21 00:26:4359 } else if (var.type == PP_VARTYPE_OBJECT) {
60 var_tracker_->StopTrackingObjectWithNoReference(var);
[email protected]66085312010-11-05 22:14:2561 }
62}
63
64PP_Var PluginVarSerializationRules::ReceivePassRef(const PP_Var& var,
[email protected]4614f192011-01-21 00:26:4365 const std::string& str_val,
66 Dispatcher* dispatcher) {
[email protected]66085312010-11-05 22:14:2567 if (var.type == PP_VARTYPE_STRING) {
68 // Convert the string to the context of the current process.
69 PP_Var ret;
70 ret.type = PP_VARTYPE_STRING;
71 ret.value.as_id = var_tracker_->MakeString(str_val);
72 return ret;
73 }
74
75 // Overview of sending an object with "pass ref" from the browser to the
76 // plugin:
77 // Example 1 Example 2
78 // Plugin Browser Plugin Browser
79 // Before send 3 2 0 1
80 // Browser calls BeginSendPassRef 3 2 0 1
81 // Plugin calls ReceivePassRef 4 1 1 1
82 // Browser calls EndSendPassRef 4 1 1 1
83 //
84 // In example 1 before the send, the plugin has 3 refs which are represented
85 // as one ref in the browser (since the plugin only tells the browser when
86 // it's refcount goes from 1 -> 0). The initial state is that the browser
87 // plugin code started to return a value, which means it gets another ref
88 // on behalf of the caller. This needs to be transferred to the plugin and
89 // folded in to its set of refs it maintains (with one ref representing all
90 // fo them in the browser).
[email protected]4614f192011-01-21 00:26:4391 if (var.type == PP_VARTYPE_OBJECT) {
[email protected]465faa22011-02-08 16:31:4692 DCHECK(dispatcher->IsPlugin());
93 return var_tracker_->ReceiveObjectPassRef(
94 var, static_cast<PluginDispatcher*>(dispatcher));
[email protected]4614f192011-01-21 00:26:4395 }
96
97 // Other types are unchanged.
[email protected]66085312010-11-05 22:14:2598 return var;
99}
100
[email protected]4614f192011-01-21 00:26:43101PP_Var PluginVarSerializationRules::BeginSendPassRef(const PP_Var& var,
102 std::string* str_val) {
[email protected]66085312010-11-05 22:14:25103 // Overview of sending an object with "pass ref" from the plugin to the
104 // browser:
105 // Example 1 Example 2
106 // Plugin Browser Plugin Browser
107 // Before send 3 1 1 1
108 // Plugin calls BeginSendPassRef 3 1 1 1
109 // Browser calls ReceivePassRef 3 2 1 2
110 // Plugin calls EndSendPassRef 2 2 0 1
111 //
112 // The plugin maintains one ref count in the browser on behalf of the
113 // entire ref count in the plugin. When the plugin refcount goes to 0, it
114 // will call the browser to deref the object. This is why in example 2
115 // transferring the object ref to the browser involves no net change in the
116 // browser's refcount.
117
[email protected]4614f192011-01-21 00:26:43118 // Objects need special translations to get the IDs valid in the host.
119 if (var.type == PP_VARTYPE_OBJECT)
120 return var_tracker_->GetHostObject(var);
121
[email protected]66085312010-11-05 22:14:25122 if (var.type == PP_VARTYPE_STRING)
123 *str_val = var_tracker_->GetString(var);
[email protected]4614f192011-01-21 00:26:43124 return var;
[email protected]66085312010-11-05 22:14:25125}
126
[email protected]f24448db2011-01-27 20:40:39127void PluginVarSerializationRules::EndSendPassRef(const PP_Var& var,
128 Dispatcher* dispatcher) {
[email protected]66085312010-11-05 22:14:25129 // See BeginSendPassRef for an example of why we release our ref here.
[email protected]f24448db2011-01-27 20:40:39130 // The var we have in our inner class has been converted to a host object
131 // by BeginSendPassRef. This means it's not a normal var valid in the plugin,
132 // so we need to use the special ReleaseHostObject.
[email protected]465faa22011-02-08 16:31:46133 if (var.type == PP_VARTYPE_OBJECT) {
134 var_tracker_->ReleaseHostObject(
135 static_cast<PluginDispatcher*>(dispatcher), var);
136 }
[email protected]66085312010-11-05 22:14:25137}
138
139void PluginVarSerializationRules::ReleaseObjectRef(const PP_Var& var) {
140 var_tracker_->Release(var);
141}
142
143} // namespace proxy
144} // namespace pp