xref: /aosp_15_r20/external/libchrome/ipc/ipc_test_sink.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef IPC_IPC_TEST_SINK_H_
6*635a8641SAndroid Build Coastguard Worker #define IPC_IPC_TEST_SINK_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
9*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
10*635a8641SAndroid Build Coastguard Worker 
11*635a8641SAndroid Build Coastguard Worker #include <utility>
12*635a8641SAndroid Build Coastguard Worker #include <vector>
13*635a8641SAndroid Build Coastguard Worker 
14*635a8641SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/observer_list.h"
17*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
18*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_channel.h"
19*635a8641SAndroid Build Coastguard Worker 
20*635a8641SAndroid Build Coastguard Worker namespace IPC {
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker class Message;
23*635a8641SAndroid Build Coastguard Worker 
24*635a8641SAndroid Build Coastguard Worker // This test sink provides a "sink" for IPC messages that are sent. It allows
25*635a8641SAndroid Build Coastguard Worker // the caller to query messages received in various different ways.  It is
26*635a8641SAndroid Build Coastguard Worker // designed for tests for objects that use the IPC system.
27*635a8641SAndroid Build Coastguard Worker //
28*635a8641SAndroid Build Coastguard Worker // Typical usage:
29*635a8641SAndroid Build Coastguard Worker //
30*635a8641SAndroid Build Coastguard Worker //   test_sink.ClearMessages();
31*635a8641SAndroid Build Coastguard Worker //   do_something();
32*635a8641SAndroid Build Coastguard Worker //
33*635a8641SAndroid Build Coastguard Worker //   // We should have gotten exactly one update state message.
34*635a8641SAndroid Build Coastguard Worker //   EXPECT_TRUE(test_sink.GetUniqeMessageMatching(ViewHostMsg_Update::ID));
35*635a8641SAndroid Build Coastguard Worker //   // ...and no start load messages.
36*635a8641SAndroid Build Coastguard Worker //   EXPECT_FALSE(test_sink.GetFirstMessageMatching(ViewHostMsg_Start::ID));
37*635a8641SAndroid Build Coastguard Worker //
38*635a8641SAndroid Build Coastguard Worker //   // Now inspect a message. This assumes a message that was declared like
39*635a8641SAndroid Build Coastguard Worker //   // this: IPC_MESSAGE_ROUTED2(ViewMsg_Foo, bool, int)
40*635a8641SAndroid Build Coastguard Worker //   IPC::Message* msg = test_sink.GetFirstMessageMatching(ViewMsg_Foo::ID));
41*635a8641SAndroid Build Coastguard Worker //   ASSERT_TRUE(msg);
42*635a8641SAndroid Build Coastguard Worker //   bool first_param;
43*635a8641SAndroid Build Coastguard Worker //   int second_param;
44*635a8641SAndroid Build Coastguard Worker //   ViewMsg_Foo::Read(msg, &first_param, &second_param);
45*635a8641SAndroid Build Coastguard Worker //
46*635a8641SAndroid Build Coastguard Worker //   // Go on to the next phase of the test.
47*635a8641SAndroid Build Coastguard Worker //   test_sink.ClearMessages();
48*635a8641SAndroid Build Coastguard Worker //
49*635a8641SAndroid Build Coastguard Worker // To read a sync reply, do this:
50*635a8641SAndroid Build Coastguard Worker //
51*635a8641SAndroid Build Coastguard Worker //   IPC::Message* msg = test_sink.GetUniqueMessageMatching(IPC_REPLY_ID);
52*635a8641SAndroid Build Coastguard Worker //   ASSERT_TRUE(msg);
53*635a8641SAndroid Build Coastguard Worker //   base::TupleTypes<ViewHostMsg_Foo::ReplyParam>::ValueTuple reply_data;
54*635a8641SAndroid Build Coastguard Worker //   EXPECT_TRUE(ViewHostMsg_Foo::ReadReplyParam(msg, &reply_data));
55*635a8641SAndroid Build Coastguard Worker //
56*635a8641SAndroid Build Coastguard Worker // You can also register to be notified when messages are posted to the sink.
57*635a8641SAndroid Build Coastguard Worker // This can be useful if you need to wait for a particular message that will
58*635a8641SAndroid Build Coastguard Worker // be posted asynchronously.  Example usage:
59*635a8641SAndroid Build Coastguard Worker //
60*635a8641SAndroid Build Coastguard Worker //   class MyListener : public IPC::Listener {
61*635a8641SAndroid Build Coastguard Worker //    public:
62*635a8641SAndroid Build Coastguard Worker //     MyListener(const base::Closure& closure)
63*635a8641SAndroid Build Coastguard Worker //       : message_received_closure_(closure) {}
64*635a8641SAndroid Build Coastguard Worker //     virtual bool OnMessageReceived(const IPC::Message& msg) {
65*635a8641SAndroid Build Coastguard Worker //       <do something with the message>
66*635a8641SAndroid Build Coastguard Worker //       message_received_closure_.Run();
67*635a8641SAndroid Build Coastguard Worker //       return false;  // to store the message in the sink, or true to drop it
68*635a8641SAndroid Build Coastguard Worker //     }
69*635a8641SAndroid Build Coastguard Worker //    private:
70*635a8641SAndroid Build Coastguard Worker //     base::Closure message_received_closure_;
71*635a8641SAndroid Build Coastguard Worker //   };
72*635a8641SAndroid Build Coastguard Worker //
73*635a8641SAndroid Build Coastguard Worker //   base::RunLoop run_loop;
74*635a8641SAndroid Build Coastguard Worker //   MyListener listener(run_loop.QuitClosure());
75*635a8641SAndroid Build Coastguard Worker //   test_sink.AddFilter(&listener);
76*635a8641SAndroid Build Coastguard Worker //   StartSomeAsynchronousProcess(&test_sink);
77*635a8641SAndroid Build Coastguard Worker //   run_loop.Run();
78*635a8641SAndroid Build Coastguard Worker //   <inspect the results>
79*635a8641SAndroid Build Coastguard Worker //   ...
80*635a8641SAndroid Build Coastguard Worker //
81*635a8641SAndroid Build Coastguard Worker // To hook up the sink, all you need to do is call OnMessageReceived when a
82*635a8641SAndroid Build Coastguard Worker // message is received.
83*635a8641SAndroid Build Coastguard Worker class TestSink : public Channel {
84*635a8641SAndroid Build Coastguard Worker  public:
85*635a8641SAndroid Build Coastguard Worker   TestSink();
86*635a8641SAndroid Build Coastguard Worker   ~TestSink() override;
87*635a8641SAndroid Build Coastguard Worker 
88*635a8641SAndroid Build Coastguard Worker   // Interface in IPC::Channel. This copies the message to the sink and then
89*635a8641SAndroid Build Coastguard Worker   // deletes it.
90*635a8641SAndroid Build Coastguard Worker   bool Send(IPC::Message* message) override;
91*635a8641SAndroid Build Coastguard Worker   bool Connect() override WARN_UNUSED_RESULT;
92*635a8641SAndroid Build Coastguard Worker   void Close() override;
93*635a8641SAndroid Build Coastguard Worker 
94*635a8641SAndroid Build Coastguard Worker   // Used by the source of the messages to send the message to the sink. This
95*635a8641SAndroid Build Coastguard Worker   // will make a copy of the message and store it in the list.
96*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& msg);
97*635a8641SAndroid Build Coastguard Worker 
98*635a8641SAndroid Build Coastguard Worker   // Returns the number of messages in the queue.
message_count()99*635a8641SAndroid Build Coastguard Worker   size_t message_count() const { return messages_.size(); }
100*635a8641SAndroid Build Coastguard Worker 
101*635a8641SAndroid Build Coastguard Worker   // Clears the message queue of saved messages.
102*635a8641SAndroid Build Coastguard Worker   void ClearMessages();
103*635a8641SAndroid Build Coastguard Worker 
104*635a8641SAndroid Build Coastguard Worker   // Returns the message at the given index in the queue. The index may be out
105*635a8641SAndroid Build Coastguard Worker   // of range, in which case the return value is NULL. The returned pointer will
106*635a8641SAndroid Build Coastguard Worker   // only be valid until another message is received or the list is cleared.
107*635a8641SAndroid Build Coastguard Worker   const Message* GetMessageAt(size_t index) const;
108*635a8641SAndroid Build Coastguard Worker 
109*635a8641SAndroid Build Coastguard Worker   // Returns the first message with the given ID in the queue. If there is no
110*635a8641SAndroid Build Coastguard Worker   // message with the given ID, returns NULL. The returned pointer will only be
111*635a8641SAndroid Build Coastguard Worker   // valid until another message is received or the list is cleared.
112*635a8641SAndroid Build Coastguard Worker   const Message* GetFirstMessageMatching(uint32_t id) const;
113*635a8641SAndroid Build Coastguard Worker 
114*635a8641SAndroid Build Coastguard Worker   // Returns the message with the given ID in the queue. If there is no such
115*635a8641SAndroid Build Coastguard Worker   // message or there is more than one of that message, this will return NULL
116*635a8641SAndroid Build Coastguard Worker   // (with the expectation that you'll do an ASSERT_TRUE() on the result).
117*635a8641SAndroid Build Coastguard Worker   // The returned pointer will only be valid until another message is received
118*635a8641SAndroid Build Coastguard Worker   // or the list is cleared.
119*635a8641SAndroid Build Coastguard Worker   const Message* GetUniqueMessageMatching(uint32_t id) const;
120*635a8641SAndroid Build Coastguard Worker 
121*635a8641SAndroid Build Coastguard Worker   // Adds the given listener as a filter to the TestSink.
122*635a8641SAndroid Build Coastguard Worker   // When a message is received by the TestSink, it will be dispatched to
123*635a8641SAndroid Build Coastguard Worker   // the filters, in the order they were added.  If a filter returns true
124*635a8641SAndroid Build Coastguard Worker   // from OnMessageReceived, subsequent filters will not receive the message
125*635a8641SAndroid Build Coastguard Worker   // and the TestSink will not store it.
126*635a8641SAndroid Build Coastguard Worker   void AddFilter(Listener* filter);
127*635a8641SAndroid Build Coastguard Worker 
128*635a8641SAndroid Build Coastguard Worker   // Removes the given filter from the TestSink.
129*635a8641SAndroid Build Coastguard Worker   void RemoveFilter(Listener* filter);
130*635a8641SAndroid Build Coastguard Worker 
131*635a8641SAndroid Build Coastguard Worker  private:
132*635a8641SAndroid Build Coastguard Worker   // The actual list of received messages.
133*635a8641SAndroid Build Coastguard Worker   std::vector<Message> messages_;
134*635a8641SAndroid Build Coastguard Worker   base::ObserverList<Listener> filter_list_;
135*635a8641SAndroid Build Coastguard Worker 
136*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(TestSink);
137*635a8641SAndroid Build Coastguard Worker };
138*635a8641SAndroid Build Coastguard Worker 
139*635a8641SAndroid Build Coastguard Worker }  // namespace IPC
140*635a8641SAndroid Build Coastguard Worker 
141*635a8641SAndroid Build Coastguard Worker #endif  // IPC_IPC_TEST_SINK_H_
142