package Ġorg . m transit . android . provider . sensor Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . hardware . Geom ag netic Field Ċ import Ġandroid . hardware . Sensor Ċ import Ġandroid . hardware . Sensor Event Ċ import Ġandroid . hardware . Sensor EventListener Ċ import Ġandroid . hardware . Sensor Manager Ċ import Ġandroid . location . Location Ċ import Ġandroid . view . Surface Ċ import Ġandroid . widget . Abs ListView Ċ import Ġdagger . h ilt . android . qual ifiers . ApplicationContext Ċ import Ġorg . m transit . android . commons . MT Log Ċ import Ġorg . m transit . android . commons . api . Support Factory Ċ import Ġorg . m transit . android . ui . view . common . I Activity Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġjavax . inject . Inject Ċ import Ġkotlin . math . abs ĊĊ Ċ class ĠSensor ManagerImpl Ġ@ Inject Ġconstructor ( ĊĠĠĠ Ġ@ ApplicationContext Ġprivate Ġval Ġapp Context : ĠContext , Ċ ) Ġ: ĠM TS ensor Manager , ĠMT Log . Log gable Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠLOG _ TAG : ĠString Ġ= ĠSensor ManagerImpl :: class . java . simple Name ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠCOMP ASS _ DEG REE _ UPDATE _ THRESHOLD Ġ= Ġ 1 0 Ġ// Ġ 1 0 Â° ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠCOMP ASS _ UPDATE _ THRESHOLD _ IN _ MS Ġ= ĠTimeUnit . MILLISECONDS . to Millis ( 2 5 0 L ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġsensor Manager Ġ= ĊĠĠĠĠĠĠĠ Ġapp Context . getSystem Service ( Context . SENSOR _ SERVICE ) Ġas ĠSensor Manager ? ĊĊĠĠĠ Ġoverride Ġfun Ġget Log Tag () Ġ= ĠLOG _ TAG ĊĊĠĠĠ Ġoverride Ġfun Ġregister Comp ass Listener ( sensor EventListener : ĠSensor EventListener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsensor Manager ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . register Listener ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsensor EventListener , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Accel erometer Sensor ( sensor Manager ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSensor Manager . SENSOR _ DELAY _ UI ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . register Listener ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsensor EventListener , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Mag netic Field Sensor ( sensor Manager ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSensor Manager . SENSOR _ DELAY _ UI ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Accel erometer Sensor ( sensor Manager : ĠSensor Manager ): ĠSensor ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsensor Manager . getDefault Sensor ( Sensor . TYPE _ AC CEL ERO METER ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Mag netic Field Sensor ( m Sensor Manager : ĠSensor Manager ): ĠSensor ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġm Sensor Manager . getDefault Sensor ( Sensor . TYPE _ MAG NET IC _ FIELD ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġunregister Sensor Listener ( sensor EventListener : ĠSensor EventListener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsensor Manager ?. unregister Listener ( sensor EventListener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġcheck For Comp ass ( ĊĠĠĠĠĠĠĠ Ġactivity : ĠI Activity , ĊĠĠĠĠĠĠĠ Ġevent : ĠSensor Event , ĊĠĠĠĠĠĠĠ Ġaccel erometer Values : ĠFloat Array , ĊĠĠĠĠĠĠĠ Ġmagnetic Field Values : ĠFloat Array , ĊĠĠĠĠĠĠĠ Ġlistener : ĠM TS ensor Manager . Comp ass Listener ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( event . sensor . type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSensor . TYPE _ AC CEL ERO METER Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . arraycopy ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent . values , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccel erometer Values , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent . values . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( mag netic Field Values . size Ġ== Ġ 3 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġmagnetic Field Values [ 0 ] Ġ!= Ġ 0 . 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġmagnetic Field Values [ 1 ] Ġ!= Ġ 0 . 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġmagnetic Field Values [ 2 ] Ġ!= Ġ 0 . 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcalculate Orientation ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactivity , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccel erometer Values , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmagnetic Field Values ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . update Comp ass ( it , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSensor . TYPE _ MAG NET IC _ FIELD Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . arraycopy ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent . values , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmagnetic Field Values , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent . values . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( accel erometer Values . size Ġ== Ġ 3 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġaccel erometer Values [ 0 ] Ġ!= Ġ 0 . 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġaccel erometer Values [ 1 ] Ġ!= Ġ 0 . 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġaccel erometer Values [ 2 ] Ġ!= Ġ 0 . 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcalculate Orientation ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactivity , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccel erometer Values , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmagnetic Field Values ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . update Comp ass ( it , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDO ĠNOT ING ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcalculate Orientation ( ĊĠĠĠĠĠĠĠ Ġactivity : ĠI Activity , ĊĠĠĠĠĠĠĠ Ġaccel erometer Values : ĠFloat Array ?, ĊĠĠĠĠĠĠĠ Ġmagnetic Field Values : ĠFloat Array ? ĊĠĠĠ Ġ): ĠFloat ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( accel erometer Values Ġ== Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġaccel erometer Values . size Ġ!= Ġ 3 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġmagnetic Field Values Ġ== Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġmagnetic Field Values . size Ġ!= Ġ 3 ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġr Array Ġ= ĠFloat Array ( 9 ) ĊĠĠĠĠĠĠĠ Ġval Ġsuccess Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSensor Manager . get Rotation Matrix ( r Array , Ġnull , Ġaccel erometer Values , Ġmagnetic Field Values ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġaxis Ġ= ĠInt Array ( 2 ) ĊĠĠĠĠĠĠĠ Ġaxis [ 0 ] Ġ= ĠSensor Manager . AXIS _ X ĊĠĠĠĠĠĠĠ Ġaxis [ 1 ] Ġ= ĠSensor Manager . AXIS _ Y ĊĠĠĠĠĠĠĠ Ġval Ġa Activity Ġ= Ġactivity . activity Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġdefault Display Ġ= ĠSupport Factory . get (). getDefault Display ( a Activity ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( default Display ?. rotation ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSurface . ROT ATION _ 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDO ĠNOT H ING ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSurface . ROT ATION _ 9 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaxis [ 0 ] Ġ= ĠSensor Manager . AXIS _ Y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaxis [ 1 ] Ġ= ĠSensor Manager . AXIS _ MINUS _ X ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSurface . ROT ATION _ 1 8 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaxis [ 1 ] Ġ= ĠSensor Manager . AXIS _ MINUS _ Y ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSurface . ROT ATION _ 2 7 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaxis [ 0 ] Ġ= ĠSensor Manager . AXIS _ MINUS _ Y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaxis [ 1 ] Ġ= ĠSensor Manager . AXIS _ X ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDO ĠNOT H ING ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġout R Ġ= ĠFloat Array ( 9 ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! Sensor Manager . remap Coordinate System ( r Array , Ġaxis [ 0 ], Ġaxis [ 1 ], Ġout R )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= ĠFloat Array ( 3 ) ĊĠĠĠĠĠĠĠ ĠSensor Manager . get Orientation ( out R , Ġvalues ) ĊĠĠĠĠĠĠĠ Ġvalues [ 0 ] Ġ= ĠMath . to Degrees ( values [ 0 ]. toDouble ()). toFloat () ĊĠĠĠĠĠĠĠ Ġvalues [ 1 ] Ġ= ĠMath . to Degrees ( values [ 1 ]. toDouble ()). toFloat () ĊĠĠĠĠĠĠĠ Ġvalues [ 2 ] Ġ= ĠMath . to Degrees ( values [ 2 ]. toDouble ()). toFloat () ĊĠĠĠĠĠĠĠ Ġreturn Ġvalues [ 0 ] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Location Decl ination ( location : ĠLocation ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠGe om ag netic Field ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocation . latitude . toFloat (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocation . longitude . toFloat (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocation . altitude . toFloat (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocation . time ĊĠĠĠĠĠĠĠ Ġ). decl ination ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġupdate Comp ass ( ĊĠĠĠĠĠĠĠ Ġforce : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġdevice Location : ĠLocation ?, ĊĠĠĠĠĠĠĠ Ġrounded Orientation : ĠInt , ĊĠĠĠĠĠĠĠ Ġnow : ĠLong , ĊĠĠĠĠĠĠĠ Ġscroll State : ĠInt , ĊĠĠĠĠĠĠĠ Ġlast Comp ass Changed : ĠLong , ĊĠĠĠĠĠĠĠ Ġlast Comp ass In Degree : ĠInt ?, ĊĠĠĠĠĠĠĠ Ġmin Threshold In Ms : ĠLong , ĊĠĠĠĠĠĠĠ Ġsensor Task Completed : ĠM TS ensor Manager . Sensor Task Completed ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( device Location Ġ== Ġnull Ġ|| Ġrounded Orientation Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsensor Task Completed . on Sensor Task Completed ( false , Ġrounded Orientation , Ġnow ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(! force ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scroll State Ġ!= ĠAbs ListView . On Scroll Listener . SCROLL _ STATE _ IDLE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsensor Task Completed . on Sensor Task Completed ( false , Ġrounded Orientation , Ġnow ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdiff In Ms Ġ= Ġnow Ġ- Ġlast Comp ass Changed ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoo So on Ġ= Ġdiff In Ms Ġ<= Ġmin Threshold In Ms . coerce At Least ( COMP ASS _ UPDATE _ THRESHOLD _ IN _ MS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( too So on ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsensor Task Completed . on Sensor Task Completed ( false , Ġrounded Orientation , Ġnow ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdiff In Degree : ĠFloat Ġ= Ġabs ( last Comp ass In Degree Ġ?: Ġ 0 Ġ- Ġrounded Orientation ). toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnot Different En ough Ġ= Ġdiff In Degree Ġ<= ĠCOMP ASS _ DEG REE _ UPDATE _ THRESHOLD ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( not Different En ough ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsensor Task Completed . on Sensor Task Completed ( false , Ġrounded Orientation , Ġnow ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsensor Task Completed . on Sensor Task Completed ( true , Ġrounded Orientation , Ġnow ) ĊĠĠĠ Ġ} Ċ }