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     for (const std::string& category : categories) {
61       args.push_back(category.c_str());
62     }
63     return enable_categories_(&args[0], args.size());
64   }
65 
DisableAllCategoriesperfetto::AtraceHalWrapper::DynamicLibLoader66   bool DisableAllCategories() {
67     if (!disable_all_categories_)
68       return false;
69     return disable_all_categories_();
70   }
71 
ForgetServiceperfetto::AtraceHalWrapper::DynamicLibLoader72   void ForgetService() {
73     if (!forget_service_)
74       return;
75     forget_service_();
76   }
77 };
78 
AtraceHalWrapper()79 AtraceHalWrapper::AtraceHalWrapper() {
80 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
81   lib_.reset(new DynamicLibLoader());
82 #endif
83 }
84 
~AtraceHalWrapper()85 AtraceHalWrapper::~AtraceHalWrapper() {
86   if (lib_)
87     lib_->ForgetService();
88 }
89 
ListCategories()90 std::vector<std::string> AtraceHalWrapper::ListCategories() {
91   if (!lib_)
92     return {};
93   return lib_->ListCategories();
94 }
95 
EnableCategories(const std::vector<std::string> & categories)96 bool AtraceHalWrapper::EnableCategories(
97     const std::vector<std::string>& categories) {
98   if (!lib_)
99     return true;
100   return lib_->EnableCategories(categories);
101 }
102 
DisableAllCategories()103 bool AtraceHalWrapper::DisableAllCategories() {
104   if (!lib_)
105     return true;
106   return lib_->DisableAllCategories();
107 }
108 
109 }  // namespace perfetto
110