aboutsummaryrefslogtreecommitdiff
path: root/patches/0001-Enable-default-initializing-liblog_rust-to-write-to-.patch
blob: 0c8c38a145a30b2f7cf010285a2e2bdfad41b567 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
From cd85e49c438e3aa9dbe2989f91e5ad7d3f4816de Mon Sep 17 00:00:00 2001
From: Marcin Radomski <dextero@google.com>
Date: Thu, 17 Aug 2023 16:11:56 +0000
Subject: [PATCH] Enable default-initializing liblog_rust to write to logcat on
 Android

Add default_log_impl cfg that, when enabled, makes `liblog_rust` use
`android_logger` instead of `NopLogger` by default.

This makes it possible to embed android_logger as mod inside liblog_rust
crate, so that AndroidLogger can be used as default logger instead of a
NopLogger.

Changing that default prevents dropping logs when the logger is
uninitialized. This can happen by accident when an application doesn't
intialize the logger in all linker namespaces it pulls libraries from.
See discussion at b/294216366#comment7.

Bug: 275290559
Test: compile test app from aosp/2717614
Test: run it on a Cuttlefish device
Test: observe logcat logs on all level from FFI call
Test: observe all logs on non-FFI call without initializing the logger
Test: observe set log filter applying only to non-FFI call
Change-Id: I04dd334c66e5a2be8cfb19e87be3afb9146e5aa6
---
 Android.bp            | 12 ++++++++++++
 src/android_logger.rs |  1 +
 src/lib.rs            | 23 +++++++++++++++++++++++
 3 files changed, 36 insertions(+)
 create mode 120000 src/android_logger.rs

diff --git a/Android.bp b/Android.bp
index e6ff3cf..81c9175 100644
--- a/Android.bp
+++ b/Android.bp
@@ -60,6 +60,18 @@ rust_library {
     product_available: true,
     vendor_available: true,
     min_sdk_version: "29",
+    target: {
+      android: {
+        cfgs: ["default_log_impl"],
+        rustlibs: [
+          "libandroid_log_sys",
+          "libonce_cell",
+        ],
+        shared_libs: [
+          "liblog",
+        ],
+      }
+    }
 }
 
 rust_library_rlib {
diff --git a/src/android_logger.rs b/src/android_logger.rs
new file mode 120000
index 0000000..84b8625
--- /dev/null
+++ b/src/android_logger.rs
@@ -0,0 +1 @@
+../../android_logger/src/lib.rs
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index 4ead826..8eb1c50 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -344,6 +344,11 @@ mod serde;
 #[cfg(feature = "kv_unstable")]
 pub mod kv;
 
+#[cfg(default_log_impl)]
+extern crate once_cell;
+#[cfg(default_log_impl)]
+mod android_logger;
+
 #[cfg(has_atomics)]
 use std::sync::atomic::{AtomicUsize, Ordering};
 
@@ -405,7 +410,10 @@ const UNINITIALIZED: usize = 0;
 const INITIALIZING: usize = 1;
 const INITIALIZED: usize = 2;
 
+#[cfg(not(default_log_impl))]
 static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(0);
+#[cfg(default_log_impl)]
+static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(5);
 
 static LOG_LEVEL_NAMES: [&str; 6] = ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"];
 
@@ -1572,6 +1580,21 @@ impl error::Error for ParseLevelError {}
 /// If a logger has not been set, a no-op implementation is returned.
 pub fn logger() -> &'static dyn Log {
     if STATE.load(Ordering::SeqCst) != INITIALIZED {
+        #[cfg(default_log_impl)]
+        {
+            // On Android, default to logging to logcat if not explicitly initialized. This
+            // prevents logs from being dropped by default, which may happen unexpectedly in case
+            // of using libraries from multiple linker namespaces and failing to initialize the
+            // logger in each namespace. See b/294216366#comment7.
+            use android_logger::{AndroidLogger, Config};
+            use std::sync::OnceLock;
+            static ANDROID_LOGGER: OnceLock<AndroidLogger> = OnceLock::new();
+            return
+                ANDROID_LOGGER.get_or_init(|| {
+                    // Pass all logs down to liblog - it does its own filtering.
+                    AndroidLogger::new(Config::default().with_max_level(LevelFilter::Trace))
+                });
+        }
         static NOP: NopLogger = NopLogger;
         &NOP
     } else {
-- 
2.42.0.rc1.204.g551eb34607-goog