Snap for 10453563 from f6151f845dd997a9e324388d07b7142c6c346914 to mainline-ipsec-release
Change-Id: I746748dd3333036c9d54c6ca45935208ad4301f6
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 00435b7..c1be5ef 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,6 @@
{
"git": {
- "sha1": "c20ec25acacf0731583140b230e6ce94e59b054d"
- }
-}
+ "sha1": "596b92d5907f0054884412d2f7137704edae4208"
+ },
+ "path_in_vcs": ""
+}
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 056c310..f03803b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,7 +43,7 @@
name: "android_logger_test_src_lib",
crate_name: "android_logger",
cargo_env_compat: true,
- cargo_pkg_version: "0.10.1",
+ cargo_pkg_version: "0.12.0",
srcs: ["src/lib.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -55,8 +55,8 @@
rustlibs: [
"libandroid_log_sys",
"libenv_logger",
- "liblazy_static",
"liblog_rust",
+ "libonce_cell",
],
}
@@ -64,7 +64,7 @@
name: "android_logger_test_defaults",
crate_name: "android_logger",
cargo_env_compat: true,
- cargo_pkg_version: "0.10.1",
+ cargo_pkg_version: "0.12.0",
test_suites: ["general-tests"],
auto_gen_config: true,
edition: "2015",
@@ -76,8 +76,8 @@
"libandroid_log_sys",
"libandroid_logger",
"libenv_logger",
- "liblazy_static",
"liblog_rust",
+ "libonce_cell",
],
}
@@ -103,7 +103,7 @@
name: "libandroid_logger",
crate_name: "android_logger",
cargo_env_compat: true,
- cargo_pkg_version: "0.10.1",
+ cargo_pkg_version: "0.12.0",
srcs: ["src/lib.rs"],
edition: "2015",
features: [
@@ -113,17 +113,14 @@
rustlibs: [
"libandroid_log_sys",
"libenv_logger",
- "liblazy_static",
"liblog_rust",
+ "libonce_cell",
],
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
- "com.android.compos",
- "com.android.resolv",
- "com.android.uwb",
- "com.android.virt",
+ "//apex_available:anyapex",
],
+ product_available: true,
vendor_available: true,
min_sdk_version: "29",
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..4952ca1
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,54 @@
+`android_logger` changelog
+==========================
+
+All user visible changes to this project will be documented in this file. This project uses [Semantic Versioning 2.0.0].
+
+
+
+
+## [0.12.0] · 2023-01-19
+[0.12.0]: /../../tree/v0.12.0
+
+[Diff](/../../compare/v0.11.3...v0.12.0)
+
+### Added
+
+- `Config::with_max_level()` method to filters logs via `log::LevelFilter`. ([#62])
+
+### Deprecated
+
+- `Config::with_min_level()` method accepting `log::Level`. ([#62])
+
+### Fixed
+
+- Incorrect logs level filtering. ([#62])
+
+[#62]: /../../pull/62
+
+
+
+
+## [0.11.3] · 2022-12-20
+[0.11.3]: /../../tree/v0.11.3
+
+[Diff](/../../compare/38186ece1056d90b8f75fd2a5eb5c860e0a1704e...v0.11.3)
+
+### Fixed
+
+- Broken compilation on [Android] targets. ([#59], [#58])
+
+[#58]: /../../issues/58
+[#59]: /../../pull/59
+
+
+
+
+## Previous releases
+
+See [Git log](/../../commits/master?after=1a5a07ec6742f0069acc2be223c1bb3b6a9d15f8+0).
+
+
+
+
+[Android]: https://www.android.com
+[Semantic Versioning 2.0.0]: https://semver.org
diff --git a/Cargo.toml b/Cargo.toml
index dec0113..a9fd573 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,38 +3,46 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
name = "android_logger"
-version = "0.10.1"
+version = "0.12.0"
authors = ["The android_logger Developers"]
-description = "A logging implementation for `log` which hooks to android log output.\n"
+description = """
+A logging implementation for `log` which hooks to android log output.
+"""
readme = "README.md"
-keywords = ["android", "bindings", "log", "logger"]
+keywords = [
+ "android",
+ "bindings",
+ "log",
+ "logger",
+]
categories = ["api-bindings"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/Nercury/android_logger-rs"
+
[dependencies.android_log-sys]
version = "0.2"
[dependencies.env_logger]
-version = "0.8"
+version = "0.10"
default-features = false
-[dependencies.lazy_static]
-version = "1.4"
-
[dependencies.log]
version = "0.4"
+[dependencies.once_cell]
+version = "1.9"
+
[features]
default = ["regex"]
regex = ["env_logger/regex"]
+
[badges.travis-ci]
repository = "Nercury/android_logger-rs"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index a9ad77f..ca1b723 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "android_logger"
-version = "0.10.1"
+version = "0.12.0"
authors = ["The android_logger Developers"]
license = "MIT OR Apache-2.0"
readme = "README.md"
@@ -16,7 +16,7 @@
regex = ["env_logger/regex"]
[dependencies]
-lazy_static = "1.4"
+once_cell = "1.9"
[dependencies.log]
version = "0.4"
@@ -25,7 +25,7 @@
version = "0.2"
[dependencies.env_logger]
-version = "0.8"
+version = "0.10"
default-features = false
[badges]
diff --git a/METADATA b/METADATA
index 27e229f..df2996f 100644
--- a/METADATA
+++ b/METADATA
@@ -1,5 +1,5 @@
name: "android_logger"
-description: "A logging implementation for `log` which hooks to android log output."
+description: "()"
third_party {
url {
type: HOMEPAGE
@@ -7,13 +7,14 @@
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/android_logger/android_logger-0.10.1.crate"
+ value: "https://static.crates.io/crates/android_logger/android_logger-0.12.0.crate"
}
- version: "0.10.1"
+ version: "0.12.0"
+ # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same.
license_type: NOTICE
last_upgrade_date {
- year: 2021
- month: 4
- day: 19
+ year: 2023
+ month: 2
+ day: 2
}
}
diff --git a/OWNERS b/OWNERS
index 46fc303..45dc4dd 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1 +1 @@
-include platform/prebuilts/rust:/OWNERS
+include platform/prebuilts/rust:master:/OWNERS
diff --git a/README.md b/README.md
index c3b88bf..eec1eba 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
```toml
[target.'cfg(target_os = "android")'.dependencies]
-android_logger = "0.10"
+android_logger = "0.11"
```
Example of initialization on activity creation, with log configuration:
@@ -22,13 +22,13 @@
#[macro_use] extern crate log;
extern crate android_logger;
-use log::Level;
+use log::LevelFilter;
use android_logger::{Config,FilterBuilder};
fn native_activity_create() {
android_logger::init_once(
Config::default()
- .with_min_level(Level::Trace) // limit log level
+ .with_max_level(LevelFilter::Trace) // limit log level
.with_tag("mytag") // logs will show under mytag tag
.with_filter( // configure messages for specific crate
FilterBuilder::new()
@@ -47,12 +47,13 @@
#[macro_use] extern crate log;
extern crate android_logger;
-use log::Level;
+use log::LevelFilter;
use android_logger::Config;
fn native_activity_create() {
android_logger::init_once(
- Config::default().with_min_level(Level::Trace));
+ Config::default().with_max_level(LevelFilter::Trace),
+ );
}
```
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 526e77a..d42c05d 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,5 +1,28 @@
// Generated by update_crate_tests.py for tests that depend on this crate.
{
+ "imports": [
+ {
+ "path": "packages/modules/DnsResolver"
+ },
+ {
+ "path": "packages/modules/Virtualization/authfs"
+ },
+ {
+ "path": "packages/modules/Virtualization/encryptedstore"
+ },
+ {
+ "path": "packages/modules/Virtualization/virtualizationmanager"
+ },
+ {
+ "path": "system/logging/rust"
+ },
+ {
+ "path": "system/security/keystore2"
+ },
+ {
+ "path": "system/security/keystore2/selinux"
+ }
+ ],
"presubmit": [
{
"name": "android_logger_test_src_lib"
@@ -12,39 +35,6 @@
},
{
"name": "android_logger_test_tests_multiple_init"
- },
- {
- "name": "authfs_device_test_src_lib"
- },
- {
- "name": "doh_unit_test"
- },
- {
- "name": "keystore2_selinux_concurrency_test"
- },
- {
- "name": "keystore2_selinux_test"
- },
- {
- "name": "keystore2_test"
- },
- {
- "name": "logger_device_unit_tests"
- },
- {
- "name": "logger_test_config_log_level"
- },
- {
- "name": "logger_test_default_init"
- },
- {
- "name": "logger_test_env_log_level"
- },
- {
- "name": "logger_test_multiple_init"
- },
- {
- "name": "virtualizationservice_device_test"
}
],
"presubmit-rust": [
@@ -59,39 +49,6 @@
},
{
"name": "android_logger_test_tests_multiple_init"
- },
- {
- "name": "authfs_device_test_src_lib"
- },
- {
- "name": "doh_unit_test"
- },
- {
- "name": "keystore2_selinux_concurrency_test"
- },
- {
- "name": "keystore2_selinux_test"
- },
- {
- "name": "keystore2_test"
- },
- {
- "name": "logger_device_unit_tests"
- },
- {
- "name": "logger_test_config_log_level"
- },
- {
- "name": "logger_test_default_init"
- },
- {
- "name": "logger_test_env_log_level"
- },
- {
- "name": "logger_test_multiple_init"
- },
- {
- "name": "virtualizationservice_device_test"
}
]
}
diff --git a/cargo2android.json b/cargo2android.json
index 18ba06d..2733be4 100644
--- a/cargo2android.json
+++ b/cargo2android.json
@@ -1,11 +1,7 @@
{
"apex-available": [
"//apex_available:platform",
- "com.android.bluetooth",
- "com.android.compos",
- "com.android.resolv",
- "com.android.uwb",
- "com.android.virt"
+ "//apex_available:anyapex"
],
"dependencies": true,
"device": true,
diff --git a/patches/0001-Support-selecting-target-log-buffer.patch b/patches/0001-Support-selecting-target-log-buffer.patch
index e5fc33b..a9e11a4 100644
--- a/patches/0001-Support-selecting-target-log-buffer.patch
+++ b/patches/0001-Support-selecting-target-log-buffer.patch
@@ -1,6 +1,6 @@
-From 2bc2650d0a7a11a74670a6583b16aa6714d7c993 Mon Sep 17 00:00:00 2001
-From: Matthew Maurer <mmaurer@google.com>
-Date: Thu, 17 Feb 2022 20:23:37 +0000
+From a41a079a81f381f2002917fb1c030690e0798f0c Mon Sep 17 00:00:00 2001
+From: Jeff Vander Stoep <jeffv@google.com>
+Date: Thu, 2 Feb 2023 13:33:47 +0100
Subject: [PATCH] Support selecting target log buffer
Android has several different log buffers. Previously, this library
@@ -8,16 +8,17 @@
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
+Test: atest
+Change-Id: I3cc393b989b8189675581ba6bf700f95715aa9e9
---
- src/lib.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++----------
- 1 file changed, 58 insertions(+), 13 deletions(-)
+ src/lib.rs | 73 +++++++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 59 insertions(+), 14 deletions(-)
diff --git a/src/lib.rs b/src/lib.rs
-index 11a127e..d21be3f 100644
+index 0446fad..9ec7f0d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
-@@ -87,21 +87,49 @@ pub use env_logger::fmt::Formatter;
+@@ -85,21 +85,49 @@ pub use env_logger::fmt::Formatter;
pub(crate) type FormatFn = Box<dyn Fn(&mut dyn fmt::Write, &Record) -> fmt::Result + Sync + Send>;
@@ -74,7 +75,7 @@
/// Underlying android logger backend
pub struct AndroidLogger {
-@@ -164,7 +192,7 @@ impl Log for AndroidLogger {
+@@ -172,7 +200,7 @@ impl Log for AndroidLogger {
// message must not exceed LOGGING_MSG_MAX_LEN
// therefore split log message into multiple log calls
@@ -83,23 +84,15 @@
// 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.
+@@ -215,6 +243,7 @@ impl AndroidLogger {
+ #[derive(Default)]
pub struct Config {
- log_level: Option<Level>,
+ log_level: Option<LevelFilter>,
+ 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 {
+@@ -241,6 +270,15 @@ impl Config {
self
}
@@ -114,34 +107,41 @@
+
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,
+ filter.matches(record)
+@@ -282,6 +320,8 @@ pub struct PlatformLogWriter<'a> {
+ 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> {
+@@ -290,10 +330,11 @@ pub 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 {
+- pub fn new_with_priority(priority: log_ffi::LogPriority, tag: &CStr) -> PlatformLogWriter {
++ pub fn new_with_priority(log_id: Option<LogId>, priority: log_ffi::LogPriority, 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,
- },
+ priority,
+ log_id: LogId::to_native(log_id),
len: 0,
last_newline_index: 0,
tag,
-@@ -299,10 +341,11 @@ impl<'a> PlatformLogWriter<'a> {
+@@ -302,8 +343,9 @@ 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 {
+ Self::new_with_priority(
++ log_id,
+ match level {
+ Level::Warn => LogPriority::WARN,
+ Level::Info => LogPriority::INFO,
+@@ -316,10 +358,11 @@ impl<'a> PlatformLogWriter<'a> {
}
#[cfg(not(target_os = "android"))]
@@ -154,44 +154,45 @@
len: 0,
last_newline_index: 0,
tag,
-@@ -358,7 +401,7 @@ impl<'a> PlatformLogWriter<'a> {
+@@ -376,7 +419,7 @@ impl<'a> PlatformLogWriter<'a> {
});
- let msg: &CStr = unsafe { CStr::from_ptr(mem::transmute(self.buffer.as_ptr())) };
+ let msg: &CStr = unsafe { CStr::from_ptr(self.buffer.as_ptr().cast()) };
- 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;
+ unsafe { *self.buffer.get_unchecked_mut(len) = last_byte };
}
-@@ -458,9 +501,11 @@ mod tests {
+@@ -481,9 +524,11 @@ mod tests {
// Filter is checked in config_filter_match below.
let config = Config::default()
- .with_min_level(Level::Trace)
+ .with_max_level(LevelFilter::Trace)
+ .with_log_id(LogId::System)
.with_tag("my_app");
- assert_eq!(config.log_level, Some(Level::Trace));
+ assert_eq!(config.log_level, Some(LevelFilter::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 {
+@@ -556,7 +601,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);
+- 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 {
+@@ -661,7 +706,7 @@ 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())
+- 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())
}
- }
+
+ unsafe fn assume_init_slice<T>(slice: &[MaybeUninit<T>]) -> &[T] {
--
-2.35.1.265.g69c8d7142f-goog
+2.39.1.456.gfc5497dd1b-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
index 721e9eb..44f08fb 100644
--- a/patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch
+++ b/patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch
@@ -1,20 +1,20 @@
-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
+From b5ee33076e1868c5946345b2cfb15a519b8c2577 Mon Sep 17 00:00:00 2001
+From: Jeff Vander Stoep <jeffv@google.com>
+Date: Mon, 5 Dec 2022 12:42:22 +0100
+Subject: [PATCH 2/2] Use older API to avoid requiring API v30
Test: Check that keystore still outputs logs to system
Bug: 221185310
-Change-Id: I25174f1617557e270db70cd432cec78c037c6b75
+Change-Id: If81d66cb145cbb41b4338fd64ac024d77243482e
---
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
+index 4bcce0c..59f942b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
-@@ -113,17 +113,11 @@ impl LogId {
+@@ -111,17 +111,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) {
@@ -37,5 +37,5 @@
}
--
-2.35.1.574.g5d30c73bfb-goog
+2.39.0.rc0.267.gcb52ba06e7-goog
diff --git a/src/lib.rs b/src/lib.rs
index bc4fa61..c22f07e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,13 +13,13 @@
//! #[macro_use] extern crate log;
//! extern crate android_logger;
//!
-//! use log::Level;
+//! use log::LevelFilter;
//! use android_logger::Config;
//!
//! /// Android code may not have obvious "main", this is just an example.
//! fn main() {
//! android_logger::init_once(
-//! Config::default().with_min_level(Level::Trace),
+//! Config::default().with_max_level(LevelFilter::Trace),
//! );
//!
//! debug!("this is a debug {}", "message");
@@ -36,13 +36,13 @@
//! #[macro_use] extern crate log;
//! extern crate android_logger;
//!
-//! use log::Level;
+//! use log::LevelFilter;
//! use android_logger::{Config,FilterBuilder};
//!
//! fn main() {
//! android_logger::init_once(
//! Config::default()
-//! .with_min_level(Level::Trace)
+//! .with_max_level(LevelFilter::Trace)
//! .with_tag("mytag")
//! .with_filter(FilterBuilder::new().parse("debug,hello::crate=trace").build()),
//! );
@@ -58,31 +58,29 @@
//!
//! android_logger::init_once(
//! Config::default()
-//! .with_min_level(log::Level::Trace)
+//! .with_max_level(log::LevelFilter::Trace)
//! .format(|f, record| write!(f, "my_app: {}", record.args()))
//! )
//! ```
#[cfg(target_os = "android")]
extern crate android_log_sys as log_ffi;
-#[macro_use]
-extern crate lazy_static;
+extern crate once_cell;
+use once_cell::sync::OnceCell;
#[macro_use]
extern crate log;
extern crate env_logger;
-use std::sync::RwLock;
-
+use log::{Level, LevelFilter, Log, Metadata, Record};
#[cfg(target_os = "android")]
use log_ffi::LogPriority;
-use log::{Level, Log, Metadata, Record};
use std::ffi::{CStr, CString};
-use std::mem;
use std::fmt;
+use std::mem::{self, MaybeUninit};
use std::ptr;
-pub use env_logger::filter::{Filter, Builder as FilterBuilder};
+pub use env_logger::filter::{Builder as FilterBuilder, Filter};
pub use env_logger::fmt::Formatter;
pub(crate) type FormatFn = Box<dyn Fn(&mut dyn fmt::Write, &Record) -> fmt::Result + Sync + Send>;
@@ -127,21 +125,23 @@
/// Underlying android logger backend
pub struct AndroidLogger {
- config: RwLock<Config>,
+ config: OnceCell<Config>,
}
impl AndroidLogger {
/// Create new logger instance from config
pub fn new(config: Config) -> AndroidLogger {
AndroidLogger {
- config: RwLock::new(config),
+ config: OnceCell::from(config),
}
}
+
+ fn config(&self) -> &Config {
+ self.config.get_or_init(Config::default)
+ }
}
-lazy_static! {
- static ref ANDROID_LOGGER: AndroidLogger = AndroidLogger::default();
-}
+static ANDROID_LOGGER: OnceCell<AndroidLogger> = OnceCell::new();
const LOGGING_TAG_MAX_LEN: usize = 23;
const LOGGING_MSG_MAX_LEN: usize = 4000;
@@ -150,34 +150,42 @@
/// Create a new logger with default config
fn default() -> AndroidLogger {
AndroidLogger {
- config: RwLock::new(Config::default()),
+ config: OnceCell::from(Config::default()),
}
}
}
impl Log for AndroidLogger {
- fn enabled(&self, _: &Metadata) -> bool {
- true
+ fn enabled(&self, metadata: &Metadata) -> bool {
+ let config = self.config();
+ // todo: consider __android_log_is_loggable.
+ metadata.level() <= config.log_level.unwrap_or_else(log::max_level)
}
fn log(&self, record: &Record) {
- let config = self.config
- .read()
- .expect("failed to acquire android_log filter lock for read");
+ let config = self.config();
+ if !self.enabled(record.metadata()) {
+ return;
+ }
+
+ // this also checks the level, but only if a filter was
+ // installed.
if !config.filter_matches(record) {
return;
}
// tag must not exceed LOGGING_TAG_MAX_LEN
- #[allow(deprecated)] // created an issue #35 for this
- let mut tag_bytes: [u8; LOGGING_TAG_MAX_LEN + 1] = unsafe { mem::uninitialized() };
+ let mut tag_bytes: [MaybeUninit<u8>; LOGGING_TAG_MAX_LEN + 1] = uninit_array();
let module_path = record.module_path().unwrap_or_default().to_owned();
// If no tag was specified, use module name
let custom_tag = &config.tag;
- let tag = custom_tag.as_ref().map(|s| s.as_bytes()).unwrap_or(module_path.as_bytes());
+ let tag = custom_tag
+ .as_ref()
+ .map(|s| s.as_bytes())
+ .unwrap_or_else(|| module_path.as_bytes());
// truncate the tag here to fit into LOGGING_TAG_MAX_LEN
self.fill_tag_bytes(&mut tag_bytes, tag);
@@ -207,53 +215,51 @@
}
impl AndroidLogger {
- fn fill_tag_bytes(&self, array: &mut [u8], tag: &[u8]) {
+ fn fill_tag_bytes(&self, array: &mut [MaybeUninit<u8>], tag: &[u8]) {
if tag.len() > LOGGING_TAG_MAX_LEN {
- for (input, output) in tag.iter()
+ for (input, output) in tag
+ .iter()
.take(LOGGING_TAG_MAX_LEN - 2)
.chain(b"..\0".iter())
.zip(array.iter_mut())
{
- *output = *input;
+ output.write(*input);
}
} else {
- for (input, output) in tag.iter()
- .chain(b"\0".iter())
- .zip(array.iter_mut())
- {
- *output = *input;
+ for (input, output) in tag.iter().chain(b"\0".iter()).zip(array.iter_mut()) {
+ output.write(*input);
}
}
}
}
/// Filter for android logger.
+#[derive(Default)]
pub struct Config {
- log_level: Option<Level>,
+ log_level: Option<LevelFilter>,
log_id: Option<LogId>,
filter: Option<env_logger::filter::Filter>,
tag: Option<CString>,
custom_format: Option<FormatFn>,
}
-impl Default for Config {
- fn default() -> Self {
- Config {
- log_level: None,
- log_id: None,
- filter: None,
- tag: None,
- custom_format: None,
- }
- }
-}
-
impl Config {
- /// Change the minimum log level.
+ // TODO: Remove on 0.13 version release.
+ /// **DEPRECATED**, use [`Config::with_max_level()`] instead.
+ #[deprecated(note = "use `.with_max_level()` instead")]
+ pub fn with_min_level(self, level: Level) -> Self {
+ self.with_max_level(level.to_level_filter())
+ }
+
+ /// Changes the maximum log level.
///
- /// All values above the set level are logged. For example, if
- /// `Warn` is set, the `Error` is logged too, but `Info` isn't.
- pub fn with_min_level(mut self, level: Level) -> Self {
+ /// Note, that `Trace` is the maximum level, because it provides the
+ /// maximum amount of detail in the emitted logs.
+ ///
+ /// If `Off` level is provided, then nothing is logged at all.
+ ///
+ /// [`log::max_level()`] is considered as the default level.
+ pub fn with_max_level(mut self, level: LevelFilter) -> Self {
self.log_level = Some(level);
self
}
@@ -269,7 +275,7 @@
fn filter_matches(&self, record: &Record) -> bool {
if let Some(ref filter) = self.filter {
- filter.matches(&record)
+ filter.matches(record)
} else {
true
}
@@ -290,7 +296,7 @@
/// # use android_logger::Config;
/// android_logger::init_once(
/// Config::default()
- /// .with_min_level(log::Level::Trace)
+ /// .with_max_level(log::LevelFilter::Trace)
/// .format(|f, record| write!(f, "my_app: {}", record.args()))
/// )
/// ```
@@ -303,35 +309,46 @@
}
}
-struct PlatformLogWriter<'a> {
- #[cfg(target_os = "android")] priority: LogPriority,
- #[cfg(not(target_os = "android"))] priority: Level,
+pub 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,
- buffer: [u8; LOGGING_MSG_MAX_LEN + 1],
+ buffer: [MaybeUninit<u8>; LOGGING_MSG_MAX_LEN + 1],
}
impl<'a> PlatformLogWriter<'a> {
#[cfg(target_os = "android")]
- pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter {
+ pub fn new_with_priority(log_id: Option<LogId>, priority: log_ffi::LogPriority, tag: &CStr) -> PlatformLogWriter {
#[allow(deprecated)] // created an issue #35 for this
PlatformLogWriter {
- priority: match level {
+ priority,
+ log_id: LogId::to_native(log_id),
+ len: 0,
+ last_newline_index: 0,
+ tag,
+ buffer: uninit_array(),
+ }
+ }
+
+ #[cfg(target_os = "android")]
+ pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter {
+ Self::new_with_priority(
+ log_id,
+ match level {
Level::Warn => LogPriority::WARN,
Level::Info => LogPriority::INFO,
Level::Debug => LogPriority::DEBUG,
Level::Error => LogPriority::ERROR,
Level::Trace => LogPriority::VERBOSE,
},
- log_id: LogId::to_native(log_id),
- len: 0,
- last_newline_index: 0,
tag,
- buffer: unsafe { mem::uninitialized() },
- }
+ )
}
#[cfg(not(target_os = "android"))]
@@ -343,7 +360,7 @@
len: 0,
last_newline_index: 0,
tag,
- buffer: unsafe { mem::uninitialized() },
+ buffer: uninit_array(),
}
}
@@ -375,7 +392,7 @@
}
/// Flush everything remaining to android logger.
- fn flush(&mut self) {
+ pub fn flush(&mut self) {
let total_len = self.len;
if total_len == 0 {
@@ -389,21 +406,22 @@
/// Output buffer up until the \0 which will be placed at `len` position.
fn output_specified_len(&mut self, len: usize) {
- let mut last_byte: u8 = b'\0';
+ let mut last_byte = MaybeUninit::new(b'\0');
+
mem::swap(&mut last_byte, unsafe {
self.buffer.get_unchecked_mut(len)
});
- let msg: &CStr = unsafe { CStr::from_ptr(mem::transmute(self.buffer.as_ptr())) };
+ let msg: &CStr = unsafe { CStr::from_ptr(self.buffer.as_ptr().cast()) };
android_log(self.log_id, self.priority, self.tag, msg);
- *unsafe { self.buffer.get_unchecked_mut(len) } = last_byte;
+ unsafe { *self.buffer.get_unchecked_mut(len) = last_byte };
}
/// Copy `len` bytes from `index` position to starting position.
fn copy_bytes_to_start(&mut self, index: usize, len: usize) {
- let src = unsafe { self.buffer.as_ptr().offset(index as isize) };
let dst = self.buffer.as_mut_ptr();
+ let src = unsafe { self.buffer.as_ptr().add(index) };
unsafe { ptr::copy(src, dst, len) };
}
}
@@ -422,7 +440,7 @@
.zip(incomming_bytes)
.enumerate()
.fold(None, |acc, (i, (output, input))| {
- *output = *input;
+ output.write(*input);
if *input == b'\n' {
Some(i)
} else {
@@ -460,7 +478,9 @@
/// This action does not require initialization. However, without initialization it
/// will use the default filter, which allows all logs.
pub fn log(record: &Record) {
- ANDROID_LOGGER.log(record)
+ ANDROID_LOGGER
+ .get_or_init(AndroidLogger::default)
+ .log(record)
}
/// Initializes the global logger with an android logger.
@@ -471,19 +491,22 @@
/// It is ok to call this at the activity creation, and it will be
/// repeatedly called on every lifecycle restart (i.e. screen rotation).
pub fn init_once(config: Config) {
- if let Err(err) = log::set_logger(&*ANDROID_LOGGER) {
+ let log_level = config.log_level;
+ let logger = ANDROID_LOGGER.get_or_init(|| AndroidLogger::new(config));
+
+ if let Err(err) = log::set_logger(logger) {
debug!("android_logger: log::set_logger failed: {}", err);
- } else {
- if let Some(level) = config.log_level {
- log::set_max_level(level.to_level_filter());
- }
- *ANDROID_LOGGER
- .config
- .write()
- .expect("failed to acquire android_log filter lock for write") = config;
+ } else if let Some(level) = log_level {
+ log::set_max_level(level);
}
}
+// FIXME: When `maybe_uninit_uninit_array ` is stabilized, use it instead of this helper
+fn uninit_array<const N: usize, T>() -> [MaybeUninit<T>; N] {
+ // SAFETY: Array contains MaybeUninit, which is fine to be uninit
+ unsafe { MaybeUninit::uninit().assume_init() }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -494,11 +517,11 @@
fn check_config_values() {
// Filter is checked in config_filter_match below.
let config = Config::default()
- .with_min_level(Level::Trace)
+ .with_max_level(LevelFilter::Trace)
.with_log_id(LogId::System)
.with_tag("my_app");
- assert_eq!(config.log_level, Some(Level::Trace));
+ assert_eq!(config.log_level, Some(LevelFilter::Trace));
assert_eq!(config.log_id, Some(LogId::System));
assert_eq!(config.tag, Some(CString::new("my_app").unwrap()));
}
@@ -507,7 +530,7 @@
fn log_calls_formatter() {
static FORMAT_FN_WAS_CALLED: AtomicBool = AtomicBool::new(false);
let config = Config::default()
- .with_min_level(Level::Info)
+ .with_max_level(LevelFilter::Info)
.format(|_, _| {
FORMAT_FN_WAS_CALLED.store(true, Ordering::SeqCst);
Ok(())
@@ -520,10 +543,12 @@
}
#[test]
- fn logger_always_enabled() {
- let logger = AndroidLogger::new(Config::default());
+ fn logger_enabled_threshold() {
+ let logger = AndroidLogger::new(Config::default().with_max_level(LevelFilter::Info));
- assert!(logger.enabled(&log::MetadataBuilder::new().build()));
+ assert!(logger.enabled(&log::MetadataBuilder::new().level(Level::Warn).build()));
+ assert!(logger.enabled(&log::MetadataBuilder::new().level(Level::Info).build()));
+ assert!(!logger.enabled(&log::MetadataBuilder::new().level(Level::Debug).build()));
}
// Test whether the filter gets called correctly. Not meant to be exhaustive for all filter
@@ -545,12 +570,12 @@
let logger = AndroidLogger::new(Config::default());
let too_long_tag: [u8; LOGGING_TAG_MAX_LEN + 20] = [b'a'; LOGGING_TAG_MAX_LEN + 20];
- let mut result: [u8; LOGGING_TAG_MAX_LEN + 1] = Default::default();
+ let mut result: [MaybeUninit<u8>; LOGGING_TAG_MAX_LEN + 1] = uninit_array();
logger.fill_tag_bytes(&mut result, &too_long_tag);
let mut expected_result = [b'a'; LOGGING_TAG_MAX_LEN - 2].to_vec();
expected_result.extend("..\0".as_bytes());
- assert_eq!(result.to_vec(), expected_result);
+ assert_eq!(unsafe { assume_init_slice(&result) }, expected_result);
}
#[test]
@@ -558,19 +583,19 @@
let logger = AndroidLogger::new(Config::default());
let short_tag: [u8; 3] = [b'a'; 3];
- let mut result: [u8; LOGGING_TAG_MAX_LEN + 1] = Default::default();
+ let mut result: [MaybeUninit<u8>; LOGGING_TAG_MAX_LEN + 1] = uninit_array();
logger.fill_tag_bytes(&mut result, &short_tag);
let mut expected_result = short_tag.to_vec();
expected_result.push(0);
- assert_eq!(result.to_vec()[..4], expected_result);
+ assert_eq!(unsafe { assume_init_slice(&result[..4]) }, expected_result);
}
#[test]
fn platform_log_writer_init_values() {
let tag = CStr::from_bytes_with_nul(b"tag\0").unwrap();
- let writer = PlatformLogWriter::new(None, 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
@@ -591,7 +616,10 @@
// Should have flushed up until the last newline.
assert_eq!(writer.len, 3);
assert_eq!(writer.last_newline_index, 0);
- assert_eq!(&writer.buffer.to_vec()[..writer.len], "\n90".as_bytes());
+ assert_eq!(
+ unsafe { assume_init_slice(&writer.buffer[..writer.len]) },
+ "\n90".as_bytes()
+ );
writer.temporal_flush();
// Should have flushed all remaining bytes.
@@ -634,7 +662,7 @@
writer.output_specified_len(5);
assert_eq!(
- writer.buffer[..log_string.len()].to_vec(),
+ unsafe { assume_init_slice(&writer.buffer[..log_string.len()]) },
log_string.as_bytes()
);
}
@@ -648,7 +676,10 @@
writer.copy_bytes_to_start(3, 2);
- assert_eq!(writer.buffer[..10].to_vec(), "3423456789".as_bytes());
+ assert_eq!(
+ unsafe { assume_init_slice(&writer.buffer[..10]) },
+ "3423456789".as_bytes()
+ );
}
#[test]
@@ -663,12 +694,16 @@
writer.copy_bytes_to_start(10, 0);
assert_eq!(
- writer.buffer[..test_string.len()].to_vec(),
+ unsafe { assume_init_slice(&writer.buffer[..test_string.len()]) },
test_string.as_bytes()
);
}
fn get_tag_writer() -> PlatformLogWriter<'static> {
- PlatformLogWriter::new(None, 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())
+ }
+
+ unsafe fn assume_init_slice<T>(slice: &[MaybeUninit<T>]) -> &[T] {
+ &*(slice as *const [MaybeUninit<T>] as *const [T])
}
}
diff --git a/tests/config_log_level.rs b/tests/config_log_level.rs
index ca6ad59..864b229 100644
--- a/tests/config_log_level.rs
+++ b/tests/config_log_level.rs
@@ -3,7 +3,9 @@
#[test]
fn config_log_level() {
- android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Trace));
+ android_logger::init_once(
+ android_logger::Config::default().with_max_level(log::LevelFilter::Trace),
+ );
assert_eq!(log::max_level(), log::LevelFilter::Trace);
-}
\ No newline at end of file
+}
diff --git a/tests/default_init.rs b/tests/default_init.rs
index e7ca9e2..7b04c24 100644
--- a/tests/default_init.rs
+++ b/tests/default_init.rs
@@ -7,4 +7,4 @@
// android_logger has default log level "off"
assert_eq!(log::max_level(), log::LevelFilter::Off);
-}
\ No newline at end of file
+}
diff --git a/tests/multiple_init.rs b/tests/multiple_init.rs
index 99b58c8..26f815d 100644
--- a/tests/multiple_init.rs
+++ b/tests/multiple_init.rs
@@ -3,10 +3,14 @@
#[test]
fn multiple_init() {
- android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Trace));
+ android_logger::init_once(
+ android_logger::Config::default().with_max_level(log::LevelFilter::Trace),
+ );
// Second initialization should be silently ignored
- android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Error));
+ android_logger::init_once(
+ android_logger::Config::default().with_max_level(log::LevelFilter::Error),
+ );
assert_eq!(log::max_level(), log::LevelFilter::Trace);
-}
\ No newline at end of file
+}