1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/traced/probes/android_log/android_log_data_source.h"
18 
19 #include "perfetto/tracing/core/data_source_config.h"
20 #include "src/base/test/test_task_runner.h"
21 #include "src/tracing/core/trace_writer_for_testing.h"
22 #include "test/gtest_and_gmock.h"
23 
24 #include "protos/perfetto/common/android_log_constants.gen.h"
25 #include "protos/perfetto/config/android/android_log_config.gen.h"
26 #include "protos/perfetto/trace/android/android_log.gen.h"
27 
28 using ::perfetto::protos::gen::AndroidLogConfig;
29 using ::perfetto::protos::gen::AndroidLogId;
30 using ::testing::Invoke;
31 using ::testing::Return;
32 
33 namespace perfetto {
34 namespace {
35 
36 class TestAndroidLogDataSource : public AndroidLogDataSource {
37  public:
TestAndroidLogDataSource(const DataSourceConfig & config,base::TaskRunner * task_runner,TracingSessionID id,std::unique_ptr<TraceWriter> writer)38   TestAndroidLogDataSource(const DataSourceConfig& config,
39                            base::TaskRunner* task_runner,
40                            TracingSessionID id,
41                            std::unique_ptr<TraceWriter> writer)
42       : AndroidLogDataSource(config, task_runner, id, std::move(writer)) {}
43 
44   MOCK_METHOD0(ReadEventLogDefinitions, std::string());
45   MOCK_METHOD0(ConnectLogdrSocket, base::UnixSocketRaw());
46 };
47 
48 class AndroidLogDataSourceTest : public ::testing::Test {
49  protected:
AndroidLogDataSourceTest()50   AndroidLogDataSourceTest() {}
51 
CreateInstance(const DataSourceConfig & cfg)52   void CreateInstance(const DataSourceConfig& cfg) {
53     auto writer =
54         std::unique_ptr<TraceWriterForTesting>(new TraceWriterForTesting());
55     writer_raw_ = writer.get();
56     data_source_.reset(
57         new TestAndroidLogDataSource(cfg, &task_runner_, 0, std::move(writer)));
58   }
59 
StartAndSimulateLogd(const std::vector<std::vector<uint8_t>> & fake_events)60   void StartAndSimulateLogd(
61       const std::vector<std::vector<uint8_t>>& fake_events) {
62     base::UnixSocketRaw send_sock;
63     base::UnixSocketRaw recv_sock;
64     // In theory this should be a kSeqPacket. We use kDgram here so that the
65     // test can run also on MacOS (which doesn't support SOCK_SEQPACKET).
66     std::tie(send_sock, recv_sock) = base::UnixSocketRaw::CreatePairPosix(
67         base::SockFamily::kUnix, base::SockType::kDgram);
68     ASSERT_TRUE(send_sock);
69     ASSERT_TRUE(recv_sock);
70 
71     EXPECT_CALL(*data_source_, ConnectLogdrSocket())
72         .WillOnce(Invoke([&recv_sock] { return std::move(recv_sock); }));
73 
74     data_source_->Start();
75 
76     char cmd[64]{};
77     EXPECT_GT(send_sock.Receive(cmd, sizeof(cmd) - 1), 0);
78     EXPECT_STREQ("stream tail=1 lids=0,2,3,4,7", cmd);
79 
80     // Send back log messages emulating Android's logdr socket.
81     for (const auto& buf : fake_events)
82       send_sock.Send(buf.data(), buf.size());
83 
84     auto on_flush = task_runner_.CreateCheckpoint("on_flush");
85     data_source_->Flush(1, on_flush);
86     task_runner_.RunUntilCheckpoint("on_flush");
87   }
88 
89   base::TestTaskRunner task_runner_;
90   std::unique_ptr<TestAndroidLogDataSource> data_source_;
91   TraceWriterForTesting* writer_raw_;
92 
93   const std::vector<std::vector<uint8_t>> kValidTextEvents{
94       // 12-29 23:13:59.679  7546  8991 I ActivityManager:
95       // Killing 11660:com.google.android.videos/u0a168 (adj 985): empty #17
96       {0x55, 0x00, 0x1c, 0x00, 0x7a, 0x1d, 0x00, 0x00, 0x1f, 0x23, 0x00, 0x00,
97        0xb7, 0xff, 0x27, 0x5c, 0xe6, 0x58, 0x7b, 0x28, 0x03, 0x00, 0x00, 0x00,
98        0xe8, 0x03, 0x00, 0x00, 0x04, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74,
99        0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x00, 0x4b, 0x69, 0x6c,
100        0x6c, 0x69, 0x6e, 0x67, 0x20, 0x31, 0x31, 0x36, 0x36, 0x30, 0x3a, 0x63,
101        0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x6e,
102        0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x73,
103        0x2f, 0x75, 0x30, 0x61, 0x31, 0x36, 0x38, 0x20, 0x28, 0x61, 0x64, 0x6a,
104        0x20, 0x39, 0x38, 0x35, 0x29, 0x3a, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79,
105        0x20, 0x23, 0x31, 0x37, 0x00},
106 
107       // 12-29 23:13:59.683  7546  7570 W libprocessgroup:
108       // kill(-11660, 9) failed: No such process
109       {0x39, 0x00, 0x1c, 0x00, 0x7a, 0x1d, 0x00, 0x00, 0x92, 0x1d, 0x00,
110        0x00, 0xb7, 0xff, 0x27, 0x5c, 0x12, 0xf3, 0xbd, 0x28, 0x00, 0x00,
111        0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x05, 0x6c, 0x69, 0x62, 0x70,
112        0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x6f, 0x75, 0x70,
113        0x00, 0x6b, 0x69, 0x6c, 0x6c, 0x28, 0x2d, 0x31, 0x31, 0x36, 0x36,
114        0x30, 0x2c, 0x20, 0x39, 0x29, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
115        0x64, 0x3a, 0x20, 0x4e, 0x6f, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20,
116        0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x00},
117 
118       // 12-29 23:13:59.719  7415  7415 I Zygote:
119       // Process 11660 exited due to signal (9)
120       {0x2f, 0x00, 0x1c, 0x00, 0xf7, 0x1c, 0x00, 0x00, 0xf7, 0x1c, 0x00,
121        0x00, 0xb7, 0xff, 0x27, 0x5c, 0x7c, 0x11, 0xe2, 0x2a, 0x00, 0x00,
122        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5a, 0x79, 0x67, 0x6f,
123        0x74, 0x65, 0x00, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20,
124        0x31, 0x31, 0x36, 0x36, 0x30, 0x20, 0x65, 0x78, 0x69, 0x74, 0x65,
125        0x64, 0x20, 0x64, 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x69,
126        0x67, 0x6e, 0x61, 0x6c, 0x20, 0x28, 0x39, 0x29, 0x00},
127   };
128 
129   const std::vector<std::vector<uint8_t>> kValidBinaryEvents{
130       // 12-30 10:22:08.914 29981 30962 I am_kill :
131       // [0,31730,android.process.acore,985,empty #17]
132       {0x3d, 0x00, 0x1c, 0x00, 0x1d, 0x75, 0x00, 0x00, 0xf2, 0x78, 0x00, 0x00,
133        0x50, 0x9c, 0x28, 0x5c, 0xdb, 0x77, 0x7e, 0x36, 0x02, 0x00, 0x00, 0x00,
134        0xe8, 0x03, 0x00, 0x00, 0x47, 0x75, 0x00, 0x00, 0x03, 0x05, 0x00, 0x00,
135        0x00, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x00, 0x02, 0x15, 0x00, 0x00,
136        0x00, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f,
137        0x63, 0x65, 0x73, 0x73, 0x2e, 0x61, 0x63, 0x6f, 0x72, 0x65, 0x00, 0xd9,
138        0x03, 0x00, 0x00, 0x02, 0x09, 0x00, 0x00, 0x00, 0x65, 0x6d, 0x70, 0x74,
139        0x79, 0x20, 0x23, 0x31, 0x37},
140 
141       // 12-30 10:22:08.946 29981 30962 I am_uid_stopped: 10018
142       {0x09, 0x00, 0x1c, 0x00, 0x1d, 0x75, 0x00, 0x00, 0xf2, 0x78,
143        0x00, 0x00, 0x50, 0x9c, 0x28, 0x5c, 0x24, 0x5a, 0x66, 0x38,
144        0x02, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x65, 0x75,
145        0x00, 0x00, 0x00, 0x22, 0x27, 0x00, 0x00},
146 
147       // 12-30 10:22:08.960 29981 29998 I am_pss  :
148       // [1417,10098,com.google.android.connectivitymonitor,4831232,3723264,0,56053760,0,9,39]
149       {0x72, 0x00, 0x1c, 0x00, 0x1d, 0x75, 0x00, 0x00, 0x2e, 0x75, 0x00, 0x00,
150        0x50, 0x9c, 0x28, 0x5c, 0xf4, 0xd7, 0x44, 0x39, 0x02, 0x00, 0x00, 0x00,
151        0xe8, 0x03, 0x00, 0x00, 0x5f, 0x75, 0x00, 0x00, 0x03, 0x0a, 0x00, 0x89,
152        0x05, 0x00, 0x00, 0x00, 0x72, 0x27, 0x00, 0x00, 0x02, 0x26, 0x00, 0x00,
153        0x00, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
154        0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x6e,
155        0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x6d, 0x6f, 0x6e, 0x69,
156        0x74, 0x6f, 0x72, 0x01, 0x00, 0xb8, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00,
157        0x01, 0x00, 0xd0, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
158        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x50, 0x57, 0x03, 0x00,
159        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
160        0x00, 0x01, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
161 };
162 
TEST_F(AndroidLogDataSourceTest,ParseEventLogDefinitions)163 TEST_F(AndroidLogDataSourceTest, ParseEventLogDefinitions) {
164   CreateInstance(DataSourceConfig());
165   static const char kContents[] = R"(
166 42 answer (to life the universe etc|3)
167 314 pi
168 1003 auditd (avc|3)
169 1004 chatty (dropped|3)
170 1005 tag_def (tag|1),(name|3),(format|3)
171 2718 e
172 2732 storaged_disk_stats (type|3),(start_time|2|3),(end_time|2|3),(read_ios|2|1),(read_merges|2|1),(read_sectors|2|1),(read_ticks|2|3),(write_ios|2|1),(write_merges|2|1),(write_sectors|2|1),(write_ticks|2|3),(o_in_flight|2|1),(io_ticks|2|3),(io_in_queue|2|1)
173 invalid_line (
174 9999 invalid_line2 (
175 1937006964 stats_log (atom_id|1|5),(data|4)
176 )";
177   EXPECT_CALL(*data_source_, ReadEventLogDefinitions())
178       .WillOnce(Return(kContents));
179   data_source_->ParseEventLogDefinitions();
180 
181   auto* fmt = data_source_->GetEventFormat(42);
182   ASSERT_NE(fmt, nullptr);
183   ASSERT_EQ(fmt->name, "answer");
184   ASSERT_EQ(fmt->fields.size(), 1u);
185   ASSERT_EQ(fmt->fields[0], "to life the universe etc");
186 
187   fmt = data_source_->GetEventFormat(314);
188   ASSERT_NE(fmt, nullptr);
189   ASSERT_EQ(fmt->name, "pi");
190   ASSERT_EQ(fmt->fields.size(), 0u);
191 
192   fmt = data_source_->GetEventFormat(1005);
193   ASSERT_NE(fmt, nullptr);
194   ASSERT_EQ(fmt->name, "tag_def");
195   ASSERT_EQ(fmt->fields.size(), 3u);
196   ASSERT_EQ(fmt->fields[0], "tag");
197   ASSERT_EQ(fmt->fields[1], "name");
198   ASSERT_EQ(fmt->fields[2], "format");
199 
200   fmt = data_source_->GetEventFormat(1937006964);
201   ASSERT_NE(fmt, nullptr);
202   ASSERT_EQ(fmt->name, "stats_log");
203   ASSERT_EQ(fmt->fields.size(), 2u);
204   ASSERT_EQ(fmt->fields[0], "atom_id");
205   ASSERT_EQ(fmt->fields[1], "data");
206 }
207 
TEST_F(AndroidLogDataSourceTest,TextEvents)208 TEST_F(AndroidLogDataSourceTest, TextEvents) {
209   DataSourceConfig cfg;
210   CreateInstance(cfg);
211   EXPECT_CALL(*data_source_, ReadEventLogDefinitions()).WillOnce(Return(""));
212   StartAndSimulateLogd(kValidTextEvents);
213 
214   // Read back the data that would have been written into the trace. One packet
215   // with the events, one with stats.
216   auto packets = writer_raw_->GetAllTracePackets();
217   ASSERT_TRUE(packets.size() == 2);
218   auto event_packet = packets[0];
219   auto stats_packet = packets[1];
220   EXPECT_TRUE(stats_packet.android_log().has_stats());
221 
222   EXPECT_EQ(event_packet.android_log().events_size(), 3);
223   const auto& decoded = event_packet.android_log().events();
224 
225   EXPECT_EQ(decoded[0].log_id(), protos::gen::AndroidLogId::LID_SYSTEM);
226   EXPECT_EQ(decoded[0].pid(), 7546);
227   EXPECT_EQ(decoded[0].tid(), 8991);
228   EXPECT_EQ(decoded[0].uid(), 1000);
229   EXPECT_EQ(decoded[0].prio(), protos::gen::AndroidLogPriority::PRIO_INFO);
230   EXPECT_EQ(decoded[0].timestamp(), 1546125239679172326ULL);
231   EXPECT_EQ(decoded[0].tag(), "ActivityManager");
232   EXPECT_EQ(
233       decoded[0].message(),
234       "Killing 11660:com.google.android.videos/u0a168 (adj 985): empty #17");
235 
236   EXPECT_EQ(decoded[1].log_id(), protos::gen::AndroidLogId::LID_DEFAULT);
237   EXPECT_EQ(decoded[1].pid(), 7546);
238   EXPECT_EQ(decoded[1].tid(), 7570);
239   EXPECT_EQ(decoded[1].uid(), 1000);
240   EXPECT_EQ(decoded[1].prio(), protos::gen::AndroidLogPriority::PRIO_WARN);
241   EXPECT_EQ(decoded[1].timestamp(), 1546125239683537170ULL);
242   EXPECT_EQ(decoded[1].tag(), "libprocessgroup");
243   EXPECT_EQ(decoded[1].message(), "kill(-11660, 9) failed: No such process");
244 
245   EXPECT_EQ(decoded[2].log_id(), protos::gen::AndroidLogId::LID_DEFAULT);
246   EXPECT_EQ(decoded[2].pid(), 7415);
247   EXPECT_EQ(decoded[2].tid(), 7415);
248   EXPECT_EQ(decoded[2].uid(), 0);
249   EXPECT_EQ(decoded[2].prio(), protos::gen::AndroidLogPriority::PRIO_INFO);
250   EXPECT_EQ(decoded[2].timestamp(), 1546125239719458684ULL);
251   EXPECT_EQ(decoded[2].tag(), "Zygote");
252   EXPECT_EQ(decoded[2].message(), "Process 11660 exited due to signal (9)");
253 }
254 
TEST_F(AndroidLogDataSourceTest,TextEventsWithTagFiltering)255 TEST_F(AndroidLogDataSourceTest, TextEventsWithTagFiltering) {
256   DataSourceConfig cfg;
257   AndroidLogConfig acfg;
258   acfg.add_filter_tags("Zygote");
259   acfg.add_filter_tags("ActivityManager");
260   acfg.add_filter_tags("Unmatched");
261   acfg.add_filter_tags("libprocessgroupZZ");
262   cfg.set_android_log_config_raw(acfg.SerializeAsString());
263 
264   CreateInstance(cfg);
265   EXPECT_CALL(*data_source_, ReadEventLogDefinitions()).WillOnce(Return(""));
266   StartAndSimulateLogd(kValidTextEvents);
267 
268   auto packets = writer_raw_->GetAllTracePackets();
269   ASSERT_TRUE(packets.size() == 2);
270   auto event_packet = packets[0];
271   auto stats_packet = packets[1];
272   EXPECT_TRUE(stats_packet.android_log().has_stats());
273 
274   EXPECT_EQ(event_packet.android_log().events_size(), 2);
275   const auto& decoded = event_packet.android_log().events();
276   EXPECT_EQ(decoded[0].tag(), "ActivityManager");
277   EXPECT_EQ(decoded[1].tag(), "Zygote");
278 }
279 
TEST_F(AndroidLogDataSourceTest,TextEventsWithPrioFiltering)280 TEST_F(AndroidLogDataSourceTest, TextEventsWithPrioFiltering) {
281   DataSourceConfig cfg;
282   AndroidLogConfig acfg;
283   acfg.set_min_prio(protos::gen::AndroidLogPriority::PRIO_WARN);
284   cfg.set_android_log_config_raw(acfg.SerializeAsString());
285 
286   CreateInstance(cfg);
287   EXPECT_CALL(*data_source_, ReadEventLogDefinitions()).WillOnce(Return(""));
288   StartAndSimulateLogd(kValidTextEvents);
289 
290   auto packets = writer_raw_->GetAllTracePackets();
291   ASSERT_TRUE(packets.size() == 2);
292   auto event_packet = packets[0];
293   auto stats_packet = packets[1];
294   EXPECT_TRUE(stats_packet.android_log().has_stats());
295 
296   EXPECT_EQ(event_packet.android_log().events_size(), 1);
297   const auto& decoded = event_packet.android_log().events();
298   EXPECT_EQ(decoded[0].tag(), "libprocessgroup");
299 }
300 
TEST_F(AndroidLogDataSourceTest,BinaryEvents)301 TEST_F(AndroidLogDataSourceTest, BinaryEvents) {
302   DataSourceConfig cfg;
303   CreateInstance(cfg);
304   static const char kDefs[] = R"(
305 30023 am_kill (User|1|5),(PID|1|5),(Process Name|3),(OomAdj|1|5),(Reason|3)
306 30053 am_uid_stopped (UID|1|5)
307 30047 am_pss (Pid|1|5),(UID|1|5),(Process Name|3),(Pss|2|2),(Uss|2|2),(SwapPss|2|2),(Rss|2|2),(StatType|1|5),(ProcState|1|5),(TimeToCollect|2|2)
308 )";
309   EXPECT_CALL(*data_source_, ReadEventLogDefinitions()).WillOnce(Return(kDefs));
310   StartAndSimulateLogd(kValidBinaryEvents);
311 
312   // Read back the data that would have been written into the trace. One packet
313   // with the events, one with stats.
314   auto packets = writer_raw_->GetAllTracePackets();
315   ASSERT_TRUE(packets.size() == 2);
316   auto event_packet = packets[0];
317   auto stats_packet = packets[1];
318   EXPECT_TRUE(stats_packet.android_log().has_stats());
319 
320   EXPECT_EQ(event_packet.android_log().events_size(), 3);
321   const auto& decoded = event_packet.android_log().events();
322 
323   EXPECT_EQ(decoded[0].log_id(), protos::gen::AndroidLogId::LID_EVENTS);
324   EXPECT_EQ(decoded[0].pid(), 29981);
325   EXPECT_EQ(decoded[0].tid(), 30962);
326   EXPECT_EQ(decoded[0].uid(), 1000);
327   EXPECT_EQ(decoded[0].timestamp(), 1546165328914257883ULL);
328   EXPECT_EQ(decoded[0].tag(), "am_kill");
329   ASSERT_EQ(decoded[0].args_size(), 5);
330   EXPECT_EQ(decoded[0].args()[0].name(), "User");
331   EXPECT_EQ(decoded[0].args()[0].int_value(), 0);
332   EXPECT_EQ(decoded[0].args()[1].name(), "PID");
333   EXPECT_EQ(decoded[0].args()[1].int_value(), 31730);
334   EXPECT_EQ(decoded[0].args()[2].name(), "Process Name");
335   EXPECT_EQ(decoded[0].args()[2].string_value(), "android.process.acore");
336   EXPECT_EQ(decoded[0].args()[3].name(), "OomAdj");
337   EXPECT_EQ(decoded[0].args()[3].int_value(), 985);
338   EXPECT_EQ(decoded[0].args()[4].name(), "Reason");
339   EXPECT_EQ(decoded[0].args()[4].string_value(), "empty #17");
340 
341   EXPECT_EQ(decoded[1].log_id(), protos::gen::AndroidLogId::LID_EVENTS);
342   EXPECT_EQ(decoded[1].pid(), 29981);
343   EXPECT_EQ(decoded[1].tid(), 30962);
344   EXPECT_EQ(decoded[1].uid(), 1000);
345   EXPECT_EQ(decoded[1].timestamp(), 1546165328946231844ULL);
346   EXPECT_EQ(decoded[1].tag(), "am_uid_stopped");
347   ASSERT_EQ(decoded[1].args_size(), 1);
348   EXPECT_EQ(decoded[1].args()[0].name(), "UID");
349   EXPECT_EQ(decoded[1].args()[0].int_value(), 10018);
350 
351   EXPECT_EQ(decoded[2].log_id(), protos::gen::AndroidLogId::LID_EVENTS);
352   EXPECT_EQ(decoded[2].pid(), 29981);
353   EXPECT_EQ(decoded[2].tid(), 29998);
354   EXPECT_EQ(decoded[2].uid(), 1000);
355   EXPECT_EQ(decoded[2].timestamp(), 1546165328960813044ULL);
356   EXPECT_EQ(decoded[2].tag(), "am_pss");
357   ASSERT_EQ(decoded[2].args_size(), 10);
358   EXPECT_EQ(decoded[2].args()[0].name(), "Pid");
359   EXPECT_EQ(decoded[2].args()[0].int_value(), 1417);
360   EXPECT_EQ(decoded[2].args()[1].name(), "UID");
361   EXPECT_EQ(decoded[2].args()[1].int_value(), 10098);
362   EXPECT_EQ(decoded[2].args()[2].name(), "Process Name");
363   EXPECT_EQ(decoded[2].args()[2].string_value(),
364             "com.google.android.connectivitymonitor");
365   EXPECT_EQ(decoded[2].args()[3].name(), "Pss");
366   EXPECT_EQ(decoded[2].args()[3].int_value(), 4831232);
367   EXPECT_EQ(decoded[2].args()[4].name(), "Uss");
368   EXPECT_EQ(decoded[2].args()[4].int_value(), 3723264);
369   EXPECT_EQ(decoded[2].args()[5].name(), "SwapPss");
370   EXPECT_EQ(decoded[2].args()[5].int_value(), 0);
371   EXPECT_EQ(decoded[2].args()[6].name(), "Rss");
372   EXPECT_EQ(decoded[2].args()[6].int_value(), 56053760);
373   EXPECT_EQ(decoded[2].args()[7].name(), "StatType");
374   EXPECT_EQ(decoded[2].args()[7].int_value(), 0);
375   EXPECT_EQ(decoded[2].args()[8].name(), "ProcState");
376   EXPECT_EQ(decoded[2].args()[8].int_value(), 9);
377   EXPECT_EQ(decoded[2].args()[9].name(), "TimeToCollect");
378   EXPECT_EQ(decoded[2].args()[9].int_value(), 39);
379 }
380 
TEST_F(AndroidLogDataSourceTest,BinaryEventsWithTagFiltering)381 TEST_F(AndroidLogDataSourceTest, BinaryEventsWithTagFiltering) {
382   DataSourceConfig cfg;
383   AndroidLogConfig acfg;
384   acfg.add_filter_tags("not mached");
385   acfg.add_filter_tags("am_uid_stopped");
386   cfg.set_android_log_config_raw(acfg.SerializeAsString());
387   CreateInstance(cfg);
388   static const char kDefs[] = R"(
389 30023 am_kill (User|1|5),(PID|1|5),(Process Name|3),(OomAdj|1|5),(Reason|3)
390 30053 am_uid_stopped (UID|1|5)
391 30047 am_pss (Pid|1|5),(UID|1|5),(Process Name|3),(Pss|2|2),(Uss|2|2),(SwapPss|2|2),(Rss|2|2),(StatType|1|5),(ProcState|1|5),(TimeToCollect|2|2)
392 )";
393   EXPECT_CALL(*data_source_, ReadEventLogDefinitions()).WillOnce(Return(kDefs));
394   StartAndSimulateLogd(kValidBinaryEvents);
395 
396   // Read back the data that would have been written into the trace. One packet
397   // with the events, one with stats.
398   auto packets = writer_raw_->GetAllTracePackets();
399   ASSERT_TRUE(packets.size() == 2);
400   auto event_packet = packets[0];
401   auto stats_packet = packets[1];
402   EXPECT_TRUE(stats_packet.android_log().has_stats());
403 
404   EXPECT_EQ(event_packet.android_log().events_size(), 1);
405   const auto& decoded = event_packet.android_log().events();
406   EXPECT_EQ(decoded[0].timestamp(), 1546165328946231844ULL);
407   EXPECT_EQ(decoded[0].tag(), "am_uid_stopped");
408 }
409 
410 }  // namespace
411 }  // namespace perfetto
412