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 #include "src/traced/probes/ftrace/atrace_hal_wrapper.h"
17 
18 #include <dlfcn.h>
19 
20 #include "src/android_internal/atrace_hal.h"
21 
22 namespace perfetto {
23 
24 namespace {
25 constexpr size_t kMaxNumCategories = 64;
26 }
27 
28 struct AtraceHalWrapper::DynamicLibLoader {
29   using ScopedDlHandle = base::ScopedResource<void*, dlclose, nullptr>;
30 
DynamicLibLoaderperfetto::AtraceHalWrapper::DynamicLibLoader31   DynamicLibLoader() {
32     static const char kLibName[] = "libperfetto_android_internal.so";
33     handle_.reset(dlopen(kLibName, RTLD_NOW));
34     if (!handle_) {
35       PERFETTO_PLOG("dlopen(%s) failed", kLibName);
36       return;
37     }
38     void* fn = dlsym(*handle_, "GetCategories");
39     if (!fn) {
40       PERFETTO_PLOG("dlsym(GetCategories) failed");
41       return;
42     }
43     get_categories_ = reinterpret_cast<decltype(get_categories_)>(fn);
44   }
45 
GetCategoriesperfetto::AtraceHalWrapper::DynamicLibLoader46   std::vector<android_internal::TracingVendorCategory> GetCategories() {
47     if (!get_categories_)
48       return std::vector<android_internal::TracingVendorCategory>();
49 
50     std::vector<android_internal::TracingVendorCategory> categories(
51         kMaxNumCategories);
52     size_t num_cat = categories.size();
53     get_categories_(&categories[0], &num_cat);
54     categories.resize(num_cat);
55     return categories;
56   }
57 
58  private:
59   decltype(&android_internal::GetCategories) get_categories_ = nullptr;
60   ScopedDlHandle handle_;
61 };
62 
AtraceHalWrapper()63 AtraceHalWrapper::AtraceHalWrapper() {
64   lib_.reset(new DynamicLibLoader());
65 }
66 
67 AtraceHalWrapper::~AtraceHalWrapper() = default;
68 
69 std::vector<AtraceHalWrapper::TracingVendorCategory>
GetAvailableCategories()70 AtraceHalWrapper::GetAvailableCategories() {
71   auto details = lib_->GetCategories();
72   std::vector<AtraceHalWrapper::TracingVendorCategory> result;
73   for (size_t i = 0; i < details.size(); i++) {
74     AtraceHalWrapper::TracingVendorCategory cat;
75     cat.name = details[i].name;
76     cat.description = details[i].description;
77     result.emplace_back(cat);
78   }
79   return result;
80 }
81 
82 }  // namespace perfetto
83