Move CanProfile to src/profiling/common.
We will also use that in traced_perf.
Change-Id: I9beb9ce0b030d7419bc60c187591fffe31b7bdf9
diff --git a/Android.bp b/Android.bp
index 451c339..e6fe0cc 100644
--- a/Android.bp
+++ b/Android.bp
@@ -79,6 +79,7 @@
":perfetto_src_profiling_common_interner",
":perfetto_src_profiling_common_interning_output",
":perfetto_src_profiling_common_proc_utils",
+ ":perfetto_src_profiling_common_producer_support",
":perfetto_src_profiling_common_profiler_guardrails",
":perfetto_src_profiling_common_unwind_support",
":perfetto_src_profiling_memory_daemon",
@@ -332,6 +333,7 @@
":perfetto_src_profiling_common_interner",
":perfetto_src_profiling_common_interning_output",
":perfetto_src_profiling_common_proc_utils",
+ ":perfetto_src_profiling_common_producer_support",
":perfetto_src_profiling_common_profiler_guardrails",
":perfetto_src_profiling_common_unwind_support",
":perfetto_src_profiling_memory_client",
@@ -1710,6 +1712,7 @@
":perfetto_src_profiling_common_interner",
":perfetto_src_profiling_common_interning_output",
":perfetto_src_profiling_common_proc_utils",
+ ":perfetto_src_profiling_common_producer_support",
":perfetto_src_profiling_common_profiler_guardrails",
":perfetto_src_profiling_common_unwind_support",
":perfetto_src_profiling_memory_client",
@@ -6839,6 +6842,14 @@
],
}
+// GN: //src/profiling/common:producer_support
+filegroup {
+ name: "perfetto_src_profiling_common_producer_support",
+ srcs: [
+ "src/profiling/common/producer_support.cc",
+ ],
+}
+
// GN: //src/profiling/common:profiler_guardrails
filegroup {
name: "perfetto_src_profiling_common_profiler_guardrails",
@@ -6853,6 +6864,7 @@
srcs: [
"src/profiling/common/interner_unittest.cc",
"src/profiling/common/proc_utils_unittest.cc",
+ "src/profiling/common/producer_support_unittest.cc",
"src/profiling/common/profiler_guardrails_unittest.cc",
],
}
@@ -8680,6 +8692,7 @@
":perfetto_src_profiling_common_interner",
":perfetto_src_profiling_common_interning_output",
":perfetto_src_profiling_common_proc_utils",
+ ":perfetto_src_profiling_common_producer_support",
":perfetto_src_profiling_common_profiler_guardrails",
":perfetto_src_profiling_common_unittests",
":perfetto_src_profiling_common_unwind_support",
diff --git a/src/profiling/common/BUILD.gn b/src/profiling/common/BUILD.gn
index a8b948f..583edc6 100644
--- a/src/profiling/common/BUILD.gn
+++ b/src/profiling/common/BUILD.gn
@@ -76,6 +76,19 @@
]
}
+source_set("producer_support") {
+ deps = [
+ "../../../gn:default_deps",
+ "../../base",
+ "../../traced/probes/packages_list:packages_list_parser",
+ "../../tracing/core",
+ ]
+ sources = [
+ "producer_support.cc",
+ "producer_support.h",
+ ]
+}
+
source_set("profiler_guardrails") {
deps = [
":proc_utils",
@@ -94,16 +107,19 @@
deps = [
":interner",
":proc_utils",
+ ":producer_support",
":profiler_guardrails",
"../../../gn:default_deps",
"../../../gn:gtest_and_gmock",
"../../../include/perfetto/profiling:normalize",
"../../base",
"../../base:test_support",
+ "../../tracing/core",
]
sources = [
"interner_unittest.cc",
"proc_utils_unittest.cc",
+ "producer_support_unittest.cc",
"profiler_guardrails_unittest.cc",
]
}
diff --git a/src/profiling/common/producer_support.cc b/src/profiling/common/producer_support.cc
new file mode 100644
index 0000000..d6a58ec
--- /dev/null
+++ b/src/profiling/common/producer_support.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/profiling/common/producer_support.h"
+
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/tracing/core/data_source_config.h"
+
+#include "src/traced/probes/packages_list/packages_list_parser.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/system_properties.h>
+#endif
+
+namespace perfetto {
+namespace profiling {
+
+bool CanProfile(const DataSourceConfig& ds_config, uint64_t uid) {
+// We restrict by !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) because a
+// sideloaded heapprofd should not be restricted by this. Do note though that,
+// at the moment, there isn't really a way to sideload a functioning heapprofd
+// onto user builds.
+#if !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) || \
+ !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ base::ignore_result(ds_config);
+ base::ignore_result(uid);
+ return true;
+#else
+ char buf[PROP_VALUE_MAX + 1] = {};
+ int ret = __system_property_get("ro.build.type", buf);
+ PERFETTO_CHECK(ret >= 0);
+ return CanProfileAndroid(ds_config, uid, std::string(buf),
+ "/data/system/packages.list");
+#endif
+}
+
+bool CanProfileAndroid(const DataSourceConfig& ds_config,
+ uint64_t uid,
+ 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
+
+ if (build_type != "user") {
+ return true;
+ }
+
+ if (ds_config.enable_extra_guardrails()) {
+ return false; // no extra guardrails on user builds.
+ }
+
+ uint64_t uid_without_profile = uid % kAidUserOffset;
+ if (uid_without_profile < kAidAppStart || kAidAppEnd < uid_without_profile) {
+ // 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());
+ return false;
+ }
+ for (base::StringSplitter ss(std::move(content), '\n'); ss.Next();) {
+ Package pkg;
+ if (!ReadPackagesListLine(ss.cur_token(), &pkg)) {
+ PERFETTO_ELOG("Failed to parse packages.list.");
+ return false;
+ }
+ if (pkg.uid == uid_without_profile &&
+ (pkg.profileable_from_shell || pkg.debuggable)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/common/producer_support.h b/src/profiling/common/producer_support.h
new file mode 100644
index 0000000..6f63e47
--- /dev/null
+++ b/src/profiling/common/producer_support.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROFILING_COMMON_PRODUCER_SUPPORT_H_
+#define SRC_PROFILING_COMMON_PRODUCER_SUPPORT_H_
+
+#include <inttypes.h>
+#include <string>
+
+#include "perfetto/tracing/core/forward_decls.h"
+
+namespace perfetto {
+namespace profiling {
+
+bool CanProfile(const DataSourceConfig& ds_config, uint64_t uid);
+bool CanProfileAndroid(const DataSourceConfig& ds_config,
+ uint64_t uid,
+ const std::string& build_type,
+ const std::string& packages_list_path);
+
+} // namespace profiling
+} // namespace perfetto
+
+#endif // SRC_PROFILING_COMMON_PRODUCER_SUPPORT_H_
diff --git a/src/profiling/common/producer_support_unittest.cc b/src/profiling/common/producer_support_unittest.cc
new file mode 100644
index 0000000..df2129a
--- /dev/null
+++ b/src/profiling/common/producer_support_unittest.cc
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/profiling/common/producer_support.h"
+
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/temp_file.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/tracing/core/data_source_config.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace profiling {
+namespace {
+
+TEST(CanProfileAndroidTest, NonUserSystemExtraGuardrails) {
+ DataSourceConfig ds_config;
+ ds_config.set_enable_extra_guardrails(true);
+ EXPECT_TRUE(CanProfileAndroid(ds_config, 1, "userdebug", "/dev/null"));
+}
+
+TEST(CanProfileAndroidTest, NonUserNonProfileableApp) {
+ 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_TRUE(CanProfileAndroid(ds_config, 10001, "userdebug", tmp.path()));
+}
+
+TEST(CanProfileAndroidTest, NonUserNonProfileableAppExtraGuardrails) {
+ DataSourceConfig ds_config;
+ ds_config.set_enable_extra_guardrails(true);
+ 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_TRUE(CanProfileAndroid(ds_config, 10001, "userdebug", tmp.path()));
+}
+
+TEST(CanProfileAndroidTest, UserProfileableApp) {
+ 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, 10001, "user", tmp.path()));
+}
+
+TEST(CanProfileAndroidTest, UserProfileableAppExtraGuardrails) {
+ DataSourceConfig ds_config;
+ ds_config.set_enable_extra_guardrails(true);
+ 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_FALSE(CanProfileAndroid(ds_config, 10001, "user", tmp.path()));
+}
+
+TEST(CanProfileAndroidTest, UserProfileableAppMultiuser) {
+ 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, 210001, "user", tmp.path()));
+}
+
+TEST(CanProfileAndroidTest, UserNonProfileableApp) {
+ 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, 10001, "user", tmp.path()));
+}
+
+TEST(CanProfileAndroidTest, UserDebuggableApp) {
+ 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, 10001, "user", tmp.path()));
+}
+
+} // namespace
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/memory/BUILD.gn b/src/profiling/memory/BUILD.gn
index 4d143af..c1b9623 100644
--- a/src/profiling/memory/BUILD.gn
+++ b/src/profiling/memory/BUILD.gn
@@ -241,13 +241,13 @@
"../../../protos/perfetto/config/profiling:cpp",
"../../base",
"../../base:unix_socket",
- "../../traced/probes/packages_list:packages_list_parser",
"../../tracing/core",
"../../tracing/ipc/producer",
"../common:callstack_trie",
"../common:interner",
"../common:interning_output",
"../common:proc_utils",
+ "../common:producer_support",
"../common:profiler_guardrails",
"../common:unwind_support",
]
diff --git a/src/profiling/memory/heapprofd_producer.cc b/src/profiling/memory/heapprofd_producer.cc
index f00bc0c..31c71e5 100644
--- a/src/profiling/memory/heapprofd_producer.cc
+++ b/src/profiling/memory/heapprofd_producer.cc
@@ -39,10 +39,10 @@
#include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
+#include "src/profiling/common/producer_support.h"
#include "src/profiling/common/profiler_guardrails.h"
#include "src/profiling/memory/unwound_messages.h"
#include "src/profiling/memory/wire_protocol.h"
-#include "src/traced/probes/packages_list/packages_list_parser.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/system_properties.h>
@@ -1235,61 +1235,5 @@
}
}
-bool CanProfile(const DataSourceConfig& ds_config, uint64_t uid) {
-#if !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
- base::ignore_result(ds_config);
- base::ignore_result(uid);
- return true;
-#else
- char buf[PROP_VALUE_MAX + 1] = {};
- int ret = __system_property_get("ro.build.type", buf);
- PERFETTO_CHECK(ret >= 0);
- return CanProfileAndroid(ds_config, uid, std::string(buf),
- "/data/system/packages.list");
-#endif
-}
-
-bool CanProfileAndroid(const DataSourceConfig& ds_config,
- uint64_t uid,
- 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
-
- if (build_type != "user") {
- return true;
- }
-
- if (ds_config.enable_extra_guardrails()) {
- return false; // no extra guardrails on user builds.
- }
-
- uint64_t uid_without_profile = uid % kAidUserOffset;
- if (uid_without_profile < kAidAppStart || kAidAppEnd < uid_without_profile) {
- // 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());
- return false;
- }
- for (base::StringSplitter ss(std::move(content), '\n'); ss.Next();) {
- Package pkg;
- if (!ReadPackagesListLine(ss.cur_token(), &pkg)) {
- PERFETTO_ELOG("Failed to parse packages.list.");
- return false;
- }
- if (pkg.uid == uid_without_profile &&
- (pkg.profileable_from_shell || pkg.debuggable)) {
- return true;
- }
- }
- return false;
-}
-
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/memory/heapprofd_producer.h b/src/profiling/memory/heapprofd_producer.h
index 5e16aee..20fc910 100644
--- a/src/profiling/memory/heapprofd_producer.h
+++ b/src/profiling/memory/heapprofd_producer.h
@@ -67,12 +67,6 @@
const HeapprofdConfig& heapprofd_config,
ClientConfiguration* cli_config);
-bool CanProfile(const DataSourceConfig& ds_config, uint64_t uid);
-bool CanProfileAndroid(const DataSourceConfig& ds_config,
- uint64_t uid,
- const std::string& build_type,
- const std::string& packages_list_path);
-
// Heap profiling producer. Can be instantiated in two modes, central and
// child (also referred to as fork mode).
//
diff --git a/src/profiling/memory/heapprofd_producer_unittest.cc b/src/profiling/memory/heapprofd_producer_unittest.cc
index fe18cf4..8a75145 100644
--- a/src/profiling/memory/heapprofd_producer_unittest.cc
+++ b/src/profiling/memory/heapprofd_producer_unittest.cc
@@ -202,95 +202,5 @@
4 * 4096u);
}
-TEST(CanProfileAndroidTest, NonUserSystemExtraGuardrails) {
- DataSourceConfig ds_config;
- ds_config.set_enable_extra_guardrails(true);
- EXPECT_TRUE(CanProfileAndroid(ds_config, 1, "userdebug", "/dev/null"));
-}
-
-TEST(CanProfileAndroidTest, NonUserNonProfileableApp) {
- 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_TRUE(CanProfileAndroid(ds_config, 10001, "userdebug", tmp.path()));
-}
-
-TEST(CanProfileAndroidTest, NonUserNonProfileableAppExtraGuardrails) {
- DataSourceConfig ds_config;
- ds_config.set_enable_extra_guardrails(true);
- 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_TRUE(CanProfileAndroid(ds_config, 10001, "userdebug", tmp.path()));
-}
-
-TEST(CanProfileAndroidTest, UserProfileableApp) {
- 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, 10001, "user", tmp.path()));
-}
-
-TEST(CanProfileAndroidTest, UserProfileableAppExtraGuardrails) {
- DataSourceConfig ds_config;
- ds_config.set_enable_extra_guardrails(true);
- 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_FALSE(CanProfileAndroid(ds_config, 10001, "user", tmp.path()));
-}
-
-TEST(CanProfileAndroidTest, UserProfileableAppMultiuser) {
- 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, 210001, "user", tmp.path()));
-}
-
-TEST(CanProfileAndroidTest, UserNonProfileableApp) {
- 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, 10001, "user", tmp.path()));
-}
-
-TEST(CanProfileAndroidTest, UserDebuggableApp) {
- 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, 10001, "user", tmp.path()));
-}
-
} // namespace profiling
} // namespace perfetto