@@ -159,6 +159,56 @@ fn android_log(
159
159
#[ cfg( not( target_os = "android" ) ) ]
160
160
fn android_log ( _buf_id : Option < LogId > , _priority : Level , _tag : & CStr , _msg : & CStr ) { }
161
161
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
+
162
212
/// Underlying android logger backend
163
213
pub struct AndroidLogger {
164
214
config : OnceLock < Config > ,
@@ -193,9 +243,7 @@ impl Default for AndroidLogger {
193
243
194
244
impl Log for AndroidLogger {
195
245
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 ( ) )
199
247
}
200
248
201
249
fn log ( & self , record : & Record ) {
@@ -375,17 +423,7 @@ impl<'a> PlatformLogWriter<'a> {
375
423
376
424
#[ cfg( target_os = "android" ) ]
377
425
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)
389
427
}
390
428
391
429
#[ cfg( not( target_os = "android" ) ) ]
@@ -535,6 +573,9 @@ pub fn init_once(config: Config) {
535
573
log:: debug!( "android_logger: log::set_logger failed: {}" , err) ;
536
574
} else if let Some ( level) = log_level {
537
575
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 ) ;
538
579
}
539
580
}
540
581
0 commit comments