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;
4042using ::android::String16;
4143using ::android::String8;
4244using ::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
4463namespace 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+
93157bool 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
204268status_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+
388488AIBinder_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+
407525void 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
735853binder_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+ }
0 commit comments