package Ġdrive chain . logger Ċ Ċ import Ġandroid . util . Log Ċ import Ġdrive chain . logger . LogLevel .* Ċ import Ġjava . util . regex . Pattern Ċ Ċ private Ġconst Ġval ĠMAX _ TAG _ LENGTH Ġ= Ġ 2 3 Ċ private Ġconst Ġval ĠCALL _ STACK _ INDEX Ġ= Ġ 2 Ċ private Ġval ĠAN ONY MO US _ CLASS Ġ= ĠPattern . compile ("( \\ $ \\ d + )+ $ ") Ċ Ċ /** Ċ Ġ* ĠLog Ġmessages Ġto Ġthe ĠAndroid ĠConsole . Ċ Ġ* Ċ Ġ* Ġ@ param Ġname ĠA Ġname Ġto Ġlog Ġas Ġa Ġtag Ġwhen Ġlogging . ĠIf Ġnone Ġis Ġprovided , Ċ Ġ* ĠĠĠĠĠĠĠ Ġthis Ġwill Ġattempt Ġto Ġuse Ġthe Ġclass Ġname Ġof Ġthe Ġsource Ġof Ġthe Ċ Ġ* ĠĠĠĠĠĠĠ Ġlog . Ġ( optional ) Ċ Ġ* Ġ@ param Ġlog Level ĠThe Ġminimum Ġseverity Ġof Ġthe Ġlog Ġmessage Ġto Ġwrite Ġto Ġthe Ċ Ġ* ĠĠĠĠĠĠĠ Ġconsole . ĠThis Ġis Ġuseful Ġfor Ġdisabling Ġverbose Ġlogging Ġin Ġreleases . Ċ Ġ* Ġ@ param Ġlogger Offset ĠThe Ġnumber Ġof Ġclasses Ġto Ġtraverse Ġup wards Ġwhen Ġgetting Ċ Ġ* ĠĠĠĠĠĠĠ Ġthe Ġname Ġof Ġthe Ġclass Ġthat Ġlogged Ġthe Ġmessage . ĠThis Ġis Ġused Ġwhen Ċ Ġ* ĠĠĠĠĠĠĠ Ġnesting Ġlog gers Ġtogether , Ġso Ġthat Ġthe Ġsource Ġof Ġthe Ġlog Ġcan Ġbe Ċ Ġ* ĠĠĠĠĠĠĠ Ġcorrectly Ġidentified . ĠBy Ġdefault Ġit Ġis Ġset Ġto Ġ 1 , Ġand Ġshould Ġbe Ċ Ġ* ĠĠĠĠĠĠĠ Ġchanged Ġto Ġ 2 Ġif Ġusing Ġthis Ġin Ġa Ġ` Composite Logger ` Ġ( optional ) Ċ Ġ*/ Ċ class ĠConsole Logger ( ĊĠĠĠ Ġprivate Ġval Ġname : ĠString ? Ġ= Ġnull , ĊĠĠĠ Ġprivate Ġval Ġlog Level : ĠLogLevel Ġ= ĠLogLevel . TRACE , ĊĠĠĠ Ġprivate Ġval Ġlogger Offset : ĠInt Ġ= Ġ 1 Ċ ): ĠLogger Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġlog ( level : ĠLogLevel , Ġmessage : ĠString , Ġvar arg Ġargs : ĠAny ?, Ġtag : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( level . severity Ġ< Ġlog Level . severity ) Ġreturn ĊĠĠĠĠĠĠĠ Ġwhen Ġ( level ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTRACE Ġ-> ĠLog . v ( tag Ġ?: Ġclass Tag , Ġmessage . format (* args )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDEBUG Ġ-> ĠLog . d ( tag Ġ?: Ġclass Tag , Ġmessage . format (* args )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠINFO Ġ-> ĠLog . i ( tag Ġ?: Ġclass Tag , Ġmessage . format (* args )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠWARN Ġ-> ĠLog . w ( tag Ġ?: Ġclass Tag , Ġmessage . format (* args )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠERROR Ġ-> ĠLog . e ( tag Ġ?: Ġclass Tag , Ġmessage . format (* args )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġlog ( level : ĠLogLevel , Ġcause : ĠThrowable , Ġmessage : ĠString , Ġvar arg Ġargs : ĠAny ?, Ġtag : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( level . severity Ġ< Ġlog Level . severity ) Ġreturn ĊĊĠĠĠĠĠĠĠ Ġwhen Ġ( level ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTRACE Ġ-> ĠLog . v ( tag Ġ?: Ġclass Tag , Ġmessage . format (* args ), Ġcause ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDEBUG Ġ-> ĠLog . d ( tag Ġ?: Ġclass Tag , Ġmessage . format (* args ), Ġcause ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠINFO Ġ-> ĠLog . i ( tag Ġ?: Ġclass Tag , Ġmessage . format (* args ), Ġcause ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠWARN Ġ-> ĠLog . w ( tag Ġ?: Ġclass Tag , Ġmessage . format (* args ), Ġcause ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠERROR Ġ-> ĠLog . e ( tag Ġ?: Ġclass Tag , Ġmessage . format (* args ), Ġcause ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠ ĠThe ĠFollowing Ġcode Ġis Ġfrom ĠJ ake ĠWh art on 's ĠTim ber Ġlibrary , ĊĠĠĠĠĠĠĠ Ġsources Ġreceived Ġfrom : Ġhttps :// github . com / J ake Wh art on / tim ber ĊĠĠĠĠĠĠĠ ĠCopyright ĠJ ake ĠWh art on Ġand Ġlicensed Ġunder : ĊĠĠĠĠĠĠĠ ĠApache ĠLicense ĊĠĠĠĠĠĠĠ ĠVersion Ġ 2 . 0 , ĠJanuary Ġ 2 0 0 4 ĊĠĠĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / ĊĠĠĠĠĠĠĠ ĠMod ifications Ġinclude : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ- ĠChange Ġget Tag Ġfirst Ġreturn Ġcondition Ġto Ġreturn Ġtag Ġname Ġof Ġlocal Ġclass Ġcontext ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ- ĠConvert ed Ġto ĠKotlin ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ- ĠChange Ġelement Ġindex Ġto Ġskip Ġdefault Ġinterface Ġimplementations ĊĠĠĠ Ġ*/ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExtract Ġthe Ġtag Ġwhich Ġshould Ġbe Ġused Ġfor Ġthe Ġmessage Ġfrom Ġthe Ġ` element `. ĠBy Ġdefault ĊĠĠĠĠ Ġ* Ġthis Ġwill Ġuse Ġthe Ġclass Ġname Ġwithout Ġany Ġanonymous Ġclass Ġsuffix es Ġ( e . g ., Ġ` Foo $ 1 ` ĊĠĠĠĠ Ġ* Ġbecomes Ġ` Foo `). ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠNote : ĠThis Ġwill Ġnot Ġbe Ġcalled Ġif Ġa Ġ[ manual Ġtag ][. tag ] Ġwas Ġspecified . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcreate Stack Element Tag ( element : ĠStack Trace Element ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġtag Ġ= Ġelement . className ĊĠĠĠĠĠĠĠ Ġval Ġm Ġ= ĠAN ONY MO US _ CLASS . matcher ( tag ) ĊĠĠĠĠĠĠĠ Ġif Ġ( m . find ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtag Ġ= Ġm . replaceAll ("") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtag Ġ= Ġtag . substring ( tag . lastIndexOf ('.') Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( tag . length Ġ> ĠMAX _ TAG _ LENGTH ) Ġtag . substring ( 0 , ĠMAX _ TAG _ LENGTH ) Ġelse Ġtag ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠDO ĠNOT Ġswitch Ġthis Ġto ĠThread . getCurrent Thread (). get StackTrace (). ĠThe Ġtest Ġwill Ġpass ĊĠĠĠ Ġ// Ġbecause ĠRo bo lectric Ġruns Ġthem Ġon Ġthe ĠJVM Ġbut Ġon ĠAndroid Ġthe Ġelements Ġare Ġdifferent . ĊĠĠĠ Ġprivate Ġval Ġclass Tag : ĠString Ġget () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( null Ġ!= Ġthis . name ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis . name ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġstack Trace Ġ= ĠThrowable (). stack Trace ĊĠĠĠĠĠĠĠ Ġif Ġ( stack Trace . size Ġ<= ĠCALL _ STACK _ INDEX ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Synt hetic Ġstack trace Ġdidn 't Ġhave Ġenough Ġelements : Ġare Ġyou Ġusing Ġpro guard ?") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġelement Ġ= Ġif Ġ( stack Trace [ CALL _ STACK _ INDEX Ġ+ Ġlogger Offset ]. className . contains ( Regex ("\\ \$ Default Imp ls \$ "))) Ġstack Trace [ CALL _ STACK _ INDEX Ġ+ Ġlogger Offset Ġ+ Ġ 3 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ Ġstack Trace [ CALL _ STACK _ INDEX Ġ+ Ġlogger Offset ] ĊĊĠĠĠĠĠĠĠ Ġreturn Ġcreate Stack Element Tag ( element ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/* ĠEnd Ġof ĠTim ber ĠCode Ġ*/ Ċ } Ċ