@@ -159,6 +159,56 @@ fn android_log(
159159#[ cfg( not( target_os = "android" ) ) ]
160160fn android_log ( _buf_id : Option < LogId > , _priority : Level , _tag : & CStr , _msg : & CStr ) { }
161161
162+ /// Outputs log to Android system.
163+ #[ cfg( target_os = "android" ) ]
164+ fn android_is_loggable_len (
165+ prio : log_ffi:: LogPriority ,
166+ tag : & str ,
167+ default_prio : log_ffi:: LogPriority ,
168+ ) -> bool {
169+ // SAFETY: tag points to a valid string tag.len() bytes long.
170+ unsafe {
171+ log_ffi:: __android_log_is_loggable_len (
172+ prio as log_ffi:: c_int ,
173+ tag. as_ptr ( ) as * const log_ffi:: c_char ,
174+ tag. len ( ) as log_ffi:: c_size_t ,
175+ default_prio as log_ffi:: c_int ,
176+ ) != 0
177+ }
178+ }
179+
180+ #[ cfg( target_os = "android" ) ]
181+ fn android_log_priority_from_level ( level : Level ) -> LogPriority {
182+ match level {
183+ Level :: Warn => LogPriority :: WARN ,
184+ Level :: Info => LogPriority :: INFO ,
185+ Level :: Debug => LogPriority :: DEBUG ,
186+ Level :: Error => LogPriority :: ERROR ,
187+ Level :: Trace => LogPriority :: VERBOSE ,
188+ }
189+ }
190+
191+ #[ cfg( target_os = "android" ) ]
192+ fn should_log ( tag : & str , level : Level , logger_config : & Config ) -> bool {
193+ let prio = android_log_priority_from_level ( level) ;
194+ // Priority to use in case no system-wide or process-wide overrides are set.
195+ let default_prio = match logger_config. log_level {
196+ Some ( level_filter) => match level_filter. to_level ( ) {
197+ Some ( level) => android_log_priority_from_level ( level) ,
198+ // LevelFilter::to_level() returns None only for LevelFilter::Off
199+ None => log_ffi:: LogPriority :: SILENT ,
200+ } ,
201+ None => log_ffi:: LogPriority :: INFO ,
202+ } ;
203+ android_is_loggable_len ( prio, tag, default_prio)
204+ }
205+
206+ /// Dummy placeholder for tests.
207+ #[ cfg( not( target_os = "android" ) ) ]
208+ fn should_log ( _tag : & str , level : Level , logger_config : & Config ) -> bool {
209+ level <= logger_config. log_level . unwrap_or ( LevelFilter :: Trace )
210+ }
211+
162212/// Underlying android logger backend
163213pub struct AndroidLogger {
164214 config : OnceLock < Config > ,
@@ -193,9 +243,7 @@ impl Default for AndroidLogger {
193243
194244impl Log for AndroidLogger {
195245 fn enabled ( & self , metadata : & Metadata ) -> bool {
196- let config = self . config ( ) ;
197- // todo: consider __android_log_is_loggable.
198- metadata. level ( ) <= config. log_level . unwrap_or_else ( log:: max_level)
246+ should_log ( metadata. target ( ) , metadata. level ( ) , self . config ( ) )
199247 }
200248
201249 fn log ( & self , record : & Record ) {
@@ -375,17 +423,7 @@ impl<'a> PlatformLogWriter<'a> {
375423
376424 #[ cfg( target_os = "android" ) ]
377425 pub fn new ( buf_id : Option < LogId > , level : Level , tag : & CStr ) -> PlatformLogWriter < ' _ > {
378- PlatformLogWriter :: new_with_priority (
379- buf_id,
380- match level {
381- Level :: Warn => LogPriority :: WARN ,
382- Level :: Info => LogPriority :: INFO ,
383- Level :: Debug => LogPriority :: DEBUG ,
384- Level :: Error => LogPriority :: ERROR ,
385- Level :: Trace => LogPriority :: VERBOSE ,
386- } ,
387- tag,
388- )
426+ PlatformLogWriter :: new_with_priority ( buf_id, android_log_priority_from_level ( level) , tag)
389427 }
390428
391429 #[ cfg( not( target_os = "android" ) ) ]
@@ -535,6 +573,9 @@ pub fn init_once(config: Config) {
535573 log:: debug!( "android_logger: log::set_logger failed: {}" , err) ;
536574 } else if let Some ( level) = log_level {
537575 log:: set_max_level ( level) ;
576+ } else {
577+ // Do not filter logs at log crate level. Delegate all filtering to underlying liblog.
578+ log:: set_max_level ( LevelFilter :: Trace ) ;
538579 }
539580}
540581
0 commit comments