Add libperfetto_android_internal.so library to access HAL/VNDK

This CL introduces a new shared library, meant to be used
only in in-android-tree builds, to access Android internal
HAL services via hwbinder (and in future maybe other sw
binder interfaces).
The concrete use case is battery tracing (see CLs based
op top of this).
The reasons for splitting off a dedicated .so are twofold:
1) Keep non-NDK dependencies isolated in a standalone target
   and avoid polluting the codebase with #ifdefs.
2) Avoid the memory impact of pulling the various VNDK .so(s)
   unless necessary.

Using hwbinder requires pulling 6 (or more) .so(s), which adds
150 KB of private dirty memory at load time due to linker
relocations.
The plan is to dlopen() libperfetto_android_internal.so
only when required and unload it when unneeded.

Bug: 113076327
Change-Id: I55b76d3c6637fb3604afff6b27870418e4831aa1
diff --git a/src/android_internal/BUILD.gn b/src/android_internal/BUILD.gn
new file mode 100644
index 0000000..0930238
--- /dev/null
+++ b/src/android_internal/BUILD.gn
@@ -0,0 +1,56 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../gn/perfetto.gni")
+
+source_set("headers") {
+  deps = [
+    "../../gn:default_deps",
+  ]
+  sources = [
+    "health_hal.h",
+  ]
+}
+
+# This target proxies calls to Android internal libraries that are not part of
+# the NDK. See README.md.
+source_set("android_internal") {
+  visibility = [ "//:libperfetto_android_internal" ]
+  deps = [
+    ":headers",
+    "../../gn:default_deps",
+  ]
+  if (perfetto_build_with_android) {
+    sources = [
+      "health_hal.cc",
+    ]
+    libs = [
+      "android.hardware.health@2.0",
+      "base",
+      "log",
+      "hwbinder",
+      "hidlbase",
+      "hidltransport",
+      "utils",
+    ]
+  }
+
+  # This target should never depend on any other perfetto target to avoid ODR
+  # violation by doubly linking code in two .so(s) loaded in the same exe.
+  assert_no_deps = [
+    "//src/base/*",
+    "//src/tracing/*",
+    "//include/*",
+  ]
+}
diff --git a/src/android_internal/README.md b/src/android_internal/README.md
new file mode 100644
index 0000000..4cd2102
--- /dev/null
+++ b/src/android_internal/README.md
@@ -0,0 +1,35 @@
+This directory contains code that accesses Android (hw)binder interfaces
+and is dynamically loaded and used by traced_probes.
+The code in this directory is built as a separate .so library and can depend on
+on Android internals.
+
+Block diagram:
+
+```
++---------------+       +---------------------------------+
+| traced_probes |- - -> | libperfetto_android_internal.so |
++---------------+  ^    +---------------+-----------------+
+                   |                    |
+                   |                    | [  Non-NDK libraries ]
+                   |                    +-> libbase.so
+                   |                    +-> libutils.so
+                   |                    +-> libhidltransport.so
+                   |                    +-> libhwbinder.so
+                   |                    +-> android.hardware.xxx@2.0
+                   |
+                   + dynamically loaded on first use via dlopen()
+```
+
+The major reason for using a separate .so() and introducing the shared library
+layer is avoiding the cost of linker relocations (~150 KB private dirty)
+required for loading the graph of binder-related libraries.
+
+The general structure and rules for code in this directory is as-follows:
+- Targets herein defined must be leaf targets. Dependencies to perfetto targets
+  (e.g. base) are not allowed, as doing that would create ODR violations.
+- Headers (e.g. health_hal.h) must have a plain old C interface (to avoid
+  dealing with name mangling) and should not expose neither android internal
+  structure/types nor struct/types defined in perfetto headers outside of this
+  directory.
+- Dependencies to Android internal headers are allowed only in .cc files, not
+  in headers.
diff --git a/src/android_internal/health_hal.cc b/src/android_internal/health_hal.cc
new file mode 100644
index 0000000..0d8ad05
--- /dev/null
+++ b/src/android_internal/health_hal.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/android_internal/health_hal.h"
+
+#include <android/hardware/health/2.0/IHealth.h>
+#include <healthhalutils/HealthHalUtils.h>
+
+namespace perfetto {
+namespace android_internal {
+
+using ::android::hardware::health::V2_0::IHealth;
+using ::android::hardware::health::V2_0::Result;
+
+namespace {
+
+android::sp<IHealth> g_svc;
+
+void ResetService() {
+  g_svc = ::android::hardware::health::V2_0::get_health_service();
+}
+
+}  // namespace
+
+bool GetBatteryCounter(BatteryCounter counter, int64_t* value) {
+  *value = 0;
+  if (!g_svc)
+    ResetService();
+
+  if (!g_svc)
+    return false;
+
+  // The Android VNDK documentation states that for blocking services, the
+  // caller blocks until the reply is received and the callback is called inline
+  // in the same thread.
+  // See https://source.android.com/devices/architecture/hidl/threading .
+
+  Result res;
+  switch (counter) {
+    case BatteryCounter::kUnspecified:
+      res = Result::NOT_FOUND;
+      break;
+
+    case BatteryCounter::kCharge:
+      g_svc->getChargeCounter([&res, value](Result hal_res, int32_t hal_value) {
+        res = hal_res;
+        *value = hal_value;
+      });
+      break;
+
+    case BatteryCounter::kCapacityPercent:
+      g_svc->getCapacity([&res, value](Result hal_res, int64_t hal_value) {
+        res = hal_res;
+        *value = hal_value;
+      });
+      break;
+
+    case BatteryCounter::kCurrent:
+      g_svc->getCurrentNow([&res, value](Result hal_res, int32_t hal_value) {
+        res = hal_res;
+        *value = hal_value;
+      });
+      break;
+
+    case BatteryCounter::kCurrentAvg:
+      g_svc->getCurrentAverage(
+          [&res, value](Result hal_res, int32_t hal_value) {
+            res = hal_res;
+            *value = hal_value;
+          });
+      break;
+  }  // switch(counter)
+
+  if (res == Result::CALLBACK_DIED)
+    g_svc.clear();
+
+  return res == Result::SUCCESS;
+}
+
+}  // namespace android_internal
+}  // namespace perfetto
diff --git a/src/android_internal/health_hal.h b/src/android_internal/health_hal.h
new file mode 100644
index 0000000..5f489af
--- /dev/null
+++ b/src/android_internal/health_hal.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_ANDROID_INTERNAL_HEALTH_HAL_H_
+#define SRC_ANDROID_INTERNAL_HEALTH_HAL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// This header declares proxy functions defined in
+// libperfetto_android_internal.so that allow traced_probes to access internal
+// android functions (e.g., hwbinder).
+// Do not add any include to either perfetto headers or android headers. See
+// README.md for more.
+
+namespace perfetto {
+namespace android_internal {
+
+enum class BatteryCounter {
+  kUnspecified = 0,
+  kCharge,
+  kCapacityPercent,
+  kCurrent,
+  kCurrentAvg,
+};
+
+extern "C" {
+
+// Thse functions are not thread safe unless specified otherwise.
+
+bool __attribute__((visibility("default")))
+GetBatteryCounter(BatteryCounter, int64_t*);
+
+}  // extern "C"
+
+}  // namespace android_internal
+}  // namespace perfetto
+
+#endif  // SRC_ANDROID_INTERNAL_HEALTH_HAL_H_