package Ġme . h uf man . android aut oid rive . car app . music Ċ Ċ import Ġandroid . util . Log Ċ import Ġde . bm w . id rive . BM WR em oting Ċ import Ġde . bm w . id rive . BM WR em oting Server Ċ import Ġde . bm w . id rive . Base BM WR em oting Client Ċ import Ġme . h uf man . android aut oid rive . Graphics Helpers Ċ import Ġme . h uf man . android aut oid rive . Phone App Resources Ċ import Ġme . h uf man . android aut oid rive . Utils . load Zip file Ċ import Ġme . h uf man . android aut oid rive . car app .* Ċ import Ġme . h uf man . android aut oid rive . car app . music . views .* Ċ import Ġme . h uf man . android aut oid rive . music . Music App Discovery Ċ import Ġme . h uf man . android aut oid rive . music . Music App Info Ċ import Ġme . h uf man . android aut oid rive . music . Music Controller Ċ import Ġme . h uf man . android aut oid rive . remove First Ċ import Ġme . h uf man . id rive connection kit . ID rive Connection Ċ import Ġme . h uf man . id rive connection kit . rh mi . RH MI Application Ide mpot ent Ċ import Ġme . h uf man . id rive connection kit . rh mi . RH MI Application Synchron ized Ċ import Ġme . h uf man . id rive connection kit . android . Car App Resources Ċ import Ġme . h uf man . id rive connection kit . android . ID rive Connection Listener Ċ import Ġme . h uf man . id rive connection kit . android . security . Security Access Ċ import Ġme . h uf man . id rive connection kit . rh mi .* Ċ import Ġjava . util .* Ċ Ċ const Ġval ĠTAG Ġ= Ġ" Music App " Ċ Ċ class ĠMusic App ( val Ġsecurity Access : ĠSecurity Access , Ġval Ġcar App Assets : ĠCar App Resources , Ġval Ġmusic Image IDs : ĠMusic Image IDs , Ġval Ġphone App Resources : ĠPhone App Resources , Ġval Ġgraphics Helpers : ĠGraphics Helpers , Ġval Ġmusic App Discovery : ĠMusic App Discovery , Ġval Ġmusic Controller : ĠMusic Controller , Ġval Ġmusic App Mode : ĠMusic App Mode ) Ġ{ Ċ ĉ val Ġcar App Ġ= Ġcreate RH MI App () ĊĊ ĉ val Ġav Context Ġ= ĠAV Context Handler (( car App . unwrap () Ġas ĠR H MI Application Et ch ). remote Server , Ġmusic Controller , Ġgraphics Helpers , Ġmusic App Mode ) Ċ ĉ val Ġam App List : ĠAM App List < Music App Info > ĊĊ ĉ val Ġglobal Metadata Ġ= ĠGlobal Metadata ( car App , Ġmusic Controller ) Ċ ĉ var Ġh mi Context Changed Time Ġ= Ġ 0 L Ċ ĉ var Ġapp ListView Visible Ġ= Ġfalse Ċ ĉ var Ġplayback View Visible Ġ= Ġfalse Ċ ĉ var Ġen queued View Visible Ġ= Ġfalse Ċ ĉ var Ġbrowse View Visible Ġ= Ġfalse Ċ ĉ val Ġplayback View : ĠPlay back View Ċ ĉ val Ġapp Switch er View : ĠApp Switch er View Ċ ĉ val Ġen queued View : ĠEn queued View Ċ ĉ val Ġbrowse View : ĠB rowse View Ċ ĉ val Ġinput State : ĠR H MI State Ċ ĉ val Ġcustom Actions View : ĠCustom Actions View ĊĊ ĉ private Ġfun Ġcreate RH MI App (): ĠR H MI Application Synchron ized Ġ{ Ċĉ ĉ val Ġcar app Listener Ġ= ĠCar App Listener () Ċĉ ĉ val Ġcar Connection Ġ= ĠID rive Connection . get Et ch Connection ( ID rive Connection Listener . host Ġ?: Ġ" 1 2 7 . 0 . 0 . 1 ", ĠID rive Connection Listener . port Ġ?: Ġ 8 0 0 3 , Ġcar app Listener ) Ċĉ ĉ val Ġapp Cert Ġ= Ġcar App Assets . getApp Certificate ( ID rive Connection Listener . brand Ġ?: Ġ"") ?. read Bytes () Ġas ĠByteArray Ċĉ ĉ val Ġs as _ challenge Ġ= Ġcar Connection . sas _ certificate ( app Cert ) Ċĉ ĉ val Ġs as _ login Ġ= Ġsecurity Access . sign Challenge ( challenge = sas _ challenge ) Ċĉ ĉ car Connection . sas _ login ( sas _ login ) Ċĉ ĉ car app Listener . server Ġ= Ġcar Connection ĊĊĉ ĉ // Ġcreate Ġthe Ġapp Ġin Ġthe Ġcar Ċĉ ĉ val Ġrh mi Handle Ġ= Ġcar Connection . rh mi _ create ( null , ĠBM WR em oting . R HM IM eta Data (" me . h uf man . android aut oid rive . music ", ĠBM WR em oting . VersionInfo ( 0 , Ġ 1 , Ġ 0 ), Ġ" me . h uf man . android aut oid rive . music ", Ġ" me . h uf man ")) Ċĉ ĉ RH MI Utils . rh mi _ set Resource Cached ( car Connection , Ġrh mi Handle , ĠBM WR em oting . RH MI ResourceType . DESCRIPTION , Ġcar App Assets . get Ui Description ()) Ċĉ ĉ RH MI Utils . rh mi _ set Resource Cached ( car Connection , Ġrh mi Handle , ĠBM WR em oting . RH MI ResourceType . TEXT DB , Ġcar App Assets . getText s DB ( ID rive Connection Listener . brand Ġ?: Ġ" common ")) Ċĉ ĉ RH MI Utils . rh mi _ set Resource Cached ( car Connection , Ġrh mi Handle , ĠBM WR em oting . RH MI ResourceType . I MAG ED B , Ġcar App Assets . get Images DB ( ID rive Connection Listener . brand Ġ?: Ġ" common ")) Ċĉ ĉ car Connection . rh mi _ initialize ( rh mi Handle ) ĊĊĉ ĉ // Ġset Ġup Ġthe Ġapp Ġin Ġthe Ġcar Ċĉ ĉ val Ġcar App Ġ= ĠR H MI Application Synchron ized ( RH MI Application Ide mpot ent ( RH MI Application Et ch ( car Connection , Ġrh mi Handle )), Ġcar Connection ) Ċĉ ĉ car app Listener . app Ġ= Ġcar App Ċĉ ĉ car App . load From XML ( car App Assets . get Ui Description ()?. read Bytes () Ġas ĠByteArray ) ĊĊĉ ĉ // Ġregister Ġfor Ġevents Ġfrom Ġthe Ġcar Ċĉ ĉ synchronized ( car Connection ) Ġ{ Ċĉĉ ĉ car Connection . rh mi _ addAction EventHandler ( rh mi Handle , Ġ" me . h uf man . android aut oid rive . music ", Ġ- 1 ) Ċĉĉ ĉ car Connection . rh mi _ add H mi EventHandler ( rh mi Handle , Ġ" me . h uf man . android aut oid rive . music ", Ġ- 1 , Ġ- 1 ) ĊĊĉĉ ĉ // Ġlisten Ġfor ĠH MI ĠContext Ġevents Ċĉĉ ĉ val Ġcds Handle Ġ= Ġcar Connection . cds _ create () Ċĉĉ ĉ car Connection . cds _ add PropertyChanged EventHandler ( cds Handle , Ġ" h mi . graphical Context ", Ġ" 1 1 4 ", Ġ 5 0 ) Ċĉ ĉ } ĊĊĉ ĉ return Ġcar App Ċ ĉ } ĊĊ ĉ init Ġ{ Ċĉ ĉ // Ġlocate Ġspecific Ġwindows Ġin Ġthe Ġapp Ċĉ ĉ val Ġcar App Images Ġ= Ġload Zip file ( car App Assets . get Images DB ( ID rive Connection Listener . brand Ġ?: Ġ" common ")) Ċĉ ĉ val Ġun claimed States Ġ= ĠLinkedList ( car App . states . values ) Ċĉ ĉ val Ġplayback States Ġ= ĠLinkedList < RH MI State >(). apply Ġ{ Ċĉĉ ĉ addAll ( car App . states . values . filter Is Instance < RH MI State . Audio H mi State >()) Ċĉĉ ĉ addAll ( car App . states . values . filter Is Instance < RH MI State . Toolbar State >()) Ċĉ ĉ } Ċĉ ĉ playback View Ġ= ĠPlay back View ( playback States . remove First Ġ{ ĠPlay back View . fits ( it ) Ġ}, Ġmusic Controller , Ġcar App Images , Ġphone App Resources , Ġgraphics Helpers , Ġmusic Image IDs ) Ċĉ ĉ app Switch er View Ġ= ĠApp Switch er View ( un claimed States . remove First Ġ{ ĠApp Switch er View . fits ( it ) Ġ}, Ġmusic App Discovery , Ġav Context , Ġgraphics Helpers , Ġmusic Image IDs ) Ċĉ ĉ en queued View Ġ= ĠEn queued View ( un claimed States . remove First Ġ{ ĠEn queued View . fits ( it ) Ġ}, Ġmusic Controller , Ġgraphics Helpers , Ġmusic Image IDs ) Ċĉ ĉ browse View Ġ= ĠB rowse View ( listOf ( un claimed States . remove First Ġ{ ĠB rowse View . fits ( it ) Ġ}, Ġun claimed States . remove First Ġ{ ĠB rowse View . fits ( it ) Ġ}, Ġun claimed States . remove First Ġ{ ĠB rowse View . fits ( it ) Ġ}), Ġmusic Controller , Ġmusic Image IDs , Ġgraphics Helpers , Ġthis ) Ċĉ ĉ input State Ġ= Ġun claimed States . remove First Ġ{ Ġit . components List . filter Is Instance < RH MI Component . Input >(). first OrNull ()?. suggest Model Ġ?: Ġ 0 Ġ> Ġ 0 Ġ} Ċĉ ĉ custom Actions View Ġ= ĠCustom Actions View ( un claimed States . remove First Ġ{ ĠCustom Actions View . fits ( it ) Ġ}, Ġgraphics Helpers , Ġmusic Controller ) ĊĊĉ ĉ Log . i ( TAG , Ġ" Selected Ġstate Ġ${ app Switch er View . state . id } Ġfor ĠApp ĠSwitch er ") Ċĉ ĉ Log . i ( TAG , Ġ" Selected Ġstate Ġ${ playback View . state . id } Ġfor ĠPlay back ") Ċĉ ĉ Log . i ( TAG , Ġ" Selected Ġstate Ġ${ en queued View . state . id } Ġfor ĠEn queued ") Ċĉ ĉ Log . i ( TAG , Ġ" Selected Ġstate Ġ${ browse View . states [ 0 ]. id } Ġfor ĠB rowse ĠPage Ġ 1 ") Ċĉ ĉ Log . i ( TAG , Ġ" Selected Ġstate Ġ${ browse View . states [ 1 ]. id } Ġfor ĠB rowse ĠPage Ġ 2 ") Ċĉ ĉ Log . i ( TAG , Ġ" Selected Ġstate Ġ${ browse View . states [ 2 ]. id } Ġfor ĠB rowse ĠPage Ġ 3 ") Ċĉ ĉ Log . i ( TAG , Ġ" Selected Ġstate Ġ${ input State . id } Ġfor ĠInput ") Ċĉ ĉ Log . i ( TAG , Ġ" Selected Ġstate Ġ${ custom Actions View . state . id } Ġfor ĠCustom ĠActions ") ĊĊĉ ĉ init Widgets () ĊĊĉ ĉ // Ġset Ġup ĠAM ĠApps Ċĉ ĉ am App List Ġ= ĠAM App List (( car App . unwrap () Ġas ĠR H MI Application Et ch ). remote Server , Ġgraphics Helpers , Ġ" me . h uf man . android aut oid rive . music ") ĊĊĉ ĉ music App Discovery . listener Ġ= ĠRunnable Ġ{ Ċĉĉ ĉ // Ġmake Ġsure Ġthe Ġcar Ġhas ĠAV ĠContext Ċĉĉ ĉ av Context . create Av Handle () ĊĊĉĉ ĉ // Ġswitch Ġthe Ġinterface Ġto Ġthe Ġcurrently Ġplaying Ġapp Ċĉĉ ĉ val Ġnow Playing Ġ= Ġmusic Controller . music Sessions . get Playing App () Ċĉĉ ĉ val Ġchanged App Ġ= Ġmusic Controller . current App Info Ġ!= Ġnow Playing Ċĉĉ ĉ if Ġ( now Playing Ġ!= Ġnull Ġ&& Ġchanged App ) Ġ{ Ċĉĉĉ ĉ val Ġdiscovered App Ġ= Ġmusic App Discovery . valid Apps . first OrNull Ġ{ Ċĉĉĉĉ ĉ it Ġ== Ġnow Playing Ċĉĉĉ ĉ } Ġ?: Ġnow Playing Ċĉĉĉ ĉ music Controller . connect App Autom atically ( dis covered App ) Ċĉĉ ĉ } ĊĊĉĉ ĉ // Ġconnect Ġto Ġthe Ġprevious Ġapp , Ġif Ġwe Ġaren 't Ġcurrently Ġconnected Ċĉĉ ĉ if Ġ( music Controller . current App Controller Ġ== Ġnull ) Ġ{ Ċĉĉĉ ĉ val ĠappName Ġ= Ġmusic Controller . load Desired App () Ċĉĉĉ ĉ val Ġapp Info Ġ= Ġmusic App Discovery . valid Apps . first OrNull Ġ{ Ġit . packageName Ġ== ĠappName Ġ} Ċĉĉĉ ĉ if Ġ( app Info Ġ!= Ġnull ) Ġ{ Ċĉĉĉĉ ĉ music Controller . connect App Autom atically ( app Info ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } ĊĊĉĉ ĉ // Ġupdate Ġthe ĠAM Ġapps Ġlist Ċĉĉ ĉ val Ġam Radio Adjustment Ġ= Ġmusic App Mode . get Radio AppName ()?. let Ġ{ AM App Info . getApp Weight ( it ) Ġ- Ġ( 8 0 0 Ġ- Ġ 5 0 0 )} Ġ?: Ġ 0 Ċĉĉ ĉ val Ġam Spot ify Adjustment Ġ= ĠAM App Info . getApp Weight (" Spot ify ") Ġ- Ġ( 8 0 0 Ġ- Ġ 5 0 0 ) ĊĊĉĉ ĉ val Ġam Apps Ġ= Ġmusic App Discovery . valid Apps . filter Ġ{ Ċĉĉĉ ĉ !( it . packageName Ġ== Ġ" com . spotify . music " Ġ&& Ġplayback View . state Ġis ĠR H MI State . Audio H mi State ) Ċĉĉ ĉ }. map Ġ{ Ċĉĉĉ ĉ // Ġenforce Ġsome ĠAM Ġsettings Ċĉĉĉ ĉ when Ġ{ Ċĉĉĉĉ ĉ music App Mode . is Id 4 () Ġ-> Ġ{ Ċĉĉĉĉĉ ĉ // Ġif Ġwe Ġare Ġin Ġid 4 , Ġdon 't Ġshow Ġany ĠRadio Ġicons Ċĉĉĉĉĉ ĉ it . clone ( forced Category Ġ= ĠAM Category . MUL TIME DI A ) Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ playback View . state Ġis ĠR H MI State . Audio H mi State Ġ&& Ġit . category Ġ== ĠAM Category . MUL TIME DI A Ġ-> Ġ{ Ċĉĉĉĉĉ ĉ // Ġif Ġwe Ġare Ġthe ĠSpotify Ġicon , Ġadjust Ġthe Ġother ĠMult imedia Ġicons Ġto Ġsort Ġproperly Ċĉĉĉĉĉ ĉ it . clone ( weight Adjustment Ġ= Ġam Spot ify Adjustment ) Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ it . category Ġ== ĠAM Category . RADIO Ġ-> Ġ{ Ċĉĉĉĉĉ ĉ it . clone ( weight Adjustment Ġ= Ġam Radio Adjustment ) Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ else Ġ-> Ġ{ Ċĉĉĉĉĉ ĉ it . clone () Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉĉ ĉ am App List . set Apps ( am Apps ) ĊĊĉĉ ĉ // Ġredraw Ġthe Ġinternal Ġapp Ġlist Ċĉĉ ĉ if Ġ( app ListView Visible ) Ġ{ Ċĉĉĉ ĉ app Switch er View . redraw () Ċĉĉ ĉ } Ċĉ ĉ } Ċĉ ĉ music App Discovery . discover Apps () ĠĠĠ Ġ// Ġtrigger Ġthe Ġdiscovery , Ġto Ġshow Ġthe Ġapps Ġwhen Ġthe Ġhandler Ġstarts Ġrunning ĊĊĉ ĉ music Controller . listener Ġ= ĠRunnable Ġ{ Ċĉĉ ĉ redraw () Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ inner Ġclass ĠCar App Listener : ĠBase BM WR em oting Client () Ġ{ Ċĉ ĉ var Ġserver : ĠBM WR em oting Server ? Ġ= Ġnull Ċĉ ĉ var Ġapp : ĠR H MI Application ? Ġ= Ġnull Ċĉ ĉ override Ġfun Ġrh mi _ on ActionEvent ( handle : ĠInt ?, Ġident : ĠString ?, Ġaction Id : ĠInt ?, Ġargs : ĠMutable Map < *, Ġ*> ?) Ġ{ Ċ // ĉĉ ĉ Log . i ( TAG , Ġ" Received Ġrh mi _ on ActionEvent : Ġhandle =$ handle Ġident =$ ident Ġaction Id =$ action Id ") Ċĉĉ ĉ try Ġ{ Ċĉĉĉ ĉ app ?. actions ?. get ( action Id )?. as RA Action ()?. rh mi Action Callback ?. on ActionEvent ( args ) Ċĉĉĉ ĉ synchronized ( server !! ) Ġ{ Ċĉĉĉĉ ĉ server ?. rh mi _ ack ActionEvent ( handle , Ġaction Id , Ġ 1 , Ġtrue ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ġcatch Ġ( e : ĠR H MI Action Abort ) Ġ{ Ċĉĉĉ ĉ // ĠAction Ġhandler Ġrequested Ġthat Ġwe Ġdon 't Ġclaim Ġsuccess Ċĉĉĉ ĉ synchronized ( server !! ) Ġ{ Ċĉĉĉĉ ĉ server ?. rh mi _ ack ActionEvent ( handle , Ġaction Id , Ġ 1 , Ġfalse ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉĉ ĉ Log . e ( TAG , Ġ" Exception Ġwhile Ġcalling Ġon ActionEvent Ġhandler !", Ġe ) Ċĉĉĉ ĉ synchronized ( server !! ) Ġ{ Ċĉĉĉĉ ĉ server ?. rh mi _ ack ActionEvent ( handle , Ġaction Id , Ġ 1 , Ġtrue ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ override Ġfun Ġrh mi _ on H mi Event ( handle : ĠInt ?, Ġident : ĠString ?, Ġcomponent Id : ĠInt ?, Ġevent Id : ĠInt ?, Ġargs : ĠMutable Map < *, Ġ*> ?) Ġ{ Ċĉĉ ĉ val Ġmsg Ġ= Ġ" Received Ġrh mi _ on H mi Event : Ġhandle =$ handle Ġident =$ ident Ġcomponent Id =$ component Id Ġevent Id =$ eventId Ġargs =${ args ?. toString () }" Ċĉĉ ĉ Log . i ( TAG , Ġmsg ) Ċĉĉ ĉ try Ġ{ Ċĉĉĉ ĉ if Ġ( component Id Ġ== Ġapp Switch er View . state . id Ġ&& Ċĉĉĉĉĉ ĉ eventId Ġ== Ġ 1 Ġ// ĠF OC US Ġevent Ċĉĉĉ ĉ ) Ġ{ Ċĉĉĉĉ ĉ app ListView Visible Ġ= Ġargs ?. get ( 4 . to Byte ()) Ġas ? ĠBoolean Ġ== Ġtrue Ċĉĉĉĉ ĉ if Ġ( app ListView Visible ) Ġ{ Ċĉĉĉĉĉ ĉ app Switch er View . show () Ċĉĉĉĉĉ ĉ music App Discovery . discover Apps Async () Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉĉ ĉ if Ġ( component Id Ġ== Ġplayback View . state . id Ġ&& Ċĉĉĉĉĉ ĉ eventId Ġ== Ġ 1 Ġ// ĠF OC US Ġevent Ċĉĉĉ ĉ ) Ġ{ Ċĉĉĉĉ ĉ playback View Visible Ġ= Ġargs ?. get ( 4 . to Byte ()) Ġas ? ĠBoolean Ġ== Ġtrue Ċĉĉĉĉ ĉ // Ġredraw Ġafter Ġa Ġnew Ġwindow Ġis Ġshown Ċĉĉĉĉ ĉ if Ġ( playback View Visible ) Ġ{ Ċĉĉĉĉĉ ĉ playback View . show () Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉĉ ĉ // g ained Ġfocus Ċĉĉĉ ĉ if Ġ( component Id Ġ== Ġen queued View . state . id Ġ&& Ċĉĉĉĉĉ ĉ eventId Ġ== Ġ 1 Ġ&& Ċĉĉĉĉĉ ĉ args ?. get ( 4 . to Byte ()) Ġas ? ĠBoolean Ġ== Ġtrue Ċĉĉĉ ĉ ) Ġ{ Ċĉĉĉĉ ĉ en queued View Visible Ġ= Ġtrue Ċĉĉĉĉ ĉ en queued View . show () Ċĉĉĉ ĉ } Ċĉĉĉ ĉ // lost Ġfocus Ċĉĉĉ ĉ else Ġif Ġ( component Id Ġ== Ġen queued View . state . id Ġ&& Ċĉĉĉĉĉ ĉ eventId Ġ== Ġ 1 Ġ&& Ċĉĉĉĉĉ ĉ args ?. get ( 4 . to Byte ()) Ġas ? ĠBoolean Ġ== Ġfalse ) Ċĉĉĉ ĉ { Ċĉĉĉĉ ĉ en queued View Visible Ġ= Ġfalse Ċĉĉĉ ĉ } Ċĉĉĉ ĉ if Ġ( component Id Ġ== Ġcustom Actions View . state . id Ġ&& Ċĉĉĉĉĉ ĉ eventId Ġ== Ġ 1 Ġ&& Ċĉĉĉĉĉ ĉ args ?. get ( 4 . to Byte ()) Ġas ? ĠBoolean Ġ== Ġtrue ) Ġ{ Ċĉĉĉĉ ĉ custom Actions View . show () Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ // Ġgeneric Ġevent Ġhandler Ċĉĉĉ ĉ app ?. states ?. get ( component Id )?. on H mi Event ( eventId , Ġargs ) Ċĉĉĉ ĉ app ?. components ?. get ( component Id )?. on H mi Event ( eventId , Ġargs ) Ċĉĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉĉ ĉ Log . e ( TAG , Ġ" Received Ġexception Ġwhile Ġhandling Ġrh mi _ on H mi Event ", Ġe ) Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ override Ġfun Ġav _ connection Granted ( handle : ĠInt ?, Ġconnection Type : ĠBM WR em oting . AV Connection Type ?) Ġ{ Ċĉĉ ĉ val Ġmsg Ġ= Ġ" Received Ġav _ connection Granted : Ġhandle =$ handle Ġconnection Type =$ connection Type " Ċĉĉ ĉ Log . i ( TAG , Ġmsg ) Ċĉĉ ĉ try Ġ{ Ċĉĉĉ ĉ av Context . av _ connection Granted ( handle , Ġconnection Type ) Ċĉĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉĉ ĉ Log . e ( TAG , Ġ" Received Ġexception Ġwhile Ġhandling Ġav _ connection Granted ", Ġe ) Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ override Ġfun Ġav _ connection De activated ( handle : ĠInt ?, Ġconnection Type : ĠBM WR em oting . AV Connection Type ?) Ġ{ Ċĉĉ ĉ val Ġmsg Ġ= Ġ" Received Ġav _ connection De activated : Ġhandle =$ handle Ġconnection Type =$ connection Type " Ċĉĉ ĉ Log . i ( TAG , Ġmsg ) Ċĉĉ ĉ try Ġ{ Ċĉĉĉ ĉ av Context . av _ connection De activated ( handle , Ġconnection Type ) Ċĉĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉĉ ĉ Log . e ( TAG , Ġ" Received Ġexception Ġwhile Ġhandling Ġav _ connection De activated ", Ġe ) Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ override Ġfun Ġav _ connection Denied ( handle : ĠInt ?, Ġconnection Type : ĠBM WR em oting . AV Connection Type ?) Ġ{ Ċĉĉ ĉ val Ġmsg Ġ= Ġ" Received Ġav _ connection Denied : Ġhandle =$ handle Ġconnection Type =$ connection Type " Ċĉĉ ĉ Log . i ( TAG , Ġmsg ) Ċĉ ĉ } ĊĊĉ ĉ override Ġfun Ġav _ request Player State ( handle : ĠInt ?, Ġconnection Type : ĠBM WR em oting . AV Connection Type ?, Ġplayer State : ĠBM WR em oting . AV Player State ?) Ġ{ Ċĉĉ ĉ val Ġmsg Ġ= Ġ" Received Ġav _ request Player State : Ġhandle =$ handle Ġconnection Type =$ connection Type Ġplayer State =$ player State " Ċĉĉ ĉ Log . i ( TAG , Ġmsg ) Ċĉĉ ĉ try Ġ{ Ċĉĉĉ ĉ av Context . av _ request Player State ( handle , Ġconnection Type , Ġplayer State ) Ċĉĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉĉ ĉ Log . e ( TAG , Ġ" Received Ġexception Ġwhile Ġhandling Ġav _ request Player State ", Ġe ) Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ override Ġfun Ġav _ mult imedia Button Event ( handle : ĠInt ?, Ġevent : ĠBM WR em oting . AV Button Event ?) Ġ{ Ċĉĉ ĉ val Ġmsg Ġ= Ġ" Received Ġav _ mult imedia Button Event : Ġhandle =$ handle Ġevent =$ event " Ċĉĉ ĉ Log . i ( TAG , Ġmsg ) Ċĉĉ ĉ try Ġ{ Ċĉĉĉ ĉ av Context . av _ mult imedia Button Event ( handle , Ġevent ) Ċĉĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉĉ ĉ Log . e ( TAG , Ġ" Received Ġexception Ġwhile Ġhandling Ġav _ mult imedia Button Event ", Ġe ) Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ override Ġfun Ġam _ on App Event ( handle : ĠInt ?, Ġident : ĠString ?, ĠappId : ĠString ?, Ġevent : ĠBM WR em oting . AME vent ?) Ġ{ Ċĉĉ ĉ Log . i ( TAG , Ġ" Received Ġam _ on App Event : Ġhandle =$ handle Ġident =$ ident ĠappId =$ appId Ġevent =$ event ") Ċĉĉ ĉ appId Ġ?: Ġreturn Ċĉĉ ĉ try Ġ{ Ċĉĉĉ ĉ val Ġapp Info Ġ= Ġam App List . getApp Info ( appId ) Ġ?: Ġreturn Ċĉĉĉ ĉ av Context . av _ request Context ( app Info ) Ċĉĉĉ ĉ app ?. events ?. values ?. filter Is Instance < RH MI Event . Focus Event >() ?. first OrNull ()?. trigger Event ( map Of ( 0 . to Byte () Ġto Ġplayback View . state . id )) Ċĉĉĉ ĉ synchronized ( server !! ) Ġ{ Ċĉĉĉĉ ĉ am App List . redraw App ( app Info ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉĉ ĉ Log . e ( TAG , Ġ" Received Ġexception Ġwhile Ġhandling Ġam _ on App Event ", Ġe ) Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ override Ġfun Ġcds _ on PropertyChanged Event ( handle : ĠInt ?, Ġident : ĠString ?, ĠpropertyName : ĠString ?, Ġproperty Value : ĠString ?) Ġ{ Ċĉĉ ĉ if Ġ( propertyName Ġ== Ġ" h mi . graphical Context ") Ġ{ Ċ // ĉĉĉ ĉ Log . i ( TAG , Ġ" Received Ġgraphical Context : Ġ$ property Value ") Ċĉĉĉ ĉ h mi Context Changed Time Ġ= ĠSystem . currentTimeMillis () Ċĉĉ ĉ } Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ private Ġfun Ġinit Widgets () Ġ{ Ċĉ ĉ car App . components . values . filter Is Instance < RH MI Component . Entry Button >(). forEach Ġ{ Ċĉĉ ĉ it . getAction ()?. as RA Action ()?. rh mi Action Callback Ġ= ĠR H MI ActionButton Callback Ġ{ Ċĉĉĉ ĉ if Ġ( music Controller . current App Controller Ġ== Ġnull ) Ġ{ Ċĉĉĉĉ ĉ it . getAction ()?. as H MI Action ()?. getTarget Model ()?. as Ra Int Model ()?. value Ġ= Ġapp Switch er View . state . id Ċĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉ ĉ it . getAction ()?. as H MI Action ()?. getTarget Model ()?. as Ra Int Model ()?. value Ġ= Ġplayback View . state . id ĊĊĉĉĉĉ ĉ // Ġinvoked Ġmanually , Ġnot Ġby Ġa Ġshortcut Ġbutton Ċĉĉĉĉ ĉ // Ġwhen Ġthe ĠMedia Ġbutton Ġis Ġpressed , Ġit Ġshows Ġthe ĠMedia / Radio Ġwindow Ġfor Ġa Ġshort Ġtime Ċĉĉĉĉ ĉ // Ġand Ġthen Ġselects Ġthe ĠEntry button Ċĉĉĉĉ ĉ val Ġcontext Change Delay Ġ= ĠSystem . currentTimeMillis () Ġ- Ġh mi Context Changed Time Ċĉĉĉĉ ĉ if Ġ( music App Mode . should Id 5 Playback () Ġ&& Ġcontext Change Delay Ġ> Ġ 1 5 0 0 ) Ġ{ Ċĉĉĉĉĉ ĉ // Ġthere 's Ġno Ġspot ify ĠAM Ġicon Ġfor Ġthe Ġuser Ġto Ġpush Ċĉĉĉĉĉ ĉ // Ġso Ġhandle Ġthis Ġspot ify Ġicon Ġpush Ċĉĉĉĉĉ ĉ // Ġbut Ġonly Ġif Ġthe Ġuser Ġhas Ġdw el led Ġon Ġa Ġscreen Ġfor Ġa Ġsecond Ċĉĉĉĉĉ ĉ val Ġspot ify App Ġ= Ġmusic App Discovery . valid Apps . first OrNull Ġ{ Ċĉĉĉĉĉĉ ĉ it . packageName Ġ== Ġ" com . spotify . music " Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ if Ġ( spotify App Ġ!= Ġnull ) Ġ{ Ċĉĉĉĉĉĉ ĉ av Context . av _ request Context ( spotify App ) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } ĊĊĉĉĉĉ ĉ val Ġcurrent App Ġ= Ġmusic Controller . current App Info Ċĉĉĉĉ ĉ if Ġ( current App Ġ!= Ġnull ) Ġ{ Ċĉĉĉĉĉ ĉ av Context . av _ request Context ( current App ) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ global Metadata . init Widgets () Ċĉ ĉ app Switch er View . init Widgets ( playback View ) Ċĉ ĉ playback View . init Widgets ( app Switch er View , Ġen queued View , Ġbrowse View , Ġcustom Actions View ) Ċĉ ĉ en queued View . init Widgets ( playback View ) Ċĉ ĉ browse View . init Widgets ( playback View , Ġinput State ) Ċĉ ĉ custom Actions View . init Widgets ( playback View ) Ċ ĉ } ĊĊ ĉ fun Ġredraw () Ġ{ Ċĉ ĉ // Ġcheck Ġif Ġwe Ġneed Ġto Ġcreate Ġan Ġav Ġhandle , Ġif Ġit 's Ġmissing Ċĉ ĉ av Context . create Av Handle () Ċĉ ĉ if Ġ( app ListView Visible ) Ġ{ Ċĉĉ ĉ app Switch er View . redraw () Ċĉ ĉ } Ċĉ ĉ if Ġ( playback View Visible Ġ|| Ġplayback View . state Ġis ĠR H MI State . Audio H mi State ) Ġ{ Ċĉĉ ĉ playback View . redraw () Ċĉ ĉ } Ċĉ ĉ if Ġ( en queued View Visible ) Ġ{ Ċĉĉ ĉ en queued View . redraw () Ċĉ ĉ } Ċĉ ĉ if Ġ( browse View Visible ) Ġ{ Ċĉĉ ĉ browse View . redraw () Ċĉ ĉ } ĊĊĉ ĉ // Ġif Ġrunning Ġover ĠUSB Ġor Ġaudio Ġcontext Ġis Ġgranted , Ġset Ġthe Ġglobal Ġmetadata Ċĉ ĉ if Ġ(! music App Mode . should Request Audio Context () Ġ|| Ġav Context . current Context ) Ġ{ Ċĉĉ ĉ global Metadata . redraw () Ċĉ ĉ } Ċ ĉ } Ċ Ċ }