Also include selected state when returning AXValue.
[chromium-blink-merge.git] / chrome_frame / sync_msg_reply_dispatcher.h
bloba1687886bb80ac853547f9270bec358aa8d6f2b5
1 // Copyright (c) 2009 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.
5 #ifndef CHROME_FRAME_SYNC_MSG_REPLY_DISPATCHER_H_
6 #define CHROME_FRAME_SYNC_MSG_REPLY_DISPATCHER_H_
8 #include <deque>
10 #include "base/callback.h"
11 #include "base/synchronization/lock.h"
12 #include "ipc/ipc_channel_proxy.h"
14 // Base class used to allow synchronous IPC messages to be sent and
15 // received in an asynchronous manner. To use this class add it as a filter to
16 // your IPC channel using ChannelProxy::AddFilter(). From then on, before
17 // sending a synchronous message, call SyncMessageReplyDispatcher::Push() with
18 // a callback and a key. This class will then handle the message response and
19 // will call the callback when it is received.
21 // This class is intended to be extended by classes implementing
22 // HandleMessageType with delegation for the messages they expect to receive in
23 // cases where you care about the return values of synchronous messages.
25 // Sample usage pattern:
26 // Define a class which inherits from SyncMessageCallContext which specifies
27 // the output_type tuple and has a Completed member function.
28 // class SampleContext
29 // : public SyncMessageReplyDispatcher::SyncMessageCallContext {
30 // public:
31 // typedef Tuple1<int> output_type;
32 // void Completed(int arg) {}
33 // };
35 // // Add handling for desired message types.
36 // class SyncMessageReplyDispatcherImpl : public SyncMessageReplyDispatcher {
37 // virtual bool HandleMessageType(const IPC::Message& msg,
38 // SyncMessageReplyDispatcher* context) {
39 // switch (context->message_type()) {
40 // case AutomationMsg_CreateExternalTab::ID:
41 // InvokeCallback<CreateExternalTabContext>(msg, context);
42 // break;
43 // [HANDLING FOR OTHER EXPECTED MESSAGE TYPES]
44 // }
45 // }
47 // // Add the filter
48 // IPC::SyncChannel channel_;
49 // channel_.AddFilter(new SyncMessageReplyDispatcherImpl());
51 // sync_->Push(msg, new SampleContext, this);
52 // channel_->ChannelProxy::Send(msg);
54 class SyncMessageReplyDispatcher : public IPC::ChannelProxy::MessageFilter {
55 public:
56 class SyncMessageCallContext {
57 public:
58 SyncMessageCallContext()
59 : id_(0),
60 message_type_(0),
61 key_(NULL) {}
63 virtual ~SyncMessageCallContext() {}
65 uint32 message_type() const {
66 return message_type_;
69 private:
70 int id_;
71 uint32 message_type_;
72 void* key_;
74 friend class SyncMessageReplyDispatcher;
77 SyncMessageReplyDispatcher() {}
78 void Push(IPC::SyncMessage* msg, SyncMessageCallContext* context,
79 void* key);
80 void Cancel(void* key);
82 protected:
83 typedef std::deque<SyncMessageCallContext*> PendingSyncMessageQueue;
85 SyncMessageCallContext* GetContext(const IPC::Message& msg);
87 virtual bool OnMessageReceived(const IPC::Message& msg);
89 // Child classes must implement a handler for the message types they are
90 // interested in handling responses for. If you don't care about the replies
91 // to any of the sync messages you are handling, then you don't have to
92 // implement this.
93 virtual bool HandleMessageType(const IPC::Message& msg,
94 SyncMessageCallContext* context);
96 template <typename T>
97 void InvokeCallback(const IPC::Message& msg,
98 SyncMessageCallContext* call_context) {
99 if (!call_context || !call_context->key_) {
100 NOTREACHED() << "Invalid context parameter";
101 return;
104 T* context = static_cast<T*>(call_context);
105 T::output_type tmp; // Acts as "initializer" for output parameters.
106 IPC::ParamDeserializer<T::output_type> deserializer(tmp);
107 if (deserializer.MessageReplyDeserializer::SerializeOutputParameters(msg)) {
108 DispatchToMethod(context, &T::Completed, deserializer.out_);
109 delete context;
110 } else {
111 // TODO(stoyan): How to handle errors?
115 PendingSyncMessageQueue message_queue_;
116 base::Lock message_queue_lock_;
119 #endif // CHROME_FRAME_SYNC_MSG_REPLY_DISPATCHER_H_