1
2 /*
3 * Copyright (C) 2024 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include <cstdint>
19 #include <memory>
20 #include <string>
21
22 #include "src/trace_redaction/prune_package_list.h"
23 #include "test/gtest_and_gmock.h"
24
25 #include "protos/perfetto/trace/android/packages_list.gen.h"
26 #include "protos/perfetto/trace/ps/process_tree.gen.h"
27 #include "protos/perfetto/trace/trace_packet.gen.h"
28
29 namespace perfetto::trace_redaction {
30
31 namespace {
32 using PackageList = protos::gen::PackagesList;
33 using TracePacket = protos::gen::TracePacket;
34 using ProcessTree = protos::gen::ProcessTree;
35
36 constexpr uint64_t kPackageUid = 1037;
37 constexpr std::string_view kPackageName =
38 "com.google.android.networkstack.tethering";
39
AddPackage(uint64_t uid,std::string_view name,PackageList * list)40 void AddPackage(uint64_t uid, std::string_view name, PackageList* list) {
41 auto* package = list->add_packages();
42 package->set_uid(uid);
43 package->set_name(std::string(name));
44 }
45
CreateTestPacket()46 std::string CreateTestPacket() {
47 auto packet = std::make_unique<TracePacket>();
48
49 packet->set_trusted_uid(9999);
50 packet->set_trusted_packet_sequence_id(2);
51 packet->set_previous_packet_dropped(true);
52
53 auto* packages = packet->mutable_packages_list();
54 AddPackage(10205, "com.google.android.uvexposurereporter", packages);
55 AddPackage(10007, "com.android.internal.display.cutout.emulation.noCutout",
56 packages);
57 AddPackage(kPackageUid, kPackageName, packages);
58 AddPackage(10367, "com.android.systemui.clocks.metro", packages);
59
60 return packet->SerializeAsString();
61 }
62
63 // packet {
64 // process_tree {
65 // processes {
66 // pid: 23022
67 // ppid: 1
68 // cmdline: "/vendor/bin/hw/wpa_supplicant"
69 // cmdline: "-O/data/vendor/wifi/wpa/sockets"
70 // cmdline: "-dd"
71 // cmdline: "-g@android:wpa_wlan0"
72 // uid: 1010
73 // }
74 // threads {
75 // tid: 6382
76 // tgid: 18176
77 // }
78 // threads {
79 // tid: 18419
80 // tgid: 18176
81 // }
82 // threads {
83 // tid: 18434
84 // tgid: 18176
85 // }
86 // collection_end_timestamp: 333724398314653
87 // }
88 // trusted_uid: 9999
89 // timestamp: 333724396714922
90 // trusted_packet_sequence_id: 3
91 // trusted_pid: 1085
92 // }
CreateNoPackageListPacket()93 std::string CreateNoPackageListPacket() {
94 auto packet = std::make_unique<TracePacket>();
95
96 packet->set_trusted_uid(9999);
97 packet->set_timestamp(333724396714922);
98 packet->set_trusted_packet_sequence_id(3);
99 packet->set_trusted_pid(1085);
100
101 ProcessTree* tree = packet->mutable_process_tree();
102
103 auto* p0 = tree->add_processes();
104 p0->set_pid(23022);
105 p0->set_ppid(1);
106 p0->add_cmdline("/vendor/bin/hw/wpa_supplicant");
107 p0->add_cmdline("-O/data/vendor/wifi/wpa/sockets");
108 p0->add_cmdline("-dd");
109 p0->add_cmdline("-g@android:wpa_wlan0");
110 p0->set_uid(1010);
111
112 auto* t0 = tree->add_threads();
113 t0->set_tid(6382);
114 t0->set_tgid(18176);
115
116 auto* t1 = tree->add_threads();
117 t1->set_tid(18419);
118 t1->set_tgid(18176);
119
120 auto* t2 = tree->add_threads();
121 t2->set_tid(18434);
122 t2->set_tgid(18176);
123
124 tree->set_collection_end_timestamp(333724398314653);
125
126 return packet->SerializeAsString();
127 }
128 } // namespace
129
TEST(PrunePackageListTest,ReturnsErrorWhenPackageUidIsMissing)130 TEST(PrunePackageListTest, ReturnsErrorWhenPackageUidIsMissing) {
131 auto before = CreateTestPacket();
132
133 const Context context;
134 const PrunePackageList prune;
135 ASSERT_FALSE(prune.Transform(context, &before).ok());
136 }
137
TEST(PrunePackageListTest,NoopWhenThereIsNoPackageList)138 TEST(PrunePackageListTest, NoopWhenThereIsNoPackageList) {
139 Context context;
140 context.package_uid.emplace(1037);
141
142 const auto before = CreateNoPackageListPacket();
143 auto after = CreateNoPackageListPacket();
144
145 ASSERT_EQ(before, after);
146
147 const PrunePackageList prune;
148 ASSERT_TRUE(prune.Transform(context, &after).ok());
149
150 // The buffer should have changed.
151 ASSERT_EQ(before, after);
152 }
153
154 // PrunePackageList should not drop packets, instead it should drop individual
155 // PackageInfo entries.
TEST(PrunePackageListTest,RemovesPackagesInfoFromPackageList)156 TEST(PrunePackageListTest, RemovesPackagesInfoFromPackageList) {
157 Context context;
158 context.package_uid.emplace(1037);
159
160 const auto before = CreateTestPacket();
161 auto after = CreateTestPacket();
162
163 ASSERT_EQ(before, after);
164
165 const PrunePackageList prune;
166 ASSERT_TRUE(prune.Transform(context, &after).ok());
167
168 // The buffer should have changed.
169 ASSERT_NE(before, after);
170
171 protos::gen::TracePacket after_packet;
172 after_packet.ParseFromString(after);
173
174 ASSERT_TRUE(after_packet.has_packages_list());
175 ASSERT_EQ(1, after_packet.packages_list().packages_size());
176
177 ASSERT_TRUE(after_packet.packages_list().packages().at(0).has_uid());
178 ASSERT_EQ(kPackageUid, after_packet.packages_list().packages().at(0).uid());
179
180 ASSERT_TRUE(after_packet.packages_list().packages().at(0).has_name());
181 ASSERT_EQ(kPackageName, after_packet.packages_list().packages().at(0).name());
182 }
183
184 } // namespace perfetto::trace_redaction
185