Support dynamically enable profiling.

* Create method configureInstrumentation to enable/disable instrumentation based
  on the corresponding system property. This method will be called every
  time setHALInstrumention is invoked for any hal.
* Add setHALInstrumention to IBase.hal

Bug: 33923655
Test: make libhidlbase.
Change-Id: I130fb903f65783568a97308e291965960abab41d
diff --git a/base/HidlSupport.cpp b/base/HidlSupport.cpp
index 3cc4b14..dce2585 100644
--- a/base/HidlSupport.cpp
+++ b/base/HidlSupport.cpp
@@ -153,18 +153,34 @@
 
 // ----------------------------------------------------------------------
 // HidlInstrumentor implementation.
-HidlInstrumentor::HidlInstrumentor(const std::string &prefix) {
-    mEnableInstrumentation = property_get_bool("hal.instrumentation.enable",
-                                               false);
-    if (mEnableInstrumentation) {
-        registerInstrumentationCallbacks(prefix, &mInstrumentationCallbacks);
-    }
+HidlInstrumentor::HidlInstrumentor(const std::string &prefix)
+        : mInstrumentationLibPrefix(prefix) {
+    configureInstrumentation(false);
 }
 
 HidlInstrumentor:: ~HidlInstrumentor() {}
 
+void HidlInstrumentor::configureInstrumentation(bool log) {
+    bool enable_instrumentation = property_get_bool(
+            "hal.instrumentation.enable",
+            false);
+    if (enable_instrumentation != mEnableInstrumentation) {
+        mEnableInstrumentation = enable_instrumentation;
+        if (mEnableInstrumentation) {
+            if (log) {
+                LOG(INFO) << "Enable instrumentation.";
+            }
+            registerInstrumentationCallbacks (&mInstrumentationCallbacks);
+        } else {
+            if (log) {
+                LOG(INFO) << "Disable instrumentation.";
+            }
+            mInstrumentationCallbacks.clear();
+        }
+    }
+}
+
 void HidlInstrumentor::registerInstrumentationCallbacks(
-        const std::string &profilerPrefix,
         std::vector<InstrumentationCallback> *instrumentationCallbacks) {
 #ifdef LIBHIDL_TARGET_DEBUGGABLE
     std::vector<std::string> instrumentationLibPaths;
@@ -188,7 +204,7 @@
 
         struct dirent *file;
         while ((file = readdir(dir)) != NULL) {
-            if (!isInstrumentationLib(profilerPrefix, file))
+            if (!isInstrumentationLib(file))
                 continue;
 
             void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
@@ -224,13 +240,11 @@
 #endif
 }
 
-bool HidlInstrumentor::isInstrumentationLib(
-        const std::string &profiler_prefix,
-        const dirent *file) {
+bool HidlInstrumentor::isInstrumentationLib(const dirent *file) {
 #ifdef LIBHIDL_TARGET_DEBUGGABLE
     if (file->d_type != DT_REG) return false;
     std::cmatch cm;
-    std::regex e("^" + profiler_prefix + "(.*).profiler.so$");
+    std::regex e("^" + mInstrumentationLibPrefix + "(.*).profiler.so$");
     if (std::regex_match(file->d_name, cm, e)) return true;
 #endif
     return false;
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 78bc2c8..106fb02 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -851,6 +851,10 @@
     virtual ~HidlInstrumentor();
 
  protected:
+    // Set mEnableInstrumentation based on system property
+    // hal.instrumentation.enable, register/de-register instrumentation
+    // callbacks if mEnableInstrumentation is true/false.
+    void configureInstrumentation(bool log=true);
     // Function that lookup and dynamically loads the hidl instrumentation
     // libraries and registers the instrumentation callback functions.
     //
@@ -864,18 +868,18 @@
     //
     // A no-op for user build.
     void registerInstrumentationCallbacks(
-            const std::string &profilerPrefix,
             std::vector<InstrumentationCallback> *instrumentationCallbacks);
 
     // Utility function to determine whether a give file is a instrumentation
     // library (i.e. the file name follow the expected pattern).
-    bool isInstrumentationLib(
-            const std::string &profilerPrefix,
-            const dirent *file);
+    bool isInstrumentationLib(const dirent *file);
+
     // A list of registered instrumentation callbacks.
     std::vector<InstrumentationCallback> mInstrumentationCallbacks;
     // Flag whether to enable instrumentation.
     bool mEnableInstrumentation;
+    // Prefix to lookup the instrumentation libraries.
+    std::string mInstrumentationLibPrefix;
 };
 
 }  // namespace hardware
diff --git a/transport/base/1.0/IBase.hal b/transport/base/1.0/IBase.hal
index d696249..30be023 100644
--- a/transport/base/1.0/IBase.hal
+++ b/transport/base/1.0/IBase.hal
@@ -71,4 +71,10 @@
      * @return success whether the death recipient was unregistered successfully.
      */
     unlinkToDeath(death_recipient recipient) generates (bool success);
+
+    /*
+     * This method trigger the interface to enable/disable instrumentation based
+     * on system property hal.instrumentation.enable.
+     */
+    oneway setHALInstrumentation();
 };