1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/traced/probes/ftrace/atrace_hal_wrapper.h"
18 
19 #include "perfetto/base/build_config.h"
20 #include "src/android_internal/atrace_hal.h"
21 #include "src/android_internal/lazy_library_loader.h"
22 
23 namespace perfetto {
24 
25 namespace {
26 constexpr size_t kMaxNumCategories = 64;
27 }
28 
29 struct AtraceHalWrapper::DynamicLibLoader {
30   PERFETTO_LAZY_LOAD(android_internal::ForgetService, forget_service_);
31   PERFETTO_LAZY_LOAD(android_internal::ListCategories, list_categories_);
32   PERFETTO_LAZY_LOAD(android_internal::EnableCategories, enable_categories_);
33   PERFETTO_LAZY_LOAD(android_internal::DisableAllCategories,
34                      disable_all_categories_);
35 
ListCategoriesperfetto::AtraceHalWrapper::DynamicLibLoader36   std::vector<std::string> ListCategories() {
37     std::vector<std::string> results;
38     if (!list_categories_)
39       return results;
40 
41     std::vector<android_internal::TracingVendorCategory> categories(
42         kMaxNumCategories);
43     size_t num_cat = categories.size();
44     bool success = list_categories_(&categories[0], &num_cat);
45     if (!success)
46       return results;
47     categories.resize(num_cat);
48 
49     for (const auto& category : categories) {
50       results.push_back(category.name);
51     }
52 
53     return results;
54   }
55 
EnableCategoriesperfetto::AtraceHalWrapper::DynamicLibLoader56   bool EnableCategories(const std::vector<std::string>& categories) {
57     if (!enable_categories_)
58       return false;
59     std::vector<const char*> args;
60     args.reserve(categories.size());
61     for (const std::string& category : categories) {
62       args.push_back(category.c_str());
63     }
64     return enable_categories_(&args[0], args.size());
65   }
66 
DisableAllCategoriesperfetto::AtraceHalWrapper::DynamicLibLoader67   bool DisableAllCategories() {
68     if (!disable_all_categories_)
69       return false;
70     return disable_all_categories_();
71   }
72 
ForgetServiceperfetto::AtraceHalWrapper::DynamicLibLoader73   void ForgetService() {
74     if (!forget_service_)
75       return;
76     forget_service_();
77   }
78 };
79 
AtraceHalWrapper()80 AtraceHalWrapper::AtraceHalWrapper() {
81 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
82   lib_.reset(new DynamicLibLoader());
83 #endif
84 }
85 
~AtraceHalWrapper()86 AtraceHalWrapper::~AtraceHalWrapper() {
87   if (lib_)
88     lib_->ForgetService();
89 }
90 
ListCategories()91 std::vector<std::string> AtraceHalWrapper::ListCategories() {
92   if (!lib_)
93     return {};
94   return lib_->ListCategories();
95 }
96 
EnableCategories(const std::vector<std::string> & categories)97 bool AtraceHalWrapper::EnableCategories(
98     const std::vector<std::string>& categories) {
99   if (!lib_)
100     return true;
101   return lib_->EnableCategories(categories);
102 }
103 
DisableAllCategories()104 bool AtraceHalWrapper::DisableAllCategories() {
105   if (!lib_)
106     return true;
107   return lib_->DisableAllCategories();
108 }
109 
110 }  // namespace perfetto
111