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