blob: 041fe7a2f7363bbf309d3ce75ddf3018db1b307d [file] [log] [blame]
Orion Hodson119733d2019-01-30 15:14:41 +00001/*
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 "palette/palette.h"
18
19#include <dlfcn.h>
20#include <stdlib.h>
21
22#include <android/log.h>
23#include <android-base/macros.h>
24
25namespace {
26
27// Logging tag.
28static constexpr const char* kLogTag = "libartpalette";
29
30// Name of the palette library present in the /system partition.
31static constexpr const char* kPaletteSystemLibrary = "libartpalette-system.so";
32
33// Generic method used when a dynamically loaded palette instance does not
34// support a method.
35enum PaletteStatus PaletteMethodNotSupported() {
36 return PaletteStatus::kNotSupported;
37}
38
39// Declare type aliases for pointers to each function in the interface.
40#define PALETTE_METHOD_TYPE_ALIAS(Name, ...) \
41 using Name ## Method = PaletteStatus(*)(__VA_ARGS__);
42PALETTE_METHOD_LIST(PALETTE_METHOD_TYPE_ALIAS)
43#undef PALETTE_METHOD_TYPE_ALIAS
44
45// Singleton class responsible for dynamically loading the palette library and
46// binding functions there to method pointers.
47class PaletteLoader {
48 public:
49 static PaletteLoader& Instance() {
50 static PaletteLoader instance;
51 return instance;
52 }
53
54 // Accessor methods to get instances of palette methods.
55#define PALETTE_LOADER_METHOD_ACCESSOR(Name, ...) \
56 Name ## Method Get ## Name ## Method() const { return Name ## Method ## _; }
57PALETTE_METHOD_LIST(PALETTE_LOADER_METHOD_ACCESSOR)
58#undef PALETTE_LOADER_METHOD_ACCESSOR
59
60 private:
61 PaletteLoader();
62
63 static void* OpenLibrary();
64 static void* GetMethod(void* palette_lib, const char* name);
65
66 // Handle to the palette library from dlopen().
67 void* palette_lib_;
68
69 // Fields to store pointers to palette methods.
70#define PALETTE_LOADER_METHOD_FIELD(Name, ...) \
71 const Name ## Method Name ## Method ## _;
72 PALETTE_METHOD_LIST(PALETTE_LOADER_METHOD_FIELD)
73#undef PALETTE_LOADER_METHOD_FIELD
74
75 DISALLOW_COPY_AND_ASSIGN(PaletteLoader);
76};
77
78void* PaletteLoader::OpenLibrary() {
Orion Hodson81fb0fb2019-02-01 10:09:39 +000079 void* handle = dlopen(kPaletteSystemLibrary, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Orion Hodson119733d2019-01-30 15:14:41 +000080 if (handle == nullptr) {
81 // dlerror message includes details of error and file being opened.
82 __android_log_assert(nullptr, kLogTag, "%s", dlerror());
83 }
84 return handle;
85}
86
87void* PaletteLoader::GetMethod(void* palette_lib, const char* name) {
88 void* method = nullptr;
89 if (palette_lib != nullptr) {
90 method = dlsym(palette_lib, name);
91 }
92 if (method == nullptr) {
93 return reinterpret_cast<void*>(PaletteMethodNotSupported);
94 }
95 // TODO(oth): consider new GetMethodSignature() in the Palette API which
96 // would allow sanity checking the type signatures.
97 return method;
98}
99
100PaletteLoader::PaletteLoader() :
101 palette_lib_(OpenLibrary())
102#define PALETTE_LOADER_BIND_METHOD(Name, ...) \
103 , Name ## Method ## _(reinterpret_cast<Name ## Method>(GetMethod(palette_lib_, #Name)))
104 PALETTE_METHOD_LIST(PALETTE_LOADER_BIND_METHOD)
105#undef PALETTE_LOADER_BIND_METHOD
106{
107}
108
109} // namespace
110
111extern "C" {
112
113enum PaletteStatus PaletteGetVersion(/*out*/int32_t* version) {
114 PaletteGetVersionMethod m = PaletteLoader::Instance().GetPaletteGetVersionMethod();
115 return m(version);
116}
117
118enum PaletteStatus PaletteSchedSetPriority(int32_t tid, int32_t java_priority) {
119 PaletteSchedSetPriorityMethod m = PaletteLoader::Instance().GetPaletteSchedSetPriorityMethod();
120 return m(tid, java_priority);
121}
122
123enum PaletteStatus PaletteSchedGetPriority(int32_t tid, /*out*/int32_t* java_priority) {
124 PaletteSchedGetPriorityMethod m = PaletteLoader::Instance().GetPaletteSchedGetPriorityMethod();
125 return m(tid, java_priority);
126}
127
Orion Hodsond3374a02019-05-02 10:56:33 +0100128enum PaletteStatus PaletteWriteCrashThreadStacks(/*in*/const char* stack, size_t stack_len) {
129 PaletteWriteCrashThreadStacksMethod m =
130 PaletteLoader::Instance().GetPaletteWriteCrashThreadStacksMethod();
131 return m(stack, stack_len);
Martin Stjernholm2e2c45e2019-04-09 20:40:59 +0100132}
133
Orion Hodson119733d2019-01-30 15:14:41 +0000134enum PaletteStatus PaletteTraceEnabled(/*out*/int32_t* enabled) {
135 PaletteTraceEnabledMethod m = PaletteLoader::Instance().GetPaletteTraceEnabledMethod();
136 return m(enabled);
137}
138
139enum PaletteStatus PaletteTraceBegin(/*in*/const char* name) {
140 PaletteTraceBeginMethod m = PaletteLoader::Instance().GetPaletteTraceBeginMethod();
141 return m(name);
142}
143
144enum PaletteStatus PaletteTraceEnd() {
145 PaletteTraceEndMethod m = PaletteLoader::Instance().GetPaletteTraceEndMethod();
146 return m();
147}
148
149enum PaletteStatus PaletteTraceIntegerValue(/*in*/const char* name, int32_t value) {
150 PaletteTraceIntegerValueMethod m = PaletteLoader::Instance().GetPaletteTraceIntegerValueMethod();
151 return m(name, value);
152}
153
Nicolas Geoffray2411f492019-06-14 08:54:46 +0100154enum PaletteStatus PaletteAshmemCreateRegion(const char* name, size_t size, int* fd) {
155 PaletteAshmemCreateRegionMethod m =
156 PaletteLoader::Instance().GetPaletteAshmemCreateRegionMethod();
157 return m(name, size, fd);
158}
159
160enum PaletteStatus PaletteAshmemSetProtRegion(int fd, int prot) {
161 PaletteAshmemSetProtRegionMethod m =
162 PaletteLoader::Instance().GetPaletteAshmemSetProtRegionMethod();
163 return m(fd, prot);
164}
165
Orion Hodson119733d2019-01-30 15:14:41 +0000166} // extern "C"