Added fallback logic for the tracing path.

Bug:71584164
Change-Id: I058e37c276906dc091bae9e9301ad8fd4d5ad30b
diff --git a/src/ftrace_reader/ftrace_controller.cc b/src/ftrace_reader/ftrace_controller.cc
index 81f5b76..a3803eb 100644
--- a/src/ftrace_reader/ftrace_controller.cc
+++ b/src/ftrace_reader/ftrace_controller.cc
@@ -37,8 +37,15 @@
 namespace perfetto {
 namespace {
 
-// TODO(b/68242551): Do not hardcode these paths.
-const char kTracingPath[] = "/sys/kernel/debug/tracing/";
+#if BUILDFLAG(OS_ANDROID)
+const char* kTracingPaths[] = {
+    "/sys/kernel/tracing/", "/sys/kernel/debug/tracing/", nullptr,
+};
+#else
+const char* kTracingPaths[] = {
+    "/sys/kernel/debug/tracing/", nullptr,
+};
+#endif
 
 // TODO(hjd): Expose this as a configurable variable.
 const int kDrainPeriodMs = 100;
@@ -46,10 +53,19 @@
 }  // namespace
 
 // static
+// TODO(taylori): Add a test for tracing paths in integration tests.
 std::unique_ptr<FtraceController> FtraceController::Create(
     base::TaskRunner* runner) {
-  auto ftrace_procfs =
-      std::unique_ptr<FtraceProcfs>(new FtraceProcfs(kTracingPath));
+  size_t index = 0;
+  std::unique_ptr<FtraceProcfs> ftrace_procfs = nullptr;
+  while (!ftrace_procfs && kTracingPaths[index]) {
+    ftrace_procfs = FtraceProcfs::Create(kTracingPaths[index++]);
+  }
+
+  if (!ftrace_procfs) {
+    return nullptr;
+  }
+
   auto table = ProtoTranslationTable::Create(
       ftrace_procfs.get(), GetStaticEventInfo(), GetStaticCommonFieldsInfo());
   return std::unique_ptr<FtraceController>(
diff --git a/src/ftrace_reader/ftrace_procfs.cc b/src/ftrace_reader/ftrace_procfs.cc
index 79b0761..59a0f8e 100644
--- a/src/ftrace_reader/ftrace_procfs.cc
+++ b/src/ftrace_reader/ftrace_procfs.cc
@@ -68,6 +68,14 @@
 
 }  // namespace
 
+// static
+std::unique_ptr<FtraceProcfs> FtraceProcfs::Create(const std::string& root) {
+  if (!CheckRootPath(root)) {
+    return nullptr;
+  }
+  return std::unique_ptr<FtraceProcfs>(new FtraceProcfs(root));
+}
+
 FtraceProcfs::FtraceProcfs(const std::string& root) : root_(root) {}
 FtraceProcfs::~FtraceProcfs() = default;
 
@@ -148,4 +156,10 @@
   return base::OpenFile(path.c_str(), O_RDONLY | O_NONBLOCK);
 }
 
+// static
+bool FtraceProcfs::CheckRootPath(const std::string& root) {
+  base::ScopedFile fd = base::OpenFile(root + "trace", O_RDONLY);
+  return static_cast<bool>(fd);
+}
+
 }  // namespace perfetto
diff --git a/src/ftrace_reader/ftrace_procfs.h b/src/ftrace_reader/ftrace_procfs.h
index 503445a..28475ff 100644
--- a/src/ftrace_reader/ftrace_procfs.h
+++ b/src/ftrace_reader/ftrace_procfs.h
@@ -17,6 +17,7 @@
 #ifndef SRC_FTRACE_READER_FTRACE_PROCFS_H_
 #define SRC_FTRACE_READER_FTRACE_PROCFS_H_
 
+#include <memory>
 #include <string>
 
 #include "perfetto/base/scoped_file.h"
@@ -25,6 +26,8 @@
 
 class FtraceProcfs {
  public:
+  static std::unique_ptr<FtraceProcfs> Create(const std::string& root);
+
   FtraceProcfs(const std::string& root);
   virtual ~FtraceProcfs();
 
@@ -73,6 +76,9 @@
   virtual bool WriteToFile(const std::string& path, const std::string& str);
 
  private:
+  // Checks the trace file is present at the given root path.
+  static bool CheckRootPath(const std::string& root);
+
   const std::string root_;
 };
 
diff --git a/src/ftrace_reader/ftrace_procfs_integrationtest.cc b/src/ftrace_reader/ftrace_procfs_integrationtest.cc
index ccf2154..0fe9b88 100644
--- a/src/ftrace_reader/ftrace_procfs_integrationtest.cc
+++ b/src/ftrace_reader/ftrace_procfs_integrationtest.cc
@@ -50,6 +50,14 @@
 
 }  // namespace
 
+TEST(FtraceProcfsIntegrationTest, CreateWithGoodPath) {
+  EXPECT_TRUE(FtraceProcfs::Create(kTracingPath));
+}
+
+TEST(FtraceProcfsIntegrationTest, CreateWithBadPath) {
+  EXPECT_FALSE(FtraceProcfs::Create(kTracingPath + std::string("bad_path")));
+}
+
 TEST(FtraceProcfsIntegrationTest, ClearTrace) {
   FtraceProcfs ftrace(kTracingPath);
   ResetFtrace(&ftrace);