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