Add a way to use libraries from the Android tree
This patch adds a gn variable build_with_android which makes it possible
to use Android internal (i.e., non-NDK) libraries when Perfetto is being
built as a part of the Android tree.
Change-Id: I935582fa969ab230b9ab0ac7d392dfeace802b0e
diff --git a/Android.bp b/Android.bp
index 4b8b1b8..4e32744 100644
--- a/Android.bp
+++ b/Android.bp
@@ -64,6 +64,7 @@
"libandroid",
"liblog",
"libprotobuf-cpp-lite",
+ "libutils",
],
static_libs: [
"libgtest_prod",
@@ -81,6 +82,9 @@
defaults: [
"perfetto_defaults",
],
+ cflags: [
+ "-DPERFETTO_BUILD_WITH_ANDROID",
+ ],
}
// GN target: //:perfetto
@@ -93,6 +97,7 @@
"libandroid",
"liblog",
"libtraced_shared",
+ "libutils",
],
defaults: [
"perfetto_defaults",
@@ -893,6 +898,7 @@
"libandroid",
"liblog",
"libtraced_shared",
+ "libutils",
],
defaults: [
"perfetto_defaults",
@@ -909,6 +915,7 @@
"libandroid",
"liblog",
"libtraced_shared",
+ "libutils",
],
defaults: [
"perfetto_defaults",
diff --git a/BUILD.gn b/BUILD.gn
index 512934e..1996c66 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -66,6 +66,10 @@
"src/traced/probes",
"src/traced/service",
]
+ if (build_with_android) {
+ cflags = [ "-DPERFETTO_BUILD_WITH_ANDROID" ]
+ libs = [ "utils" ]
+ }
}
# The unprivileged trace daemon that listens for Producer and Consumer
diff --git a/build_overrides/build.gni b/build_overrides/build.gni
index b7a2bab..a89a764 100644
--- a/build_overrides/build.gni
+++ b/build_overrides/build.gni
@@ -12,8 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# When building perfetto in the android tree this variable becomes magically
+# When building perfetto in the Chromium tree this variable becomes magically
# true by virtue of including //build_overrides by absolute path.
# When false, instead, the build files can assume this is a Perfetto standalone
# build.
build_with_chromium = false
+
+declare_args() {
+ # The Android blueprint file generator overrides this to true.
+ build_with_android = false
+}
diff --git a/src/traced/perfetto_cmd/perfetto_cmd.cc b/src/traced/perfetto_cmd/perfetto_cmd.cc
index 32d5b87..66ce34b 100644
--- a/src/traced/perfetto_cmd/perfetto_cmd.cc
+++ b/src/traced/perfetto_cmd/perfetto_cmd.cc
@@ -35,16 +35,27 @@
#include "protos/tracing_service/trace_config.pb.h"
+#if defined(PERFETTO_BUILD_WITH_ANDROID)
+#include "perfetto/base/android_task_runner.h"
+
+#include <utils/Looper.h>
+#include <utils/StrongPointer.h>
+#endif // defined(PERFETTO_BUILD_WITH_ANDROID)
+
// TODO(primiano): add the ability to pass the file descriptor directly to the
// traced service instead of receiving a copy of the chunks and writing them
// from this process.
-
namespace perfetto {
+#if defined(PERFETTO_BUILD_WITH_ANDROID)
+using PlatformTaskRunner = base::AndroidTaskRunner;
+#else
+using PlatformTaskRunner = base::UnixTaskRunner;
+#endif
+
class PerfettoCmd : public Consumer {
public:
int Main(int argc, char** argv);
-
int PrintUsage(const char* argv0);
void OnStopTraceTimer();
@@ -54,7 +65,7 @@
void OnTraceData(std::vector<TracePacket>, bool has_more) override;
private:
- perfetto::base::UnixTaskRunner task_runner_;
+ PlatformTaskRunner task_runner_;
std::unique_ptr<perfetto::Service::ConsumerEndpoint> consumer_endpoint_;
std::unique_ptr<TraceConfig> trace_config_;
std::ofstream trace_out_stream_;
@@ -144,7 +155,14 @@
consumer_endpoint_ = ConsumerIPCClient::Connect(PERFETTO_CONSUMER_SOCK_NAME,
this, &task_runner_);
+#if defined(PERFETTO_BUILD_WITH_ANDROID)
+ android::sp<android::Looper> looper(android::Looper::prepare(0 /* opts */));
+ while (true) {
+ looper->pollAll(-1 /* timeoutMillis */);
+ }
+#else // defined(PERFETTO_BUILD_WITH_ANDROID)
task_runner_.Run();
+#endif // defined(PERFETTO_BUILD_WITH_ANDROID)
return did_receive_full_trace_ ? 0 : 1;
} // namespace perfetto
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 48f69ca..79416d4 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -26,6 +26,7 @@
# libraries are also mapped to their Android equivalents -- see |builtin_deps|.
import argparse
+import errno
import json
import os
import re
@@ -35,11 +36,12 @@
# Default targets to translate to the blueprint file.
default_targets = [
+ '//:libtraced_shared',
+ '//:perfetto',
'//:perfetto_tests',
'//:perfetto',
'//:traced',
'//:traced_probes',
- '//:libtraced_shared',
'//src/tracing:consumer_cmd',
]
@@ -48,7 +50,7 @@
target_initrc = {} # TODO(primiano): populate in upcoming CLs.
# Arguments for the GN output directory.
-gn_args = 'target_os="android" target_cpu="arm" is_debug=false'
+gn_args = 'target_os="android" target_cpu="arm" is_debug=false build_with_android=true'
# All module names are prefixed with this string to avoid collisions.
module_prefix = 'perfetto_'
@@ -57,6 +59,7 @@
library_whitelist = [
'android',
'log',
+ 'utils',
]
# Name of the module which settings such as compiler flags for all other
@@ -66,6 +69,9 @@
# Location of the project in the Android source tree.
tree_path = 'external/perfetto'
+# Compiler flags which are passed through to the blueprint.
+cflag_whitelist = r'^-DPERFETTO.*$'
+
def enable_gmock(module):
module.static_libs.append('libgmock')
@@ -437,6 +443,9 @@
# Don't try to inject library/source dependencies into genrules because
# they are not compiled in the traditional sense.
if module.type != 'genrule':
+ for flag in target.get('cflags', []):
+ if re.match(cflag_whitelist, flag):
+ module.cflags.append(flag)
module.defaults = [defaults_module]
apply_module_dependency(blueprint, desc, module, target_name)
for dep in resolve_dependencies(desc, target_name):