blob: a56e5b4f17d5bc990c13331e9fc6e6ce960ece27 [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]4614f192011-01-21 00:26:437#include "ppapi/proxy/plugin_dispatcher.h"
[email protected]66085312010-11-05 22:14:258#include "ppapi/proxy/plugin_var_tracker.h"
9
10namespace pp {
11namespace proxy {
12
[email protected]4614f192011-01-21 00:26:4313PluginVarSerializationRules::PluginVarSerializationRules()
14 : var_tracker_(PluginVarTracker::GetInstance()) {
[email protected]66085312010-11-05 22:14:2515}
16
17PluginVarSerializationRules::~PluginVarSerializationRules() {
18}
19
[email protected]4614f192011-01-21 00:26:4320PP_Var PluginVarSerializationRules::SendCallerOwned(const PP_Var& var,
21 std::string* str_val) {
22 // Objects need special translations to get the IDs valid in the host.
23 if (var.type == PP_VARTYPE_OBJECT)
24 return var_tracker_->GetHostObject(var);
25
[email protected]66085312010-11-05 22:14:2526 // Nothing to do since we manage the refcount, other than retrieve the string
27 // to use for IPC.
28 if (var.type == PP_VARTYPE_STRING)
29 *str_val = var_tracker_->GetString(var);
[email protected]4614f192011-01-21 00:26:4330 return var;
[email protected]66085312010-11-05 22:14:2531}
32
33PP_Var PluginVarSerializationRules::BeginReceiveCallerOwned(
34 const PP_Var& var,
[email protected]4614f192011-01-21 00:26:4335 const std::string* str_val,
36 Dispatcher* dispatcher) {
[email protected]66085312010-11-05 22:14:2537 if (var.type == PP_VARTYPE_STRING) {
38 // Convert the string to the context of the current process.
39 PP_Var ret;
40 ret.type = PP_VARTYPE_STRING;
41 ret.value.as_id = var_tracker_->MakeString(*str_val);
42 return ret;
43 }
44
[email protected]4614f192011-01-21 00:26:4345 if (var.type == PP_VARTYPE_OBJECT)
46 return var_tracker_->TrackObjectWithNoReference(var, dispatcher);
47
[email protected]66085312010-11-05 22:14:2548 return var;
49}
50
51void PluginVarSerializationRules::EndReceiveCallerOwned(const PP_Var& var) {
52 if (var.type == PP_VARTYPE_STRING) {
53 // Destroy the string BeginReceiveCallerOwned created above.
54 var_tracker_->Release(var);
[email protected]4614f192011-01-21 00:26:4355 } else if (var.type == PP_VARTYPE_OBJECT) {
56 var_tracker_->StopTrackingObjectWithNoReference(var);
[email protected]66085312010-11-05 22:14:2557 }
58}
59
60PP_Var PluginVarSerializationRules::ReceivePassRef(const PP_Var& var,
[email protected]4614f192011-01-21 00:26:4361 const std::string& str_val,
62 Dispatcher* dispatcher) {
[email protected]66085312010-11-05 22:14:2563 if (var.type == PP_VARTYPE_STRING) {
64 // Convert the string to the context of the current process.
65 PP_Var ret;
66 ret.type = PP_VARTYPE_STRING;
67 ret.value.as_id = var_tracker_->MakeString(str_val);
68 return ret;
69 }
70
71 // Overview of sending an object with "pass ref" from the browser to the
72 // plugin:
73 // Example 1 Example 2
74 // Plugin Browser Plugin Browser
75 // Before send 3 2 0 1
76 // Browser calls BeginSendPassRef 3 2 0 1
77 // Plugin calls ReceivePassRef 4 1 1 1
78 // Browser calls EndSendPassRef 4 1 1 1
79 //
80 // In example 1 before the send, the plugin has 3 refs which are represented
81 // as one ref in the browser (since the plugin only tells the browser when
82 // it's refcount goes from 1 -> 0). The initial state is that the browser
83 // plugin code started to return a value, which means it gets another ref
84 // on behalf of the caller. This needs to be transferred to the plugin and
85 // folded in to its set of refs it maintains (with one ref representing all
86 // fo them in the browser).
[email protected]4614f192011-01-21 00:26:4387 if (var.type == PP_VARTYPE_OBJECT) {
88 return var_tracker_->ReceiveObjectPassRef(var, dispatcher);
89 }
90
91 // Other types are unchanged.
[email protected]66085312010-11-05 22:14:2592 return var;
93}
94
[email protected]4614f192011-01-21 00:26:4395PP_Var PluginVarSerializationRules::BeginSendPassRef(const PP_Var& var,
96 std::string* str_val) {
[email protected]66085312010-11-05 22:14:2597 // Overview of sending an object with "pass ref" from the plugin to the
98 // browser:
99 // Example 1 Example 2
100 // Plugin Browser Plugin Browser
101 // Before send 3 1 1 1
102 // Plugin calls BeginSendPassRef 3 1 1 1
103 // Browser calls ReceivePassRef 3 2 1 2
104 // Plugin calls EndSendPassRef 2 2 0 1
105 //
106 // The plugin maintains one ref count in the browser on behalf of the
107 // entire ref count in the plugin. When the plugin refcount goes to 0, it
108 // will call the browser to deref the object. This is why in example 2
109 // transferring the object ref to the browser involves no net change in the
110 // browser's refcount.
111
[email protected]4614f192011-01-21 00:26:43112 // Objects need special translations to get the IDs valid in the host.
113 if (var.type == PP_VARTYPE_OBJECT)
114 return var_tracker_->GetHostObject(var);
115
[email protected]66085312010-11-05 22:14:25116 if (var.type == PP_VARTYPE_STRING)
117 *str_val = var_tracker_->GetString(var);
[email protected]4614f192011-01-21 00:26:43118 return var;
[email protected]66085312010-11-05 22:14:25119}
120
[email protected]f24448db2011-01-27 20:40:39121void PluginVarSerializationRules::EndSendPassRef(const PP_Var& var,
122 Dispatcher* dispatcher) {
[email protected]66085312010-11-05 22:14:25123 // See BeginSendPassRef for an example of why we release our ref here.
[email protected]f24448db2011-01-27 20:40:39124 // The var we have in our inner class has been converted to a host object
125 // by BeginSendPassRef. This means it's not a normal var valid in the plugin,
126 // so we need to use the special ReleaseHostObject.
[email protected]66085312010-11-05 22:14:25127 if (var.type == PP_VARTYPE_OBJECT)
[email protected]f24448db2011-01-27 20:40:39128 var_tracker_->ReleaseHostObject(dispatcher, var);
[email protected]66085312010-11-05 22:14:25129}
130
131void PluginVarSerializationRules::ReleaseObjectRef(const PP_Var& var) {
132 var_tracker_->Release(var);
133}
134
135} // namespace proxy
136} // namespace pp