InputTracer: Adjust traced event sensitivity based on allow-list

An allow-list of packages will be defined in the perfetto config for
input traces. We can only allow an event to traced completely (i.e.
treated as a non-sensitive event) if _all_ of the UIDs that the event is
targeting are allow-listed for the trace.

In each trace instace, we maintain a cache of whether UIDs seen so far
are allow-listed. Since the allow-list is specified through a list of
package names, we must query PackageManager through the InputDispatcher
policy to look up the packages that correspond to each UID that we see.

Bug: 210460522
Test: manual with perfetto
Change-Id: I9c19a5ed941ebc239dccc0363cc6553733e16afd
diff --git a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
index bed753c..b76bec3 100644
--- a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
+++ b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
@@ -22,6 +22,7 @@
 
 #include <android-base/logging.h>
 #include <perfetto/trace/android/android_input_event.pbzero.h>
+#include <private/android_filesystem_config.h>
 
 namespace android::inputdispatcher::trace::impl {
 
@@ -29,6 +30,17 @@
 
 constexpr auto INPUT_EVENT_TRACE_DATA_SOURCE_NAME = "android.input.inputevent";
 
+bool isPermanentlyAllowed(gui::Uid uid) {
+    switch (uid.val()) {
+        case AID_SYSTEM:
+        case AID_SHELL:
+        case AID_ROOT:
+            return true;
+        default:
+            return false;
+    }
+}
+
 } // namespace
 
 // --- PerfettoBackend::InputEventDataSource ---
@@ -55,6 +67,22 @@
     InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) { ctx.Flush(); });
 }
 
+void PerfettoBackend::InputEventDataSource::initializeUidMap(GetPackageUid getPackageUid) {
+    if (mUidMap.has_value()) {
+        return;
+    }
+
+    mUidMap = {{}};
+    for (const auto& rule : mConfig.rules) {
+        for (const auto& package : rule.matchAllPackages) {
+            mUidMap->emplace(package, getPackageUid(package));
+        }
+        for (const auto& package : rule.matchAnyPackages) {
+            mUidMap->emplace(package, getPackageUid(package));
+        }
+    }
+}
+
 bool PerfettoBackend::InputEventDataSource::shouldIgnoreTracedInputEvent(
         const EventType& type) const {
     if (!getFlags().test(TraceFlag::TRACE_DISPATCHER_INPUT_EVENTS)) {
@@ -77,7 +105,6 @@
             return rule.level;
         }
     }
-
     // The event is not traced if it matched zero rules.
     return TraceLevel::TRACE_LEVEL_NONE;
 }
@@ -86,10 +113,31 @@
                                                         const TracedEventArgs& args) const {
     // By default, a rule will match all events. Return early if the rule does not match.
 
+    // Match the event if it is directed to a secure window.
     if (rule.matchSecure.has_value() && *rule.matchSecure != args.isSecure) {
         return false;
     }
 
+    // Match the event if all of its target packages are explicitly allowed in the "match all" list.
+    if (!rule.matchAllPackages.empty() &&
+        !std::all_of(args.targets.begin(), args.targets.end(), [&](const auto& uid) {
+            return isPermanentlyAllowed(uid) ||
+                    std::any_of(rule.matchAllPackages.begin(), rule.matchAllPackages.end(),
+                                [&](const auto& pkg) { return uid == mUidMap->at(pkg); });
+        })) {
+        return false;
+    }
+
+    // Match the event if any of its target packages are allowed in the "match any" list.
+    if (!rule.matchAnyPackages.empty() &&
+        !std::any_of(args.targets.begin(), args.targets.end(), [&](const auto& uid) {
+            return std::any_of(rule.matchAnyPackages.begin(), rule.matchAnyPackages.end(),
+                               [&](const auto& pkg) { return uid == mUidMap->at(pkg); });
+        })) {
+        return false;
+    }
+
+    // The event matches all matchers specified in the rule.
     return true;
 }
 
@@ -99,7 +147,8 @@
 
 std::atomic<int32_t> PerfettoBackend::sNextInstanceId{1};
 
-PerfettoBackend::PerfettoBackend() {
+PerfettoBackend::PerfettoBackend(GetPackageUid getPackagesForUid)
+      : mGetPackageUid(getPackagesForUid) {
     // Use a once-flag to ensure that the data source is only registered once per boot, since
     // we never unregister the InputEventDataSource.
     std::call_once(sDataSourceRegistrationFlag, []() {
@@ -120,6 +169,7 @@
                                        const TracedEventArgs& args) {
     InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
         auto dataSource = ctx.GetDataSourceLocked();
+        dataSource->initializeUidMap(mGetPackageUid);
         if (dataSource->shouldIgnoreTracedInputEvent(event.eventType)) {
             return;
         }
@@ -139,6 +189,7 @@
 void PerfettoBackend::traceKeyEvent(const TracedKeyEvent& event, const TracedEventArgs& args) {
     InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
         auto dataSource = ctx.GetDataSourceLocked();
+        dataSource->initializeUidMap(mGetPackageUid);
         if (dataSource->shouldIgnoreTracedInputEvent(event.eventType)) {
             return;
         }
@@ -159,6 +210,7 @@
                                           const TracedEventArgs& args) {
     InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
         auto dataSource = ctx.GetDataSourceLocked();
+        dataSource->initializeUidMap(mGetPackageUid);
         if (!dataSource->getFlags().test(TraceFlag::TRACE_DISPATCHER_WINDOW_DISPATCH)) {
             return;
         }