1+ // NOTE: logging methods below are need temporarily due to:
2+ // 1) linux-bionic BCL doesn't redirect stdout/stderr to logcat
3+ // 2) Android.Util.Log won't work until we initialize the Java.Interop.JreRuntime
4+
5+ using System . IO ;
6+ using System . Runtime . InteropServices ;
7+ using System . Text ;
8+
9+ namespace NativeAOT ;
10+
11+ internal sealed class LogcatTextWriter : TextWriter {
12+
13+ public static void Init ( )
14+ {
15+ // This method is a no-op, but it's necessary to ensure the static
16+ // constructor is executed.
17+ }
18+
19+ static LogcatTextWriter ( )
20+ {
21+ Console . SetOut ( new LogcatTextWriter ( AndroidLogLevel . Info ) ) ;
22+ Console . SetError ( new LogcatTextWriter ( AndroidLogLevel . Error ) ) ;
23+ }
24+
25+ AndroidLogLevel Level ;
26+ string Tag ;
27+
28+ internal LogcatTextWriter ( AndroidLogLevel level , string tag = "NativeAotFromAndroid" )
29+ {
30+ Level = level ;
31+ Tag = tag ;
32+ }
33+
34+ public override Encoding Encoding => Encoding . UTF8 ;
35+ public override string NewLine => "\n " ;
36+
37+ public override void WriteLine ( string ? value )
38+ {
39+ if ( value == null ) {
40+ AndroidLog . Print ( Level , Tag , "" ) ;
41+ return ;
42+ }
43+ ReadOnlySpan < char > span = value ;
44+ while ( ! span . IsEmpty ) {
45+ if ( span . IndexOf ( '\n ' ) is int n && n < 0 ) {
46+ break ;
47+ }
48+ var line = span . Slice ( 0 , n ) ;
49+ AndroidLog . Print ( Level , Tag , line . ToString ( ) ) ;
50+ span = span . Slice ( n + 1 ) ;
51+ }
52+ AndroidLog . Print ( Level , Tag , span . ToString ( ) ) ;
53+ }
54+ }
55+
56+ static class AndroidLog {
57+
58+ [ DllImport ( "log" , EntryPoint = "__android_log_print" , CallingConvention = CallingConvention . Cdecl ) ]
59+ private static extern void __android_log_print ( AndroidLogLevel level , string ? tag , string format , string args , IntPtr ptr ) ;
60+
61+ internal static void Print ( AndroidLogLevel level , string ? tag , string message ) =>
62+ __android_log_print ( level , tag , "%s" , message , IntPtr . Zero ) ;
63+
64+ }
65+
66+ internal enum AndroidLogLevel
67+ {
68+ Unknown = 0x00 ,
69+ Default = 0x01 ,
70+ Verbose = 0x02 ,
71+ Debug = 0x03 ,
72+ Info = 0x04 ,
73+ Warn = 0x05 ,
74+ Error = 0x06 ,
75+ Fatal = 0x07 ,
76+ Silent = 0x08
77+ }
0 commit comments