summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/binder/IBinder.h1
-rw-r--r--include/utils/Trace.h5
-rw-r--r--include/utils/misc.h4
-rw-r--r--libs/binder/Binder.cpp7
-rw-r--r--libs/utils/Trace.cpp22
-rw-r--r--libs/utils/misc.cpp60
6 files changed, 94 insertions, 5 deletions
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 81b56c2..8b84951 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -51,6 +51,7 @@ public:
PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'),
DUMP_TRANSACTION = B_PACK_CHARS('_','D','M','P'),
INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'),
+ SYSPROPS_TRANSACTION = B_PACK_CHARS('_', 'S', 'P', 'R'),
// Corresponds to TF_ONE_WAY -- an asynchronous call.
FLAG_ONEWAY = 0x00000001
diff --git a/include/utils/Trace.h b/include/utils/Trace.h
index 62f5d6b..984cd46 100644
--- a/include/utils/Trace.h
+++ b/include/utils/Trace.h
@@ -121,11 +121,16 @@ private:
}
}
+ static void changeCallback();
+
// init opens the trace marker file for writing and reads the
// atrace.tags.enableflags system property. It does this only the first
// time it is run, using sMutex for synchronization.
static void init();
+ // retrieve the current value of the system property.
+ static void loadSystemProperty();
+
// sIsReady is a boolean value indicating whether a call to init() has
// completed in this process. It is initialized to 0 and set to 1 when the
// first init() call completes. It is set to 1 even if a failure occurred
diff --git a/include/utils/misc.h b/include/utils/misc.h
index 23f2a4c..d7d5bc1 100644
--- a/include/utils/misc.h
+++ b/include/utils/misc.h
@@ -88,6 +88,10 @@ void strreverse(char* begin, char* end);
void k_itoa(int value, char* str, int base);
char* itoa(int val, int base);
+typedef void (*sysprop_change_callback)(void);
+void add_sysprop_change_callback(sysprop_change_callback cb, int priority);
+void report_sysprop_change();
+
}; // namespace android
#endif // _LIBS_UTILS_MISC_H
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index e20d8a3..1f21f9c 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -17,6 +17,7 @@
#include <binder/Binder.h>
#include <utils/Atomic.h>
+#include <utils/misc.h>
#include <binder/BpBinder.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
@@ -199,6 +200,12 @@ status_t BBinder::onTransact(
}
return dump(fd, args);
}
+
+ case SYSPROPS_TRANSACTION: {
+ report_sysprop_change();
+ return NO_ERROR;
+ }
+
default:
return UNKNOWN_TRANSACTION;
}
diff --git a/libs/utils/Trace.cpp b/libs/utils/Trace.cpp
index f3ec485..5cd5731 100644
--- a/libs/utils/Trace.cpp
+++ b/libs/utils/Trace.cpp
@@ -19,6 +19,7 @@
#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <utils/misc.h>
namespace android {
@@ -27,10 +28,19 @@ int Tracer::sTraceFD = -1;
uint64_t Tracer::sEnabledTags = 0;
Mutex Tracer::sMutex;
+void Tracer::changeCallback() {
+ Mutex::Autolock lock(sMutex);
+ if (sIsReady && sTraceFD >= 0) {
+ loadSystemProperty();
+ }
+}
+
void Tracer::init() {
Mutex::Autolock lock(sMutex);
if (!sIsReady) {
+ add_sysprop_change_callback(changeCallback, 0);
+
const char* const traceFileName =
"/sys/kernel/debug/tracing/trace_marker";
sTraceFD = open(traceFileName, O_WRONLY);
@@ -38,14 +48,18 @@ void Tracer::init() {
ALOGE("error opening trace file: %s (%d)", strerror(errno), errno);
// sEnabledTags remains zero indicating that no tracing can occur
} else {
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.atrace.tags.enableflags", value, "0");
- sEnabledTags = (strtoll(value, NULL, 0) & ATRACE_TAG_VALID_MASK)
- | ATRACE_TAG_ALWAYS;
+ loadSystemProperty();
}
android_atomic_release_store(1, &sIsReady);
}
}
+void Tracer::loadSystemProperty() {
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.atrace.tags.enableflags", value, "0");
+ sEnabledTags = (strtoll(value, NULL, 0) & ATRACE_TAG_VALID_MASK)
+ | ATRACE_TAG_ALWAYS;
+}
+
} // namespace andoid
diff --git a/libs/utils/misc.cpp b/libs/utils/misc.cpp
index dc89d15..b3c99e6 100644
--- a/libs/utils/misc.cpp
+++ b/libs/utils/misc.cpp
@@ -14,10 +14,13 @@
* limitations under the License.
*/
+#define LOG_TAG "misc"
+
//
// Miscellaneous utility functions.
//
#include <utils/misc.h>
+#include <utils/Log.h>
#include <sys/stat.h>
#include <string.h>
@@ -25,6 +28,12 @@
#include <assert.h>
#include <stdio.h>
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/Vector.h>
+
using namespace android;
namespace android {
@@ -181,5 +190,54 @@ unsigned int roundUpPower2(unsigned int val)
return val;
}
-}; // namespace android
+struct sysprop_change_callback_info {
+ sysprop_change_callback callback;
+ int priority;
+};
+
+#if defined(HAVE_PTHREADS)
+static pthread_mutex_t gSyspropMutex = PTHREAD_MUTEX_INITIALIZER;
+static Vector<sysprop_change_callback_info>* gSyspropList = NULL;
+#endif
+
+void add_sysprop_change_callback(sysprop_change_callback cb, int priority) {
+#if defined(HAVE_PTHREADS)
+ pthread_mutex_lock(&gSyspropMutex);
+ if (gSyspropList == NULL) {
+ gSyspropList = new Vector<sysprop_change_callback_info>();
+ }
+ sysprop_change_callback_info info;
+ info.callback = cb;
+ info.priority = priority;
+ bool added = false;
+ for (size_t i=0; i<gSyspropList->size(); i++) {
+ if (priority >= gSyspropList->itemAt(i).priority) {
+ gSyspropList->insertAt(info, i);
+ added = true;
+ break;
+ }
+ }
+ if (!added) {
+ gSyspropList->add(info);
+ }
+ pthread_mutex_unlock(&gSyspropMutex);
+#endif
+}
+
+void report_sysprop_change() {
+#if defined(HAVE_PTHREADS)
+ pthread_mutex_lock(&gSyspropMutex);
+ Vector<sysprop_change_callback_info> listeners;
+ if (gSyspropList != NULL) {
+ listeners = *gSyspropList;
+ }
+ pthread_mutex_unlock(&gSyspropMutex);
+ //ALOGI("Reporting sysprop change to %d listeners", listeners.size());
+ for (size_t i=0; i<listeners.size(); i++) {
+ listeners[i].callback();
+ }
+#endif
+}
+
+}; // namespace android