blob: 3a023091496f0e4da669d32e6d8c9e12ea002087 [file] [log] [blame]
[email protected]eccf80312012-07-14 15:43:421// 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#include "ppapi/proxy/plugin_resource.h"
6
[email protected]d84e9992012-11-08 22:13:287#include <limits>
8
[email protected]eccf80312012-07-14 15:43:429#include "ppapi/proxy/ppapi_messages.h"
[email protected]eccf80312012-07-14 15:43:4210
11namespace ppapi {
12namespace proxy {
13
[email protected]93df81e2012-08-10 22:22:4614PluginResource::PluginResource(Connection connection, PP_Instance instance)
[email protected]eccf80312012-07-14 15:43:4215 : Resource(OBJECT_IS_PROXY, instance),
[email protected]93df81e2012-08-10 22:22:4616 connection_(connection),
[email protected]d84e9992012-11-08 22:13:2817 next_sequence_number_(1),
[email protected]93df81e2012-08-10 22:22:4618 sent_create_to_browser_(false),
[email protected]eccf80312012-07-14 15:43:4219 sent_create_to_renderer_(false) {
20}
21
22PluginResource::~PluginResource() {
[email protected]93df81e2012-08-10 22:22:4623 if (sent_create_to_browser_) {
24 connection_.browser_sender->Send(
25 new PpapiHostMsg_ResourceDestroyed(pp_resource()));
26 }
27 if (sent_create_to_renderer_) {
28 connection_.renderer_sender->Send(
29 new PpapiHostMsg_ResourceDestroyed(pp_resource()));
30 }
[email protected]eccf80312012-07-14 15:43:4231}
32
[email protected]e1f5c9b2012-10-04 00:07:4433void PluginResource::OnReplyReceived(
34 const proxy::ResourceMessageReplyParams& params,
35 const IPC::Message& msg) {
36 // Grab the callback for the reply sequence number and run it with |msg|.
37 CallbackMap::iterator it = callbacks_.find(params.sequence());
38 if (it == callbacks_.end()) {
39 DCHECK(false) << "Callback does not exist for an expected sequence number.";
40 } else {
41 scoped_refptr<PluginResourceCallbackBase> callback = it->second;
42 callbacks_.erase(it);
43 callback->Run(params, msg);
44 }
45}
46
[email protected]28df6a02012-11-08 07:29:4547void PluginResource::NotifyLastPluginRefWasDeleted() {
48 Resource::NotifyLastPluginRefWasDeleted();
49
50 // The callbacks may hold referrences to this object. Normally, we will get
51 // reply messages from the host side and remove them. However, it is possible
52 // that some replies from the host never arrive, e.g., the corresponding
53 // renderer crashes. In that case, we have to clean up the callbacks,
54 // otherwise this object will live forever.
55 callbacks_.clear();
56}
57
58void PluginResource::NotifyInstanceWasDeleted() {
59 Resource::NotifyInstanceWasDeleted();
60
61 // Please see comments in NotifyLastPluginRefWasDeleted() about why we must
62 // clean up the callbacks.
63 // It is possible that NotifyLastPluginRefWasDeleted() is never called for a
64 // resource. For example, those singleton-style resources such as
65 // GamepadResource never expose references to the plugin and thus won't
66 // receive a NotifyLastPluginRefWasDeleted() call. For those resources, we
67 // need to clean up callbacks when the instance goes away.
68 callbacks_.clear();
69}
70
[email protected]9164da32012-10-16 03:40:5771void PluginResource::SendCreate(Destination dest, const IPC::Message& msg) {
72 if (dest == RENDERER) {
73 DCHECK(!sent_create_to_renderer_);
74 sent_create_to_renderer_ = true;
75 } else {
76 DCHECK(!sent_create_to_browser_);
77 sent_create_to_browser_ = true;
78 }
[email protected]d84e9992012-11-08 22:13:2879 ResourceMessageCallParams params(pp_resource(), GetNextSequence());
[email protected]9164da32012-10-16 03:40:5780 GetSender(dest)->Send(
[email protected]93df81e2012-08-10 22:22:4681 new PpapiHostMsg_ResourceCreated(params, pp_instance(), msg));
[email protected]eccf80312012-07-14 15:43:4282}
83
[email protected]9164da32012-10-16 03:40:5784void PluginResource::Post(Destination dest, const IPC::Message& msg) {
[email protected]d84e9992012-11-08 22:13:2885 ResourceMessageCallParams params(pp_resource(), GetNextSequence());
[email protected]9164da32012-10-16 03:40:5786 SendResourceCall(dest, params, msg);
[email protected]93df81e2012-08-10 22:22:4687}
88
[email protected]e1f5c9b2012-10-04 00:07:4489bool PluginResource::SendResourceCall(
[email protected]9164da32012-10-16 03:40:5790 Destination dest,
[email protected]e1f5c9b2012-10-04 00:07:4491 const ResourceMessageCallParams& call_params,
92 const IPC::Message& nested_msg) {
[email protected]9164da32012-10-16 03:40:5793 return GetSender(dest)->Send(
94 new PpapiHostMsg_ResourceCall(call_params, nested_msg));
[email protected]eccf80312012-07-14 15:43:4295}
96
[email protected]58786932012-10-13 10:16:0897int32_t PluginResource::GenericSyncCall(Destination dest,
98 const IPC::Message& msg,
[email protected]ff44fc12012-10-03 00:52:1699 IPC::Message* reply) {
[email protected]d84e9992012-11-08 22:13:28100 ResourceMessageCallParams params(pp_resource(), GetNextSequence());
[email protected]ff44fc12012-10-03 00:52:16101 params.set_has_callback();
102 ResourceMessageReplyParams reply_params;
[email protected]58786932012-10-13 10:16:08103 bool success = GetSender(dest)->Send(new PpapiHostMsg_ResourceSyncCall(
104 params, msg, &reply_params, reply));
[email protected]ff44fc12012-10-03 00:52:16105 if (success)
106 return reply_params.result();
107 return PP_ERROR_FAILED;
108}
109
[email protected]d84e9992012-11-08 22:13:28110int32_t PluginResource::GetNextSequence() {
111 // Return the value with wraparound, making sure we don't make a sequence
112 // number with a 0 ID. Note that signed wraparound is undefined in C++ so we
113 // manually check.
114 int32_t ret = next_sequence_number_;
115 if (next_sequence_number_ == std::numeric_limits<int32_t>::max())
116 next_sequence_number_ = 1; // Skip 0 which is invalid.
117 else
118 next_sequence_number_++;
119 return ret;
120}
121
[email protected]eccf80312012-07-14 15:43:42122} // namespace proxy
123} // namespace ppapi