Cut off process names for profiling.

/proc/<pid>/comm cannot be longer than 16 characters. Because of this,
packages starting with android.hardware.* etc.. are indistinguishable
between tool that use comm to identify processes. This makes using tools
like systrace extremely difficult and error prone.

Test: external/chromium-trace/systrace.py -b 32000 audio sched freq idle
workq irq binder_driver am sync hal app pm ss -t 5
Test: (sanity) hidl_test
Bug: 33664825

(cherry picked from commit 405d76134f5ec033817a21fbbcc13083fe0349fe)
Merged-In: I4c9ba4d75b9ad1c1161335fe3595e13ac3222bb6
Change-Id: I4c9ba4d75b9ad1c1161335fe3595e13ac3222bb6
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index ff9884e..c766b7a 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -19,6 +19,8 @@
 #include <condition_variable>
 #include <dlfcn.h>
 #include <dirent.h>
+#include <fstream>
+#include <pthread.h>
 #include <unistd.h>
 
 #include <mutex>
@@ -66,13 +68,74 @@
     }
 }
 
-sp<IServiceManager> defaultServiceManager() {
+bool endsWith(const std::string &in, const std::string &suffix) {
+    return in.size() >= suffix.size() &&
+           in.substr(in.size() - suffix.size()) == suffix;
+}
 
+bool startsWith(const std::string &in, const std::string &prefix) {
+    return in.size() >= prefix.size() &&
+           in.substr(0, prefix.size()) == prefix;
+}
+
+std::string binaryName() {
+    std::ifstream ifs("/proc/self/cmdline");
+    std::string cmdline;
+    if (!ifs.is_open()) {
+        return "";
+    }
+    ifs >> cmdline;
+
+    size_t idx = cmdline.rfind("/");
+    if (idx != std::string::npos) {
+        cmdline = cmdline.substr(idx + 1);
+    }
+
+    return cmdline;
+}
+
+void tryShortenProcessName(const std::string &packageName) {
+    std::string processName = binaryName();
+
+    if (!startsWith(processName, packageName)) {
+        return;
+    }
+
+    // e.x. android.hardware.module.foo@1.0 -> foo@1.0
+    size_t lastDot = packageName.rfind('.');
+    size_t secondDot = packageName.rfind('.', lastDot - 1);
+
+    if (secondDot == std::string::npos) {
+        return;
+    }
+
+    std::string newName = processName.substr(secondDot + 1,
+            16 /* TASK_COMM_LEN */ - 1);
+    ALOGI("Removing namespace from process name %s to %s.",
+            processName.c_str(), newName.c_str());
+
+    int rc = pthread_setname_np(pthread_self(), newName.c_str());
+    ALOGI_IF(rc != 0, "Removing namespace from process name %s failed.",
+            processName.c_str());
+}
+
+namespace details {
+
+void onRegistration(const std::string &packageName,
+                    const std::string& /* interfaceName */,
+                    const std::string& /* instanceName */) {
+    tryShortenProcessName(packageName);
+}
+
+}  // details
+
+sp<IServiceManager> defaultServiceManager() {
     {
         AutoMutex _l(details::gDefaultServiceManagerLock);
         if (details::gDefaultServiceManager != NULL) {
             return details::gDefaultServiceManager;
         }
+
         if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) {
             // HwBinder not available on this device or not accessible to
             // this process.
@@ -95,16 +158,6 @@
     return details::gDefaultServiceManager;
 }
 
-bool endsWith(const std::string &in, const std::string &suffix) {
-    return in.size() >= suffix.size() &&
-           in.substr(in.size() - suffix.size()) == suffix;
-}
-
-bool startsWith(const std::string &in, const std::string &prefix) {
-    return in.size() >= prefix.size() &&
-           in.substr(0, prefix.size()) == prefix;
-}
-
 std::vector<std::string> search(const std::string &path,
                               const std::string &prefix,
                               const std::string &suffix) {
diff --git a/transport/include/hidl/ServiceManagement.h b/transport/include/hidl/ServiceManagement.h
index 2035fb7..2b2266b 100644
--- a/transport/include/hidl/ServiceManagement.h
+++ b/transport/include/hidl/ServiceManagement.h
@@ -39,6 +39,12 @@
 sp<::android::hidl::manager::V1_0::IServiceManager> getPassthroughServiceManager();
 
 namespace details {
+// e.x.: android.hardware.foo@1.0, IFoo, default
+void onRegistration(const std::string &packageName,
+                    const std::string &interfaceName,
+                    const std::string &instanceName);
+
+// e.x.: android.hardware.foo@1.0::IFoo, default
 void waitForHwService(const std::string &interface, const std::string &instanceName);
 };