Skip to content

Commit 0d6e60f

Browse files
committed
Reland "Move tracing calls to libbinder_ndk"
00f5a99 Change-Id: I2151e6b2c3ddb15d9aedd493018b0252938c3639
1 parent 00f5a99 commit 0d6e60f

12 files changed

Lines changed: 260 additions & 4 deletions

File tree

libs/binder/OS.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace android::binder::os {
2727
LIBBINDER_EXPORTED void trace_begin(uint64_t tag, const char* name);
2828
LIBBINDER_EXPORTED void trace_end(uint64_t tag);
2929
LIBBINDER_EXPORTED void trace_int(uint64_t tag, const char* name, int32_t value);
30+
LIBBINDER_EXPORTED uint64_t get_trace_enabled_tags();
3031

3132
status_t setNonBlocking(borrowed_fd fd);
3233

libs/binder/OS_android.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ void trace_int(uint64_t tag, const char* name, int32_t value) {
4848
atrace_int(tag, name, value);
4949
}
5050

51+
uint64_t get_trace_enabled_tags() {
52+
return atrace_enabled_tags;
53+
}
54+
5155
} // namespace os
5256

5357
// Legacy trace symbol. To be removed once all of downstream rebuilds.

libs/binder/OS_non_android_linux.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ void trace_end(uint64_t) {}
4141

4242
void trace_int(uint64_t, const char*, int32_t) {}
4343

44+
uint64_t get_trace_enabled_tags() {
45+
return 0;
46+
}
47+
4448
uint64_t GetThreadId() {
4549
return syscall(__NR_gettid);
4650
}

libs/binder/include/binder/Trace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace os {
4242
void trace_begin(uint64_t tag, const char* name);
4343
void trace_end(uint64_t tag);
4444
void trace_int(uint64_t tag, const char* name, int32_t value);
45+
uint64_t get_trace_enabled_tags();
4546
} // namespace os
4647

4748
class LIBBINDER_EXPORTED ScopedTrace {

libs/binder/ndk/ibinder.cpp

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
#include <android/binder_ibinder_platform.h>
1919
#include <android/binder_stability.h>
2020
#include <android/binder_status.h>
21+
#include <binder/Functional.h>
2122
#include <binder/IPCThreadState.h>
2223
#include <binder/IResultReceiver.h>
24+
#include <binder/Trace.h>
2325
#if __has_include(<private/android_filesystem_config.h>)
2426
#include <private/android_filesystem_config.h>
2527
#endif
@@ -40,6 +42,23 @@ using ::android::statusToString;
4042
using ::android::String16;
4143
using ::android::String8;
4244
using ::android::wp;
45+
using ::android::binder::impl::make_scope_guard;
46+
using ::android::binder::impl::scope_guard;
47+
using ::android::binder::os::get_trace_enabled_tags;
48+
using ::android::binder::os::trace_begin;
49+
using ::android::binder::os::trace_end;
50+
51+
// transaction codes for getInterfaceHash and getInterfaceVersion are defined
52+
// in file : system/tools/aidl/aidl.cpp
53+
static constexpr int kGetInterfaceVersionId = 0x00fffffe;
54+
static const char* kInterfaceVersion = "getInterfaceVersion";
55+
static constexpr int kGetInterfaceHashId = 0x00fffffd;
56+
static const char* kInterfaceHash = "getInterfaceHash";
57+
static const char* kNdkTrace = "AIDL::ndk::";
58+
static const char* kServerTrace = "::server";
59+
static const char* kClientTrace = "::client";
60+
static const char* kSeparator = "::";
61+
static const char* kUnknownCode = "Unknown_Transaction_Code:";
4362

4463
namespace ABBinderTag {
4564

@@ -90,6 +109,51 @@ static std::string SanitizeString(const String16& str) {
90109
return sanitized;
91110
}
92111

112+
const std::string getMethodName(const AIBinder_Class* clazz, transaction_code_t code) {
113+
// TODO(b/150155678) - Move getInterfaceHash and getInterfaceVersion to libbinder and remove
114+
// hardcoded cases.
115+
if (code <= clazz->getTransactionCodeToFunctionLength() && code >= FIRST_CALL_TRANSACTION) {
116+
// Codes have FIRST_CALL_TRANSACTION as added offset. Subtract to access function name
117+
return clazz->getFunctionName(code);
118+
} else if (code == kGetInterfaceVersionId) {
119+
return kInterfaceVersion;
120+
} else if (code == kGetInterfaceHashId) {
121+
return kInterfaceHash;
122+
}
123+
return kUnknownCode + std::to_string(code);
124+
}
125+
126+
const std::string getTraceSectionName(const AIBinder_Class* clazz, transaction_code_t code,
127+
bool isServer) {
128+
if (clazz == nullptr) {
129+
ALOGE("class associated with binder is null. Class is needed to add trace with interface "
130+
"name and function name");
131+
return kNdkTrace;
132+
}
133+
134+
const std::string descriptor = clazz->getInterfaceDescriptorUtf8();
135+
const std::string methodName = getMethodName(clazz, code);
136+
137+
size_t traceSize =
138+
strlen(kNdkTrace) + descriptor.size() + strlen(kSeparator) + methodName.size();
139+
traceSize += isServer ? strlen(kServerTrace) : strlen(kClientTrace);
140+
141+
std::string trace;
142+
// reserve to avoid repeated allocations
143+
trace.reserve(traceSize);
144+
145+
trace += kNdkTrace;
146+
trace += clazz->getInterfaceDescriptorUtf8();
147+
trace += kSeparator;
148+
trace += methodName;
149+
trace += isServer ? kServerTrace : kClientTrace;
150+
151+
LOG_ALWAYS_FATAL_IF(trace.size() != traceSize, "Trace size mismatch. Expected %zu, got %zu",
152+
traceSize, trace.size());
153+
154+
return trace;
155+
}
156+
93157
bool AIBinder::associateClass(const AIBinder_Class* clazz) {
94158
if (clazz == nullptr) return false;
95159

@@ -203,6 +267,17 @@ status_t ABBinder::dump(int fd, const ::android::Vector<String16>& args) {
203267

204268
status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply,
205269
binder_flags_t flags) {
270+
std::string sectionName;
271+
bool tracingEnabled = get_trace_enabled_tags() & ATRACE_TAG_AIDL;
272+
if (tracingEnabled) {
273+
sectionName = getTraceSectionName(getClass(), code, true /*isServer*/);
274+
trace_begin(ATRACE_TAG_AIDL, sectionName.c_str());
275+
}
276+
277+
scope_guard guard = make_scope_guard([&]() {
278+
if (tracingEnabled) trace_end(ATRACE_TAG_AIDL);
279+
});
280+
206281
if (isUserCommand(code)) {
207282
if (getClass()->writeHeader && !data.checkInterface(this)) {
208283
return STATUS_BAD_TYPE;
@@ -385,6 +460,31 @@ AIBinder_Class::AIBinder_Class(const char* interfaceDescriptor, AIBinder_Class_o
385460
mInterfaceDescriptor(interfaceDescriptor),
386461
mWideInterfaceDescriptor(interfaceDescriptor) {}
387462

463+
bool AIBinder_Class::setTransactionCodeMap(const char** transactionCodeMap, size_t length) {
464+
if (mTransactionCodeToFunction != nullptr) {
465+
ALOGE("mTransactionCodeToFunction is already set!");
466+
return false;
467+
}
468+
mTransactionCodeToFunction = transactionCodeMap;
469+
mTransactionCodeToFunctionLength = length;
470+
return true;
471+
}
472+
473+
const char* AIBinder_Class::getFunctionName(transaction_code_t code) const {
474+
if (mTransactionCodeToFunction == nullptr) {
475+
ALOGE("mTransactionCodeToFunction is not set!");
476+
return nullptr;
477+
}
478+
479+
if (code < FIRST_CALL_TRANSACTION ||
480+
code - FIRST_CALL_TRANSACTION >= mTransactionCodeToFunctionLength) {
481+
ALOGE("Function name for requested code not found!");
482+
return nullptr;
483+
}
484+
485+
return mTransactionCodeToFunction[code - FIRST_CALL_TRANSACTION];
486+
}
487+
388488
AIBinder_Class* AIBinder_Class_define(const char* interfaceDescriptor,
389489
AIBinder_Class_onCreate onCreate,
390490
AIBinder_Class_onDestroy onDestroy,
@@ -404,6 +504,24 @@ void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) {
404504
clazz->onDump = onDump;
405505
}
406506

507+
void AIBinder_Class_setTransactionCodeToFunctionNameMap(AIBinder_Class* clazz,
508+
const char** transactionCodeToFunction,
509+
size_t length) {
510+
LOG_ALWAYS_FATAL_IF(clazz == nullptr || transactionCodeToFunction == nullptr,
511+
"Valid clazz and transactionCodeToFunction are needed to set code to "
512+
"function mapping.");
513+
LOG_ALWAYS_FATAL_IF(!clazz->setTransactionCodeMap(transactionCodeToFunction, length),
514+
"Failed to set transactionCodeToFunction to clazz! Is "
515+
"transactionCodeToFunction already set?");
516+
}
517+
518+
const char* AIBinder_Class_getFunctionName(AIBinder_Class* clazz, transaction_code_t code) {
519+
LOG_ALWAYS_FATAL_IF(
520+
clazz == nullptr,
521+
"Valid clazz is needed to get function name for requested transaction code");
522+
return clazz->getFunctionName(code);
523+
}
524+
407525
void AIBinder_Class_disableInterfaceTokenHeader(AIBinder_Class* clazz) {
408526
LOG_ALWAYS_FATAL_IF(clazz == nullptr, "disableInterfaceTokenHeader requires non-null clazz");
409527

@@ -734,6 +852,19 @@ static void DestroyParcel(AParcel** parcel) {
734852

735853
binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in,
736854
AParcel** out, binder_flags_t flags) {
855+
const AIBinder_Class* clazz = binder ? binder->getClass() : nullptr;
856+
857+
std::string sectionName;
858+
bool tracingEnabled = get_trace_enabled_tags() & ATRACE_TAG_AIDL;
859+
if (tracingEnabled) {
860+
sectionName = getTraceSectionName(clazz, code, false /*isServer*/);
861+
trace_begin(ATRACE_TAG_AIDL, sectionName.c_str());
862+
}
863+
864+
scope_guard guard = make_scope_guard([&]() {
865+
if (tracingEnabled) trace_end(ATRACE_TAG_AIDL);
866+
});
867+
737868
if (in == nullptr) {
738869
ALOGE("%s: requires non-null in parameter", __func__);
739870
return STATUS_UNEXPECTED_NULL;
@@ -872,4 +1003,4 @@ void AIBinder_setInheritRt(AIBinder* binder, bool inheritRt) {
8721003
"AIBinder_setInheritRt must be called on a local binder");
8731004

8741005
localBinder->setInheritRt(inheritRt);
875-
}
1006+
}

libs/binder/ndk/ibinder_internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ struct AIBinder_Class {
132132

133133
const ::android::String16& getInterfaceDescriptor() const { return mWideInterfaceDescriptor; }
134134
const char* getInterfaceDescriptorUtf8() const { return mInterfaceDescriptor.c_str(); }
135+
bool setTransactionCodeMap(const char** transactionCodeMap, size_t transactionCodeMapSize);
136+
const char* getFunctionName(transaction_code_t code) const;
137+
size_t getTransactionCodeToFunctionLength() const { return mTransactionCodeToFunctionLength; }
135138

136139
// whether a transaction header should be written
137140
bool writeHeader = true;
@@ -151,6 +154,10 @@ struct AIBinder_Class {
151154
// This must be a String16 since BBinder virtual getInterfaceDescriptor returns a reference to
152155
// one.
153156
const ::android::String16 mWideInterfaceDescriptor;
157+
// Array which holds names of the functions
158+
const char** mTransactionCodeToFunction = nullptr;
159+
// length of mmTransactionCodeToFunctionLength array
160+
size_t mTransactionCodeToFunctionLength = 0;
154161
};
155162

156163
// Ownership is like this (when linked to death):

libs/binder/ndk/include_cpp/android/binder_interface_utils.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@
3030
#include <android/binder_auto_utils.h>
3131
#include <android/binder_ibinder.h>
3232

33+
#if defined(__ANDROID_VENDOR__)
34+
#include <android/llndk-versioning.h>
35+
#elif !defined(API_LEVEL_AT_LEAST)
36+
#if defined(__BIONIC__)
37+
#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) \
38+
(__builtin_available(android sdk_api_level, *))
39+
#else
40+
#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) (true)
41+
#endif // __BIONIC__
42+
#endif // __ANDROID_VENDOR__
43+
3344
#if __has_include(<android/binder_shell.h>)
3445
#include <android/binder_shell.h>
3546
#define HAS_BINDER_SHELL_COMMAND
@@ -164,7 +175,8 @@ class ICInterface : public SharedRefBase {
164175
* Helper method to create a class
165176
*/
166177
static inline AIBinder_Class* defineClass(const char* interfaceDescriptor,
167-
AIBinder_Class_onTransact onTransact);
178+
AIBinder_Class_onTransact onTransact,
179+
const char** codeToFunction, size_t functionCount);
168180

169181
private:
170182
class ICInterfaceData {
@@ -255,7 +267,8 @@ std::shared_ptr<ICInterface> ICInterface::asInterface(AIBinder* binder) {
255267
}
256268

257269
AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor,
258-
AIBinder_Class_onTransact onTransact) {
270+
AIBinder_Class_onTransact onTransact,
271+
const char** codeToFunction, size_t functionCount) {
259272
AIBinder_Class* clazz = AIBinder_Class_define(interfaceDescriptor, ICInterfaceData::onCreate,
260273
ICInterfaceData::onDestroy, onTransact);
261274
if (clazz == nullptr) {
@@ -274,6 +287,17 @@ AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor,
274287
AIBinder_Class_setHandleShellCommand(clazz, ICInterfaceData::handleShellCommand);
275288
}
276289
#endif
290+
291+
// TODO(b/368559337): fix versioning on product partition
292+
#if !defined(__ANDROID_PRODUCT__) && \
293+
(defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__) || __ANDROID_API__ >= 36)
294+
if API_LEVEL_AT_LEAST (36, 202504) {
295+
AIBinder_Class_setTransactionCodeToFunctionNameMap(clazz, codeToFunction, functionCount);
296+
}
297+
#else
298+
(void)codeToFunction;
299+
(void)functionCount;
300+
#endif // defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__) || __ANDROID_API__ >= 36
277301
return clazz;
278302
}
279303

libs/binder/ndk/include_ndk/android/binder_ibinder.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,50 @@ typedef binder_status_t (*AIBinder_onDump)(AIBinder* binder, int fd, const char*
218218
*/
219219
void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) __INTRODUCED_IN(29);
220220

221+
/**
222+
* Associates a mapping of transaction codes(transaction_code_t) to function names for the given
223+
* class.
224+
*
225+
* Trace messages will use the provided names instead of bare integer codes when set. If not set by
226+
* this function, trace messages will only be identified by the bare code. This should be called one
227+
* time during clazz initialization. clazz and transactionCodeToFunctionMap should have same
228+
* lifetime. Resetting/clearing the transactionCodeToFunctionMap is not allowed.
229+
*
230+
* Available since API level 36.
231+
*
232+
* \param clazz class which should use this transaction to code function map.
233+
* \param transactionCodeToFunctionMap array of function names indexed by transaction code.
234+
* Transaction codes start from 1, functions with transaction code 1 will correspond to index 0 in
235+
* transactionCodeToFunctionMap. When defining methods, transaction codes are expected to be
236+
* contiguous, and this is required for maximum memory efficiency.
237+
* You can use nullptr if certain transaction codes are not used. Lifetime should be same as clazz.
238+
* \param length number of elements in the transactionCodeToFunctionMap
239+
*
240+
* \return true if setting codeToFunction to clazz is successful. return false if clazz or
241+
* codeToFunction is nullptr.
242+
*/
243+
void AIBinder_Class_setTransactionCodeToFunctionNameMap(AIBinder_Class* clazz,
244+
const char** transactionCodeToFunctionMap,
245+
size_t length) __INTRODUCED_IN(36);
246+
247+
/**
248+
* Get function name associated with transaction code for given class
249+
*
250+
* This function returns function name associated with provided transaction code for given class.
251+
* AIBinder_Class_setTransactionCodeToFunctionNameMap should be called first to associate function
252+
* to transaction code mapping.
253+
*
254+
* Available since API level 36.
255+
*
256+
* \param clazz class for which function name is requested
257+
* \param transactionCode transaction_code_t for which function name is requested.
258+
*
259+
* \return function name in form of const char* if transaction code is valid for given class.
260+
* if transaction code is invalid or transactionCodeToFunctionMap is not set, nullptr is returned
261+
*/
262+
const char* AIBinder_Class_getFunctionName(AIBinder_Class* clazz, transaction_code_t code)
263+
__INTRODUCED_IN(36);
264+
221265
/**
222266
* This tells users of this class not to use a transaction header. By default, libbinder_ndk users
223267
* read/write transaction headers implicitly (in the SDK, this must be manually written by

libs/binder/ndk/libbinder_ndk.map.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ LIBBINDER_NDK35 { # introduced=VanillaIceCream
250250

251251
LIBBINDER_NDK36 { # introduced=36
252252
global:
253+
AIBinder_Class_setTransactionCodeToFunctionNameMap;
254+
AIBinder_Class_setTransactionCodeToFunctionNameMap; # llndk=202504
255+
AIBinder_Class_getFunctionName;
256+
AIBinder_Class_getFunctionName; # llndk=202504
253257
ABinderRpc_registerAccessorProvider; # systemapi
254258
ABinderRpc_unregisterAccessorProvider; # systemapi
255259
ABinderRpc_Accessor_new; # systemapi

0 commit comments

Comments
 (0)