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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
// Copyright (c) 2012 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.
// This file provides infrastructure for dispatching host resource reply
// messages. Normal IPC Reply handlers can't take extra parameters.
// We want to take a ResourceMessageReplyParams as a parameter.
#ifndef PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_
#define PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_
#include "base/profiler/scoped_profile.h" // For TRACK_RUN_IN_IPC_HANDLER.
#include "ipc/ipc_message_macros.h"
#include "ppapi/c/pp_errors.h"
namespace ppapi {
namespace proxy {
class ResourceMessageReplyParams;
template <class ObjT, class Method>
inline void DispatchResourceReply(ObjT* obj, Method method,
const ResourceMessageReplyParams& params,
const Tuple0& arg) {
(obj->*method)(params);
}
template <class ObjT, class Method, class A>
inline void DispatchResourceReply(ObjT* obj, Method method,
const ResourceMessageReplyParams& params,
const Tuple1<A>& arg) {
return (obj->*method)(params, arg.a);
}
template<class ObjT, class Method, class A, class B>
inline void DispatchResourceReply(ObjT* obj, Method method,
const ResourceMessageReplyParams& params,
const Tuple2<A, B>& arg) {
return (obj->*method)(params, arg.a, arg.b);
}
template<class ObjT, class Method, class A, class B, class C>
inline void DispatchResourceReply(ObjT* obj, Method method,
const ResourceMessageReplyParams& params,
const Tuple3<A, B, C>& arg) {
return (obj->*method)(params, arg.a, arg.b, arg.c);
}
template<class ObjT, class Method, class A, class B, class C, class D>
inline void DispatchResourceReply(ObjT* obj, Method method,
const ResourceMessageReplyParams& params,
const Tuple4<A, B, C, D>& arg) {
return (obj->*method)(params, arg.a, arg.b, arg.c, arg.d);
}
template<class ObjT, class Method, class A, class B, class C, class D, class E>
inline void DispatchResourceReply(ObjT* obj, Method method,
const ResourceMessageReplyParams& params,
const Tuple5<A, B, C, D, E>& arg) {
return (obj->*method)(params, arg.a, arg.b, arg.c, arg.d, arg.e);
}
// Used to dispatch resource replies. In most cases, you should not call this
// function to dispatch a resource reply manually, but instead use
// |PluginResource::CallBrowser|/|PluginResource::CallRenderer| with a
// |base::Callback| which will be called when a reply message is received
// (see plugin_resource.h).
//
// This function will call your callback with the nested reply message's
// parameters on success. On failure, your callback will be called with each
// parameter having its default constructed value.
//
// Resource replies are a bit weird in that the host will automatically
// generate a reply in error cases (when the call handler returns error rather
// than returning "completion pending"). This makes it more convenient to write
// the call message handlers. But this also means that the reply handler has to
// handle both the success case (when all of the reply message paramaters are
// specified) and the error case (when the nested reply message is empty).
// In both cases the resource will want to issue completion callbacks to the
// plugin.
//
// This function handles the error case by calling your reply handler with the
// default value for each paramater in the error case. In most situations this
// will be the right thing. You should always dispatch completion callbacks
// using the result code present in the ResourceMessageReplyParams.
template<class MsgClass, class ObjT, class Method>
void DispatchResourceReplyOrDefaultParams(
ObjT* obj,
Method method,
const ResourceMessageReplyParams& reply_params,
const IPC::Message& msg) {
typename MsgClass::Schema::Param msg_params;
// We either expect the nested message type to match, or that there is no
// nested message. No nested message indicates a default reply sent from
// the host: when the resource message handler returns an error, a reply
// is implicitly sent with no nested message.
DCHECK(msg.type() == MsgClass::ID || msg.type() == 0)
<< "Resource reply message of unexpected type.";
if (msg.type() == MsgClass::ID && MsgClass::Read(&msg, &msg_params)) {
// Message type matches and the parameters were successfully read.
DispatchResourceReply(obj, method, reply_params, msg_params);
} else {
// The nested message is empty because the host handler didn't explicitly
// send a reply (likely), or you screwed up and didn't use the correct
// message type when calling this function (you should have hit the
// assertion above, Einstein).
//
// Dispatch the reply function with the default parameters. We explicitly
// use a new Params() structure since if the Read failed due to an invalid
// message, the params could have been partially filled in.
DispatchResourceReply(obj, method, reply_params,
typename MsgClass::Schema::Param());
}
}
// Template specialization for |Callback|s that only accept a
// |ResourceMessageReplyParams|. In this case |msg| shouldn't contain any
// arguments, so just call the |method| with the |reply_params|.
template<class MsgClass, class Method>
void DispatchResourceReplyOrDefaultParams(
base::Callback<void(const ResourceMessageReplyParams&)>* obj,
Method method,
const ResourceMessageReplyParams& reply_params,
const IPC::Message& msg) {
DCHECK(msg.type() == MsgClass::ID || msg.type() == 0)
<< "Resource reply message of unexpected type.";
return (obj->*method)(reply_params);
}
} // namespace proxy
} // namespace ppapi
#endif // PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_
|