diff options
-rw-r--r-- | TEST_MAPPING | 6 | ||||
-rw-r--r-- | patches/0001-Support-selecting-target-log-buffer.patch | 197 | ||||
-rw-r--r-- | patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch | 41 | ||||
-rw-r--r-- | src/lib.rs | 65 |
4 files changed, 290 insertions, 19 deletions
diff --git a/TEST_MAPPING b/TEST_MAPPING index 7fc7922..526e77a 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -44,9 +44,6 @@ "name": "logger_test_multiple_init" }, { - "name": "open_then_run_module" - }, - { "name": "virtualizationservice_device_test" } ], @@ -94,9 +91,6 @@ "name": "logger_test_multiple_init" }, { - "name": "open_then_run_module" - }, - { "name": "virtualizationservice_device_test" } ] diff --git a/patches/0001-Support-selecting-target-log-buffer.patch b/patches/0001-Support-selecting-target-log-buffer.patch new file mode 100644 index 0000000..e5fc33b --- /dev/null +++ b/patches/0001-Support-selecting-target-log-buffer.patch @@ -0,0 +1,197 @@ +From 2bc2650d0a7a11a74670a6583b16aa6714d7c993 Mon Sep 17 00:00:00 2001 +From: Matthew Maurer <mmaurer@google.com> +Date: Thu, 17 Feb 2022 20:23:37 +0000 +Subject: [PATCH] Support selecting target log buffer + +Android has several different log buffers. Previously, this library +would only support logging to the "Main" log. Now, it logs to the +default log (which is Main for most processes), with the option to +override which log buffer you send messages to in the config. + +Change-Id: I72779e62bd963586e3dfad431cd82c75daf04d92 +--- + src/lib.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 58 insertions(+), 13 deletions(-) + +diff --git a/src/lib.rs b/src/lib.rs +index 11a127e..d21be3f 100644 +--- a/src/lib.rs ++++ b/src/lib.rs +@@ -87,21 +87,49 @@ pub use env_logger::fmt::Formatter; + + pub(crate) type FormatFn = Box<dyn Fn(&mut dyn fmt::Write, &Record) -> fmt::Result + Sync + Send>; + ++#[derive(Copy, Clone, Eq, PartialEq, Debug)] ++pub enum LogId { ++ Main, ++ Radio, ++ Events, ++ System, ++ Crash ++} ++ ++impl LogId { ++ #[cfg(target_os = "android")] ++ fn to_native(log_id: Option<Self>) -> log_ffi::log_id_t { ++ match log_id { ++ Some(LogId::Main) => log_ffi::log_id_t::MAIN, ++ Some(LogId::Radio) => log_ffi::log_id_t::RADIO, ++ Some(LogId::Events) => log_ffi::log_id_t::EVENTS, ++ Some(LogId::System) => log_ffi::log_id_t::SYSTEM, ++ Some(LogId::Crash) => log_ffi::log_id_t::CRASH, ++ None => log_ffi::log_id_t::DEFAULT, ++ } ++ } ++} ++ + /// Output log to android system. + #[cfg(target_os = "android")] +-fn android_log(prio: log_ffi::LogPriority, tag: &CStr, msg: &CStr) { ++fn android_log(log_id: log_ffi::log_id_t, prio: log_ffi::LogPriority, tag: &CStr, msg: &CStr) { ++ let mut message = log_ffi::__android_log_message { ++ struct_size: std::mem::size_of::<log_ffi::__android_log_message>(), ++ buffer_id: log_id as i32, ++ priority: prio as i32, ++ tag: tag.as_ptr() as *const log_ffi::c_char, ++ file: ptr::null(), ++ line: 0, ++ message: msg.as_ptr() as *const log_ffi::c_char, ++ }; + unsafe { +- log_ffi::__android_log_write( +- prio as log_ffi::c_int, +- tag.as_ptr() as *const log_ffi::c_char, +- msg.as_ptr() as *const log_ffi::c_char, +- ) ++ log_ffi::__android_log_write_log_message(&mut message as *mut _); + }; + } + + /// Dummy output placeholder for tests. + #[cfg(not(target_os = "android"))] +-fn android_log(_priority: Level, _tag: &CStr, _msg: &CStr) {} ++fn android_log(_log_id: Option<LogId>, _priority: Level, _tag: &CStr, _msg: &CStr) {} + + /// Underlying android logger backend + pub struct AndroidLogger { +@@ -164,7 +192,7 @@ impl Log for AndroidLogger { + + // message must not exceed LOGGING_MSG_MAX_LEN + // therefore split log message into multiple log calls +- let mut writer = PlatformLogWriter::new(record.level(), tag); ++ let mut writer = PlatformLogWriter::new(config.log_id, record.level(), tag); + + // If a custom tag is used, add the module path to the message. + // Use PlatformLogWriter to output chunks if they exceed max size. +@@ -208,6 +236,7 @@ impl AndroidLogger { + /// Filter for android logger. + pub struct Config { + log_level: Option<Level>, ++ log_id: Option<LogId>, + filter: Option<env_logger::filter::Filter>, + tag: Option<CString>, + custom_format: Option<FormatFn>, +@@ -217,6 +246,7 @@ impl Default for Config { + fn default() -> Self { + Config { + log_level: None, ++ log_id: None, + filter: None, + tag: None, + custom_format: None, +@@ -234,6 +264,15 @@ impl Config { + self + } + ++ /// Change which log buffer is used ++ /// ++ /// By default, logs are sent to the `Main` log. Other logging buffers may only be accessible ++ /// to certain processes. ++ pub fn with_log_id(mut self, log_id: LogId) -> Self { ++ self.log_id = Some(log_id); ++ self ++ } ++ + fn filter_matches(&self, record: &Record) -> bool { + if let Some(ref filter) = self.filter { + filter.matches(&record) +@@ -273,6 +312,8 @@ impl Config { + struct PlatformLogWriter<'a> { + #[cfg(target_os = "android")] priority: LogPriority, + #[cfg(not(target_os = "android"))] priority: Level, ++ #[cfg(target_os = "android")] log_id: log_ffi::log_id_t, ++ #[cfg(not(target_os = "android"))] log_id: Option<LogId>, + len: usize, + last_newline_index: usize, + tag: &'a CStr, +@@ -281,7 +322,7 @@ struct PlatformLogWriter<'a> { + + impl<'a> PlatformLogWriter<'a> { + #[cfg(target_os = "android")] +- pub fn new(level: Level, tag: &CStr) -> PlatformLogWriter { ++ pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter { + #[allow(deprecated)] // created an issue #35 for this + PlatformLogWriter { + priority: match level { +@@ -291,6 +332,7 @@ impl<'a> PlatformLogWriter<'a> { + Level::Error => LogPriority::ERROR, + Level::Trace => LogPriority::VERBOSE, + }, ++ log_id: LogId::to_native(log_id), + len: 0, + last_newline_index: 0, + tag, +@@ -299,10 +341,11 @@ impl<'a> PlatformLogWriter<'a> { + } + + #[cfg(not(target_os = "android"))] +- pub fn new(level: Level, tag: &CStr) -> PlatformLogWriter { ++ pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter { + #[allow(deprecated)] // created an issue #35 for this + PlatformLogWriter { + priority: level, ++ log_id, + len: 0, + last_newline_index: 0, + tag, +@@ -358,7 +401,7 @@ impl<'a> PlatformLogWriter<'a> { + }); + + let msg: &CStr = unsafe { CStr::from_ptr(mem::transmute(self.buffer.as_ptr())) }; +- android_log(self.priority, self.tag, msg); ++ android_log(self.log_id, self.priority, self.tag, msg); + + *unsafe { self.buffer.get_unchecked_mut(len) } = last_byte; + } +@@ -458,9 +501,11 @@ mod tests { + // Filter is checked in config_filter_match below. + let config = Config::default() + .with_min_level(Level::Trace) ++ .with_log_id(LogId::System) + .with_tag("my_app"); + + assert_eq!(config.log_level, Some(Level::Trace)); ++ assert_eq!(config.log_id, Some(LogId::System)); + assert_eq!(config.tag, Some(CString::new("my_app").unwrap())); + } + +@@ -531,7 +576,7 @@ mod tests { + fn platform_log_writer_init_values() { + let tag = CStr::from_bytes_with_nul(b"tag\0").unwrap(); + +- let writer = PlatformLogWriter::new(Level::Warn, &tag); ++ let writer = PlatformLogWriter::new(None, Level::Warn, &tag); + + assert_eq!(writer.tag, tag); + // Android uses LogPriority instead, which doesn't implement equality checks +@@ -630,6 +675,6 @@ mod tests { + } + + fn get_tag_writer() -> PlatformLogWriter<'static> { +- PlatformLogWriter::new(Level::Warn, &CStr::from_bytes_with_nul(b"tag\0").unwrap()) ++ PlatformLogWriter::new(None, Level::Warn, &CStr::from_bytes_with_nul(b"tag\0").unwrap()) + } + } +-- +2.35.1.265.g69c8d7142f-goog + diff --git a/patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch b/patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch new file mode 100644 index 0000000..721e9eb --- /dev/null +++ b/patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch @@ -0,0 +1,41 @@ +From ec84856e0f0bc5a307529122bfed3d94d2ef4011 Mon Sep 17 00:00:00 2001 +From: Matthew Maurer <mmaurer@google.com> +Date: Thu, 24 Feb 2022 14:07:03 -0800 +Subject: [PATCH] Use older API to avoid requiring API v30 + +Test: Check that keystore still outputs logs to system +Bug: 221185310 +Change-Id: I25174f1617557e270db70cd432cec78c037c6b75 +--- + src/lib.rs | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +diff --git a/src/lib.rs b/src/lib.rs +index d21be3f..bc4fa61 100644 +--- a/src/lib.rs ++++ b/src/lib.rs +@@ -113,17 +113,11 @@ impl LogId { + /// Output log to android system. + #[cfg(target_os = "android")] + fn android_log(log_id: log_ffi::log_id_t, prio: log_ffi::LogPriority, tag: &CStr, msg: &CStr) { +- let mut message = log_ffi::__android_log_message { +- struct_size: std::mem::size_of::<log_ffi::__android_log_message>(), +- buffer_id: log_id as i32, +- priority: prio as i32, +- tag: tag.as_ptr() as *const log_ffi::c_char, +- file: ptr::null(), +- line: 0, +- message: msg.as_ptr() as *const log_ffi::c_char, +- }; + unsafe { +- log_ffi::__android_log_write_log_message(&mut message as *mut _); ++ log_ffi::__android_log_buf_write(log_id as i32, ++ prio as i32, ++ tag.as_ptr() as *const log_ffi::c_char, ++ msg.as_ptr() as *const log_ffi::c_char); + }; + } + +-- +2.35.1.574.g5d30c73bfb-goog + @@ -87,21 +87,43 @@ pub use env_logger::fmt::Formatter; pub(crate) type FormatFn = Box<dyn Fn(&mut dyn fmt::Write, &Record) -> fmt::Result + Sync + Send>; +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub enum LogId { + Main, + Radio, + Events, + System, + Crash +} + +impl LogId { + #[cfg(target_os = "android")] + fn to_native(log_id: Option<Self>) -> log_ffi::log_id_t { + match log_id { + Some(LogId::Main) => log_ffi::log_id_t::MAIN, + Some(LogId::Radio) => log_ffi::log_id_t::RADIO, + Some(LogId::Events) => log_ffi::log_id_t::EVENTS, + Some(LogId::System) => log_ffi::log_id_t::SYSTEM, + Some(LogId::Crash) => log_ffi::log_id_t::CRASH, + None => log_ffi::log_id_t::DEFAULT, + } + } +} + /// Output log to android system. #[cfg(target_os = "android")] -fn android_log(prio: log_ffi::LogPriority, tag: &CStr, msg: &CStr) { +fn android_log(log_id: log_ffi::log_id_t, prio: log_ffi::LogPriority, tag: &CStr, msg: &CStr) { unsafe { - log_ffi::__android_log_write( - prio as log_ffi::c_int, - tag.as_ptr() as *const log_ffi::c_char, - msg.as_ptr() as *const log_ffi::c_char, - ) + log_ffi::__android_log_buf_write(log_id as i32, + prio as i32, + tag.as_ptr() as *const log_ffi::c_char, + msg.as_ptr() as *const log_ffi::c_char); }; } /// Dummy output placeholder for tests. #[cfg(not(target_os = "android"))] -fn android_log(_priority: Level, _tag: &CStr, _msg: &CStr) {} +fn android_log(_log_id: Option<LogId>, _priority: Level, _tag: &CStr, _msg: &CStr) {} /// Underlying android logger backend pub struct AndroidLogger { @@ -164,7 +186,7 @@ impl Log for AndroidLogger { // message must not exceed LOGGING_MSG_MAX_LEN // therefore split log message into multiple log calls - let mut writer = PlatformLogWriter::new(record.level(), tag); + let mut writer = PlatformLogWriter::new(config.log_id, record.level(), tag); // If a custom tag is used, add the module path to the message. // Use PlatformLogWriter to output chunks if they exceed max size. @@ -208,6 +230,7 @@ impl AndroidLogger { /// Filter for android logger. pub struct Config { log_level: Option<Level>, + log_id: Option<LogId>, filter: Option<env_logger::filter::Filter>, tag: Option<CString>, custom_format: Option<FormatFn>, @@ -217,6 +240,7 @@ impl Default for Config { fn default() -> Self { Config { log_level: None, + log_id: None, filter: None, tag: None, custom_format: None, @@ -234,6 +258,15 @@ impl Config { self } + /// Change which log buffer is used + /// + /// By default, logs are sent to the `Main` log. Other logging buffers may only be accessible + /// to certain processes. + pub fn with_log_id(mut self, log_id: LogId) -> Self { + self.log_id = Some(log_id); + self + } + fn filter_matches(&self, record: &Record) -> bool { if let Some(ref filter) = self.filter { filter.matches(&record) @@ -273,6 +306,8 @@ impl Config { struct PlatformLogWriter<'a> { #[cfg(target_os = "android")] priority: LogPriority, #[cfg(not(target_os = "android"))] priority: Level, + #[cfg(target_os = "android")] log_id: log_ffi::log_id_t, + #[cfg(not(target_os = "android"))] log_id: Option<LogId>, len: usize, last_newline_index: usize, tag: &'a CStr, @@ -281,7 +316,7 @@ struct PlatformLogWriter<'a> { impl<'a> PlatformLogWriter<'a> { #[cfg(target_os = "android")] - pub fn new(level: Level, tag: &CStr) -> PlatformLogWriter { + pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter { #[allow(deprecated)] // created an issue #35 for this PlatformLogWriter { priority: match level { @@ -291,6 +326,7 @@ impl<'a> PlatformLogWriter<'a> { Level::Error => LogPriority::ERROR, Level::Trace => LogPriority::VERBOSE, }, + log_id: LogId::to_native(log_id), len: 0, last_newline_index: 0, tag, @@ -299,10 +335,11 @@ impl<'a> PlatformLogWriter<'a> { } #[cfg(not(target_os = "android"))] - pub fn new(level: Level, tag: &CStr) -> PlatformLogWriter { + pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter { #[allow(deprecated)] // created an issue #35 for this PlatformLogWriter { priority: level, + log_id, len: 0, last_newline_index: 0, tag, @@ -358,7 +395,7 @@ impl<'a> PlatformLogWriter<'a> { }); let msg: &CStr = unsafe { CStr::from_ptr(mem::transmute(self.buffer.as_ptr())) }; - android_log(self.priority, self.tag, msg); + android_log(self.log_id, self.priority, self.tag, msg); *unsafe { self.buffer.get_unchecked_mut(len) } = last_byte; } @@ -458,9 +495,11 @@ mod tests { // Filter is checked in config_filter_match below. let config = Config::default() .with_min_level(Level::Trace) + .with_log_id(LogId::System) .with_tag("my_app"); assert_eq!(config.log_level, Some(Level::Trace)); + assert_eq!(config.log_id, Some(LogId::System)); assert_eq!(config.tag, Some(CString::new("my_app").unwrap())); } @@ -531,7 +570,7 @@ mod tests { fn platform_log_writer_init_values() { let tag = CStr::from_bytes_with_nul(b"tag\0").unwrap(); - let writer = PlatformLogWriter::new(Level::Warn, &tag); + let writer = PlatformLogWriter::new(None, Level::Warn, &tag); assert_eq!(writer.tag, tag); // Android uses LogPriority instead, which doesn't implement equality checks @@ -630,6 +669,6 @@ mod tests { } fn get_tag_writer() -> PlatformLogWriter<'static> { - PlatformLogWriter::new(Level::Warn, &CStr::from_bytes_with_nul(b"tag\0").unwrap()) + PlatformLogWriter::new(None, Level::Warn, &CStr::from_bytes_with_nul(b"tag\0").unwrap()) } } |