CanProfileAndroid: Inherit app profileability for SDK sandbox process

If the process being profiled is an SDK sandbox process then the uid is
mapped to the corresponding app process uid before profileable and
debuggable checks take place.
This allows the SDK sandbox process to be profiled when the
corresponding app is profileable.

Bug: 228169493
Test: perfetto_unittests --gtest_filter=CanProfileAndroidTest.*
Test: tools/heap_profile -n [sdk_sandbox_process]
Test: tools/cpu_profile -n [sdk_sandbox_process]

Change-Id: I0e977b693f9106e55a09df043b0fdf7a9814456e
diff --git a/src/profiling/common/producer_support.cc b/src/profiling/common/producer_support.cc
index df8316b..482f42f 100644
--- a/src/profiling/common/producer_support.cc
+++ b/src/profiling/common/producer_support.cc
@@ -53,10 +53,12 @@
                        const std::string& build_type,
                        const std::string& packages_list_path) {
   // These are replicated constants from libcutils android_filesystem_config.h
-  constexpr auto kAidAppStart = 10000;     // AID_APP_START
-  constexpr auto kAidAppEnd = 19999;       // AID_APP_END
-  constexpr auto kAidUserOffset = 100000;  // AID_USER_OFFSET
-  constexpr auto kAidSystem = 1000;        // AID_SYSTEM
+  constexpr auto kAidAppStart = 10000;        // AID_APP_START
+  constexpr auto kAidAppEnd = 19999;          // AID_APP_END
+  constexpr auto kAidUserOffset = 100000;     // AID_USER_OFFSET
+  constexpr auto kAidSystem = 1000;           // AID_SYSTEM
+  constexpr auto kAidSdkSandboxStart = 20000; // AID_SDK_SANDBOX_PROCESS_START
+  constexpr auto kAidSdkSandboxEnd = 29999;   // AID_SDK_SANDBOX_PROCESS_END
 
   if (!build_type.empty() && build_type != "user") {
     return true;
@@ -69,11 +71,22 @@
   }
 
   uint64_t uid_without_profile = uid % kAidUserOffset;
-  if (uid_without_profile < kAidAppStart || kAidAppEnd < uid_without_profile) {
+  uint64_t uid_for_lookup = 0;
+
+  if (uid_without_profile >= kAidAppStart &&
+      uid_without_profile <= kAidAppEnd) {
+    uid_for_lookup = uid_without_profile;
+  } else if (uid_without_profile >= kAidSdkSandboxStart &&
+             uid_without_profile <= kAidSdkSandboxEnd) {
+    // Map SDK sandbox process to corresponding app
+    uint64_t sdk_sandbox_offset = kAidSdkSandboxStart - kAidAppStart;
+    uid_for_lookup = uid_without_profile - sdk_sandbox_offset;
+  } else {
     // TODO(fmayer): relax this.
     return false;  // no native services on user.
   }
 
+
   std::string content;
   if (!base::ReadFile(packages_list_path, &content)) {
     PERFETTO_ELOG("Failed to read %s.", packages_list_path.c_str());
@@ -85,7 +98,7 @@
       PERFETTO_ELOG("Failed to parse packages.list.");
       return false;
     }
-    if (pkg.uid != uid_without_profile)
+    if (pkg.uid != uid_for_lookup)
       continue;
     if (!installed_by.empty()) {
       if (pkg.installed_by.empty()) {
diff --git a/src/profiling/common/producer_support_unittest.cc b/src/profiling/common/producer_support_unittest.cc
index 33fdf28..cacd505 100644
--- a/src/profiling/common/producer_support_unittest.cc
+++ b/src/profiling/common/producer_support_unittest.cc
@@ -169,6 +169,42 @@
                                  "user", tmp.path()));
 }
 
+TEST(CanProfileAndroidTest, UserProfileableAppSdkSandbox) {
+    DataSourceConfig ds_config;
+  ds_config.set_enable_extra_guardrails(false);
+  auto tmp = base::TempFile::Create();
+  constexpr char content[] =
+      "invalid.example.profileable 10001 0 "
+      "/data/user/0/invalid.example.profileable default:targetSdkVersion=10000 "
+      "none 1 1\n";
+  base::WriteAll(tmp.fd(), content, sizeof(content));
+  EXPECT_TRUE(CanProfileAndroid(ds_config, 20001, {}, "user", tmp.path()));
+}
+
+TEST(CanProfileAndroidTest, UserNonProfileableAppSdkSandbox) {
+    DataSourceConfig ds_config;
+  ds_config.set_enable_extra_guardrails(false);
+  auto tmp = base::TempFile::Create();
+  constexpr char content[] =
+      "invalid.example.profileable 10001 0 "
+      "/data/user/0/invalid.example.profileable default:targetSdkVersion=10000 "
+      "none 0 1\n";
+  base::WriteAll(tmp.fd(), content, sizeof(content));
+  EXPECT_FALSE(CanProfileAndroid(ds_config, 20001, {}, "user", tmp.path()));
+}
+
+TEST(CanProfileAndroidTest, UserDebuggableAppSdkSandbox) {
+  DataSourceConfig ds_config;
+  ds_config.set_enable_extra_guardrails(false);
+  auto tmp = base::TempFile::Create();
+  constexpr char content[] =
+      "invalid.example.profileable 10001 1 "
+      "/data/user/0/invalid.example.profileable default:targetSdkVersion=10000 "
+      "none 0 1\n";
+  base::WriteAll(tmp.fd(), content, sizeof(content));
+  EXPECT_TRUE(CanProfileAndroid(ds_config, 20001, {}, "user", tmp.path()));
+}
+
 }  // namespace
 }  // namespace profiling
 }  // namespace perfetto