From 745040be2bcb27b35c4044a004c64610ce30d1ed Mon Sep 17 00:00:00 2001 From: Kavish Devar Date: Sat, 19 Oct 2024 19:48:12 +0530 Subject: [PATCH] android: add QS Tile to change Noise Control Mode --- .../release/baselineProfiles/0/app-release.dm | Bin 7736 -> 8335 bytes .../release/baselineProfiles/1/app-release.dm | Bin 7656 -> 8264 bytes android/app/src/main/AndroidManifest.xml | 11 ++ .../me/kavishdevar/aln/AirPodsQSService.kt | 90 +++++++++++++ .../java/me/kavishdevar/aln/AirPodsService.kt | 127 ++++++++++-------- .../kavishdevar/aln/AirPodsSettingsScreen.kt | 6 +- .../java/me/kavishdevar/aln/MainActivity.kt | 4 +- .../main/java/me/kavishdevar/aln/Packets.kt | 4 + .../me/kavishdevar/aln/StartupReceiver.kt | 74 ---------- android/app/src/main/res/drawable/airpods.xml | 10 ++ 10 files changed, 190 insertions(+), 136 deletions(-) create mode 100644 android/app/src/main/java/me/kavishdevar/aln/AirPodsQSService.kt delete mode 100644 android/app/src/main/java/me/kavishdevar/aln/StartupReceiver.kt create mode 100644 android/app/src/main/res/drawable/airpods.xml diff --git a/android/app/release/baselineProfiles/0/app-release.dm b/android/app/release/baselineProfiles/0/app-release.dm index 7d4a3cce5276e6418e12d532f25cf95bc903b08c..89991458aec8ce0a2a3fce431b4fd1065cfb59d0 100644 GIT binary patch literal 8335 zcmbtaWl&sQlg7e8un>X-CnN!ayL-^!7Tj%ccNioE0UgcU zeA!&woUKuNsYKQu2PhnzyeR1ZzER}S^8Wi6?a{hE>eZtfzD4=R9$Qot6az{WlnHh; z6f_j+d3*&mrpGrAC@45677k|a?pE$>mR3GhKhtjf2~kk`Tu@MO|6_scuN5Cu_#!8M zD94NblaKn$oGN=ehox;{&8J$_zvz8%0D$V%Tm39-^jBLs#jK`h!7vnA@%rt(af}L9 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 UJi+{H`LDhJ&qs?v``7H>0Qmv9o&W#< delta 7196 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 F{{U!+W?=vT diff --git a/android/app/release/baselineProfiles/1/app-release.dm b/android/app/release/baselineProfiles/1/app-release.dm index 9a2b1b23b4fe3cda20bc5a289eada20cffc9b572..4bf5ed1924a1721dc0ee7153b179be279286168a 100644 GIT binary patch literal 8264 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 X(@|UP5%yop7=J$ZKmR7WzpVcUnnS|{ literal 7656 zcmb7Jbx;)Ew+8`1KoCJfT4I%Mq!koIkd$WWl#*C#*(D@ITIohgYUwVK?vmJr1(aI4 z7M5M=`F%5Qe&6@z#rK^%cg~G-&b>3|p3nW`qoqbbNP|a0LV`!4`q~KZZ$kcO{NBUS z#nQu1;Jt^N9lkDO`P!cWo{+E*-Yus$x9}7h@$h`{_keffZS+7La&oPryA(3DyEWt? z-ciFMj}?Y*+s0U6NVy&p>T?)}zKFoP^(l$VX`tvCj-RidGrfw-RxC2%6fnudo6u80 zsPn|1>YgsQv(BU;E$yE9tCzgwT|5XO_00fG`w8wWWA4ff)0VxJhTZ=O!7O=>%WW=t zcKRGZ6i)ox{q~z8IiyZTbFvS=&)l_!wPVxU!IjJ4STT<6}l)qh|h_CyJZ|vv!KyKuWdQ@`D4S1jKnJy0)*ppBilT=^S2v@ z-;2c(lQ!uGD=B>=xPTl-ySe1h#6055eznW5FDA6*%^xAM*{B-wTtzvcU=UBCtm*mE7AA^rQT za1Jz_lwiv;_tI!6pAYwip6&KWe5;`UL*1q#z-7;~AsRAWrhKrsn<-OlFdSci&s%bsBP|mC>v*a71u_5&CARdfeYM`8OoA{G#gNS_~hRJZ^m<492zW zxJub}ffUSGU0bTcgXoeuFxn4WO?0rmrd6T@O^o;82|pvhNAOS7GcY+H+K(5qu+)gY z3sL%qUjID)Keqf35}a=}kUOs^^OV-eVx?Rlu(kww;GH!QmRZ+n-_${tcGz1DJhuO( zFtpi@WB84&?kMQXOpwj8c$l|?_mLO?eV$5?o@6BDqMG^D9XUU*{vFefKv;5_eT2WxB}qQU9!W^_S+bF3 zfR7-w{;M{Z1#gyDeN{6Q022T>cFoJ3`x1K~GO2v!pVP)hUC93ut0XrPd{uMu3BRUy zZ#9iNN>tx4?#rxtg@QHJW;0))lBk-Iw6X#JSHZV{>0T)S${yz@Ws$o)r*rsRVPkB4 zWr5FScTW7C^WuahGva5_{$~j^-^F4@IjVJ`WiyBgV_XT$nL_QL$IgTy=)n@X0q={< zpN)mSjk3~asuJ8YtkLJ+rVUHV`4c2^`(vz`-q@nk1$x_3`v6%uPt)j5>7(Kb#+@&V zb-3wc+ZcGA|6u-S|8l2I!31^ zZH`_|e^;Nw7zMwX^LD?s0p0NUU!9f;IHP(ck&8-OFXb2Bzv28_eXubQR3^%?X78~> z4SoZ-N|(KIBJFuU;>hpK`8T=#^v58S9AV@WVu}>UzWT5|Eq%Dd=0>#&k)W?u@t*b) zRpN6MIAl`~3-oh{@{l|LDs}Smw%8{JTGpKMnD`-m@Sjb~=ZzctRMUTuHYjRP`LwCl zB%lR%h-gzrhk>`b&3?r_j}0TdpvB3$YvGpmFQox_H>zi?n?Cms*k-I_Kh~;j;y3Qc z{3zRORWpylk}aIOh~q*au?i6=I$YRaMIO8_R3&QZvbW*)BDq81Nf(R{1o|xQFfK|w znyt}cvfF~X!53_RZtuuqG8ej~m@(Jdi%&aMGII)VR=sSVblyMeJ<=I724t^h(@#>* z5w~9lIFT+jofX(d$>F|St49Tk9jtE4ZPtkx++Ti>IV}RDGq^7?Pd8TkPs;fpm)rju z?3q6~8VBaw>&WqM4S3sZaN~B+jp0oG?PFy=7Xd|YPebdb-5#DQommZ;?z%PFoXS`j zVNqufVyDY5#a?-!7f#8lw}u`_?;8bl3J*)M?=}8Zs8a0DH;C4Fae4IVRkJ~}^W4Q! zbVvTdKfuoaze%tSc|iOP+04mJ3bpy*`PVoU$A2KS1;{dYpxxF0JPZva-sESBgY{X9 zj~V2c5k|Lls4;K8JfC|x2Kurp-U>6hOwBwb%#Xa6y%RSynf0!>-R-@M*lFr;dKJD2Z38HmT8HpCX2ntKi&i zl2+E8_f{rlG2lMQ!iX_SpNrz;rd=`0!-E*)ikH-BRD;0MqPlsdtN9K_2i$%eIC?&K zZ1SxP9=8kjq-ZJZUJ8f4!#&xKf(9@ulv)c9JHmKrr?U&EK#p{q-Hoj)z|w24e96)J zVMcw!oG+KFON~aIL%8fU#@R*~rQ^ON7j}0BXtg^cfR))}U$_ca|2#TeajgWzIZL4r zo~h?Z^iTZ8iOht%iLd;6UBP5F77|S7&9d|O-0=+il_$ki5c9@XR z*0x9n=o4RjJ*(M`Yi|{dkvH*xtQ|L_%})CHyA0bo3ded)Tc=>P?SEjcQSBl_ZBm|A zC)TqLsgrcWqXd@On@lMU90s}-Hw*4F2Q^)9*G4t9JTGKkU8zB~@?O=nPkWv~w@g1S z)}1tgq1)26vq!avs>G{h8tXVjlHNlIhFx_ZNml2WcfKb^%n4_yIM~1zf+>{O$&IB( z&k|gj7dk}&;4>T?HW2pt|n_;f$1*>@F+1A4zY5m#6S}iwbzU5c0ykMes$!J>rhO-pKFe@UK z6jD*JGr}#UI8<>Tt3o+Jfd2ma1aCv~dXfN*C->~Hh5uH4_dtJlY`!*zc)0|w>q^VT z?*`vLu<%*Ozmc-9F;C&>*K9rR@z`Z|DI!iDBbd3I+A6a14`QL0rF1q66{kB06Smn7 z7DPq{IzLYpqt20UgE^SjiP}Xlv=aW@B9=&#OgEqzbvpc!CCupI6m9RBp!7iSMD;N# zMO#$EBSx+Gr1zhtmdCy1$HXp!Zlw0?Q_H+KkYwfW#P08wl3GiC?pj7UtIGY1QIC3G zsf}8kO*K|?>RgdLe%)91$-Afv_&=ad~HU70Dzn4Qt8 z(g%*3nN*$;4oaFbxTpJ^YU@c`OMFbB`i+z!R8dX@4J~P7+AJD7W(`9}SK)QBPh;Ga zw?CZ(slQqsUycea{}L6YYzsSjOXksC!uZjVx-aZHs%l@#^m=SiJhx>?(dY8=E~8Dc z_TlRq_G;=S(-Kz-x1U#R#O#LZ3cr zks;QNF!Hy?Z(DU`Zz`%3-+0JzE-vK00L&utHi$a)u>N@$rFw6}z%TGD6+OL(LVB;a zEGE0{D&PciPI+`M@~O*Wt{BG@0!}`Bd3nibQ(A@X5`QV=Z|!EXU?sCrEyaKzsyJgl zUp;_ROEd5lHD=H~6FkU3ZOOjo=lL3DfzfKzeH{MWPM-4?DX(5z-W#3@Yv55#S`ylO zwSHIeGTpo1h)RH->Mp-!U+NtcO^oe#Qu7auc_)$hw3T_Xqkbk8cCRT7we%P@LHIhX z{#kKmL6-O~W_WvUN(Dh$hvSoOuO!@56C4XcePB5Jhi^l>!b@51ktO}o6QA7Zy&q;jV6oEMD}ZOL=YXZyazbm95q?P|r2 z1_5(82nRyhY!yL{${I3_!u08u#yo1=hVX!zCV+jPJ(*~SFpv7!6J18hc>>i}^XWnB z38ubx4exk?yB5s?jI!ZjXBzTFszBG}q(SbV-5(?z- z4#ZA`Cr`@>u}OOl`tM-D%{sYULRHz*!qnIXUOJKX=kG-3HWE9Ls(>|qr zN!I)I&RD0@{1bLV$V&5(E1oVJ$2Lug|I#c%36@={=M2-L)-Zy(M=(Dp4P&(Ph<{s^ z&xZcS2hQ*M!tEJzWZXUPP0YyAbfrb+Q+J{=e|+je(#9O?_md@gD|kfiJtpk@+HyIh zQ7{lg*ujS)4Cv{ljBu6ys1BEhoN+d~+8=Ee2b7s63-;3}bW=Z<{S11{8fe5;^R5kX zn6z#RPo`Wi8a~s$0%9@%o}$f*YbD7Y_Fh9bBN`K>X)8Po?10tgQyOyG4#Oq#W$}73 z4iu5DZ6UlyusLmmG)Woyv=RUhTd(!IO5uBWIr=~#mNn`#wQ=aesUS@I%ZAw9TIim$ zM)G%B_fdV=)OXqHy3j%aSl}2;&GutIY5KvViUxYZ#uS?_Aj7W&JIVb<_=I40Oq*GM zSRES&1qLW`k+~S{5fb%q(J#JsxFks*y7eU5xK-;Wcv+~Nvi$qwvZX2ky*@X`jLPrb zwY*iDyHivCxwb#lK(SABhrRB3|4=~gB&Dn0^IY}h@Nlom)EJ_uO*#XM7yhc^wwv08 zi5zCOC2fShb4XSi5#yadUDs1&hD4+|%>XEA8KWowgk+#5z{+K6M4X)>w-;RDl@2>8KrfZU!(OGw>OiyxK~Q8v02Y%Y3u)tyI@G} z!Ns$A>W}R~#a9#_Wr}K~51xN%W4jmnsohfAs;c&oAlIY>S))><=2t8P_#%Q56){4{ zMVN-XIA9o#@lShM#sQjkSQM=2FSGiRY7k!&y7IMmW0SSq4CNJqehg)$IbH#}W6o+) z`AD<0s;Q^0GL1NN3fc<;b-UUN`a&WSLMHm=@FxceLjz4*L&*55{*Yyb?Z}r@0RuKyN;y+KWfje0G_Y`qqKw;{ z@(ydKJOpc4vrsZk{4xt1IJl{u$mMHV~4H^am+}_#Rw6yM$MyEPr8% z5a_s7G-Zo4V7H)z;MYzq^rcieMgTl5MC#T^Gq?}ikO%(|cZvvK3mnU7oGWh}3_P<= zRwg{Ki8nA7>qVD}nF=~Wg>~m6QQJLa58hGQ2{gih^85XCddjU50?cj5!&aBp(f%zs zf7u6KKx}`7idjG1D#`UUClBS&M`Pj^6YoG%7Bv6;u6!urXi}kHZ*6rhKynp11~g-F0`zf&9C>D(%+;3CG_m(Gi+@*Al;o;&`dO^UU&x^o@qfw$^{N zPA0e)tyPNzFDDTpKQ5<`Ce1v#iX?e1hj309iTrG(8WHFIBcH;*PS6)Z=yt2b70n<~ znsuIFJTN7EJLh7xVkm+p<3UmsO&fv^72#SCUwG{L;J3z;GN!{efybTNI*IIR*o24} z0I?T(k2~_bdPUU|YB=@b{xatggJrUykTEz=X^1tRL~fh7E?9P+P=SdxQ8OM*8u^JB zt>kyu{k@84UPTUyK39y4CorjJHQ}P{%p+(0CU8oubI75%)O&w@XdFRmn#;fYll4fa zc{?KCYJ!pTcNklplH4Vw-{GAh+=r1W;GQm{=KY7qfda(m;MxLXV%cw5U{1=;Tneh1 z_?9zs4%@>_Ko5iJj5(t34U$#P+vQe~h3MBQONHat%UmIBWN5Mw>C=cJjNh8g&pLh- z=buFM=P2EE?X;?c=-im&Zvh6h2ut$Cj*xIq{Jlgv7x6fM{(PiUi1dUOG16ft`T4ZS znghexqpuWV=gp6)Y*&myU(2ba#Y&MYGqT&?%Stx1^^rVuEi(!{)R(zkEb9b!ZBGS< zKJrky=*1qlxSX2alF+U^PB4&3P$b@ZE~(^LTc2e_7y$!r zHxN*6+%8BZ)-Hz3oWUv+H;NqcA@8>a^5cvvB|<3DhRVE9AQ#V*A$FHgL`qTlUCyr(S&`c?Cv=;sR=Xy0n(?_C zZks*XBIXKF*@ITBE%Or9Q+bs$uef8M&5^X68R^!mECkJsI+;ku%&H6v9PAKWtvL1* z-=OGQWhamHO{!f#m=8}x9QzM`V>u`GI@h_16A1|QUg?w_Xx*Xq6{2JZt+#sT3BXuH zPECWO$+&nVCRk1vxLVGhQJ`MsOaDf#1Os6%hA9&)E%7bdr;ldZW2W9-8|nDOzL<}e zu8Rn;AZxH1`_5DbQb=yweyVwFsH8;9L!%nH&)$6W)^{m;?exc9%uW37 zj1*mf!_F;PEwItE0EX{-Sy1jVKr7=zFy^k0EH;4^QjdNm9Fc{o^CNgCe~LZ0x?||_ zc=!gqpuT^iM4hd<)Ow^+T9F>3dfmE1wB+kuhR7N7~?I8lBAB zkl_Zrfb8VS$lZd)JLwP8~OrH>c-I zM^{swH5RG`&^y44CS7tVto4@-n#ATJY3|e zM2=L-<*>9FDY)Bo*1Ks&8=;yCZ9bP#85iy~xo^AMaJO$H3;Rgo1llyPTPE*&P{`s6 zMhLZ#8L-#n+>8+2yw_Y(pIdeuDZF0Xt|f1`3Y=VP)0lRd*+h@DjC!xv-ZHqhjLVd% z1=|jr<1F`0xAxUbw1B|x+BWAd>(yX!fWR}s+6Xh;*xe)< z@4IP`zPF>JE7>Ihdqk$Eh?O+aZF8+)v@Q)evE^@n`i zl8gGuS^3m9nUa?SPsofvxw>y1^W){%_x1EJZ**O9d7Rw*Tx=Wi{eigmTUUfkTrjk) zyGfej16h{Ut36@ei>7k(c$CX>PRg6#2MWg>rx>|5%&R>-76k^+Ie;>^4L+|tcA?*b zFe=d3ceT9X`KH335_pSKWeRj$xe(4nt1Mfi1$~48!I( zU(+DkuEq!1e#a0Wrt2U4J1iY%<_fsovhX#DYJlPW67LLSCR!zLjcjXy5QN=fIy|-+ z$?OEKL>p&>OS&lfHz!#_RsHEj77(6$7Nk<3`5cAIoH>Ofh4HpEH(1$C<4z}~xzmt> zdZN3bY;;-8uY}`Stpz!|zShD+)h~@nirG!mowBJ78Zn8#YWfeuKWv)rpRV;kGIDqS3nS-( zABFFA{oca`Pe@1v?-m{zHy)lJ{=ai_#_by2Liai@6H9}n-#V+S>(SlrA+P*CU;h<3 z|A_teQi#E-9F8!li9`G~uL)?^Ec2r#U~cqk*(cVvp1bAiT%(?zOX$1vX@RL4SGR*H3bI)P9%3QTs8l$c$2IN%gYZjjoYQY29XGbI?$^D#i_i6@X zL9M>Y;$L4D%}!stq|1|FQJJw6F*jjBkePv41|{!GVV2f9mwf^d*D-u8-8mdsT=Mm5 z7q-Cfu2SNn$cL0?-@1+ORl%6q{Wa7J(8JBw>ZQN`5c$~){-{Rc78Hn?o*JvCyoSUJ zN!!V*ED4xzINNP__JmNfP29$xLpZMzv^>idBq=Z%-+F{00<>~h|3M1$*vnc6%c(+JN_)Y-p)IGmiql@2? ztb`_!V)J_1wdc*#>xcKsojlifp6>@h-bDJv^-@a2a|HjD%KNHe$?<=Z5cQ{Pso~$E z!TT4z`u8;dMX&y6`8(PAUp@aG^{;2}FZulE$^6~ZMN5t7_Fvn#{xr}Z4P^dn_HVmy Bq$L0V diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index a9f9e93..57599da 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -43,6 +43,17 @@ android:foregroundServiceType="connectedDevice" android:permission="android.permission.BLUETOOTH_CONNECT" /> + + + + + + diff --git a/android/app/src/main/java/me/kavishdevar/aln/AirPodsQSService.kt b/android/app/src/main/java/me/kavishdevar/aln/AirPodsQSService.kt new file mode 100644 index 0000000..c7562fc --- /dev/null +++ b/android/app/src/main/java/me/kavishdevar/aln/AirPodsQSService.kt @@ -0,0 +1,90 @@ +package me.kavishdevar.aln + +import android.annotation.SuppressLint +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.service.quicksettings.Tile +import android.service.quicksettings.TileService +import android.util.Log + +class AirPodsQSService: TileService() { + private val ancModes = listOf(NoiseControlMode.OFF.name, NoiseControlMode.NOISE_CANCELLATION.name, NoiseControlMode.TRANSPARENCY.name, NoiseControlMode.ADAPTIVE.name) + private var currentModeIndex = 3 + private lateinit var ancStatusReceiver: BroadcastReceiver + private lateinit var availabilityReceiver: BroadcastReceiver + + @SuppressLint("InlinedApi") + override fun onStartListening() { + super.onStartListening() + currentModeIndex = (ServiceManager.getService()?.getANC()?.minus(1)) ?: 3 + if (currentModeIndex == -1) { + currentModeIndex = 3 + } + + if (ServiceManager.getService() == null) { + qsTile.state = Tile.STATE_UNAVAILABLE + qsTile.updateTile() + } + if (ServiceManager.getService()?.isConnected == true) { + qsTile.state = Tile.STATE_ACTIVE + qsTile.updateTile() + } + else { + qsTile.state = Tile.STATE_UNAVAILABLE + qsTile.updateTile() + } + + ancStatusReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + val ancStatus = intent.getIntExtra("data", 4) + currentModeIndex = ancStatus - 1 + updateTile() + } + } + + availabilityReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action == AirPodsNotifications.AIRPODS_CONNECTED) { + qsTile.state = Tile.STATE_ACTIVE + qsTile.updateTile() + } + else if (intent.action == AirPodsNotifications.AIRPODS_DISCONNECTED) { + qsTile.state = Tile.STATE_UNAVAILABLE + qsTile.updateTile() + } + } + } + + registerReceiver(ancStatusReceiver, IntentFilter(AirPodsNotifications.ANC_DATA), RECEIVER_EXPORTED) + updateTile() + } + + override fun onStopListening() { + super.onStopListening() + unregisterReceiver(ancStatusReceiver) + unregisterReceiver(availabilityReceiver) + } + + override fun onClick() { + super.onClick() + Log.d("QuickSettingTileService", "ANC tile clicked") + currentModeIndex = (currentModeIndex + 1) % ancModes.size + switchAncMode(currentModeIndex) + } + + private fun updateTile() { + val currentMode = ancModes[currentModeIndex] + qsTile.label = currentMode.replace("_", " ").lowercase().replaceFirstChar { it.uppercase() } + qsTile.state = Tile.STATE_ACTIVE + qsTile.updateTile() + } + + private fun switchAncMode(modeIndex: Int) { + currentModeIndex = modeIndex + val airPodsService = ServiceManager.getService() + airPodsService?.setANCMode(currentModeIndex + 1) + updateTile() + } +} \ No newline at end of file diff --git a/android/app/src/main/java/me/kavishdevar/aln/AirPodsService.kt b/android/app/src/main/java/me/kavishdevar/aln/AirPodsService.kt index 9a5cf14..a7a51c8 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/AirPodsService.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/AirPodsService.kt @@ -36,6 +36,19 @@ private const val ACTION_ASI_UPDATE_BLUETOOTH_DATA = "batterywidget.impl.action. //private const val COMPANION_TYPE_NONE = "COMPANION_NONE" //const val VENDOR_RESULT_CODE_COMMAND_ANDROID = "+ANDROID" + +object ServiceManager { + private var service: AirPodsService? = null + @Synchronized + fun getService(): AirPodsService? { + return service + } + @Synchronized + fun setService(service: AirPodsService?) { + this.service = service + } +} + class AirPodsService : Service() { inner class LocalBinder : Binder() { fun getService(): AirPodsService = this@AirPodsService @@ -45,7 +58,8 @@ class AirPodsService : Service() { return LocalBinder() } - var isRunning: Boolean = false + + var isConnected: Boolean = false private var socket: BluetoothSocket? = null fun sendPacket(packet: String) { @@ -211,7 +225,7 @@ class AirPodsService : Service() { var batteryUnified = 0 var batteryUnifiedArg = 0 - // Handle each Battery object from batteryList + // Handle each Battery object from batteryList // batteryList.forEach { battery -> // when (battery.getComponentName()) { // "LEFT" -> { @@ -296,10 +310,12 @@ class AirPodsService : Service() { val notification = createNotification() startForeground(1, notification) - if (isRunning) { + ServiceManager.setService(this) + + if (isConnected) { return START_STICKY } - isRunning = true + isConnected = true @Suppress("DEPRECATION") val device = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) intent?.getParcelableExtra("device", BluetoothDevice::class.java) else intent?.getParcelableExtra("device") @@ -354,65 +370,65 @@ class AirPodsService : Service() { Log.d("AirPods Parser", "Ear Detection: ${earDetectionNotification.status[0]} ${earDetectionNotification.status[1]}") var justEnabledA2dp = false val earReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - val data = intent.getByteArrayExtra("data") - if (data != null && earDetectionEnabled) { - inEar = if (data.find { it == 0x02.toByte() } != null || data.find { it == 0x03.toByte() } != null) { - data[0] == 0x00.toByte() || data[1] == 0x00.toByte() - } else { - data[0] == 0x00.toByte() && data[1] == 0x00.toByte() - } + override fun onReceive(context: Context, intent: Intent) { + val data = intent.getByteArrayExtra("data") + if (data != null && earDetectionEnabled) { + inEar = if (data.find { it == 0x02.toByte() } != null || data.find { it == 0x03.toByte() } != null) { + data[0] == 0x00.toByte() || data[1] == 0x00.toByte() + } else { + data[0] == 0x00.toByte() && data[1] == 0x00.toByte() + } - val newInEarData = listOf(data[0] == 0x00.toByte(), data[1] == 0x00.toByte()) - if (newInEarData.contains(true) && inEarData == listOf(false, false)) { - connectAudio(this@AirPodsService, device) - justEnabledA2dp = true - val bluetoothAdapter = this@AirPodsService.getSystemService(BluetoothManager::class.java).adapter - bluetoothAdapter.getProfileProxy( - this@AirPodsService, object : BluetoothProfile.ServiceListener { - override fun onServiceConnected( - profile: Int, - proxy: BluetoothProfile - ) { - if (profile == BluetoothProfile.A2DP) { - val connectedDevices = - proxy.connectedDevices - if (connectedDevices.isNotEmpty()) { - MediaController.sendPlay() - } + val newInEarData = listOf(data[0] == 0x00.toByte(), data[1] == 0x00.toByte()) + if (newInEarData.contains(true) && inEarData == listOf(false, false)) { + connectAudio(this@AirPodsService, device) + justEnabledA2dp = true + val bluetoothAdapter = this@AirPodsService.getSystemService(BluetoothManager::class.java).adapter + bluetoothAdapter.getProfileProxy( + this@AirPodsService, object : BluetoothProfile.ServiceListener { + override fun onServiceConnected( + profile: Int, + proxy: BluetoothProfile + ) { + if (profile == BluetoothProfile.A2DP) { + val connectedDevices = + proxy.connectedDevices + if (connectedDevices.isNotEmpty()) { + MediaController.sendPlay() } - bluetoothAdapter.closeProfileProxy( - profile, - proxy - ) - } - - override fun onServiceDisconnected( - profile: Int - ) { } + bluetoothAdapter.closeProfileProxy( + profile, + proxy + ) } - ,BluetoothProfile.A2DP - ) - } - else if (newInEarData == listOf(false, false)){ - disconnectAudio(this@AirPodsService, device) - } - - inEarData = newInEarData - - if (inEar == true) { - if (!justEnabledA2dp) { - justEnabledA2dp = false - MediaController.sendPlay() + override fun onServiceDisconnected( + profile: Int + ) { + } } - } else { - MediaController.sendPause() + ,BluetoothProfile.A2DP + ) + + } + else if (newInEarData == listOf(false, false)){ + disconnectAudio(this@AirPodsService, device) + } + + inEarData = newInEarData + + if (inEar == true) { + if (!justEnabledA2dp) { + justEnabledA2dp = false + MediaController.sendPlay() } + } else { + MediaController.sendPause() } } } + } val earIntentFilter = IntentFilter(AirPodsNotifications.EAR_DETECTION_DATA) this@AirPodsService.registerReceiver(earReceiver, earIntentFilter, @@ -455,7 +471,7 @@ class AirPodsService : Service() { } } Log.d("AirPods Service", "Socket closed") - isRunning = false + isConnected = false this@AirPodsService.stopForeground(STOP_FOREGROUND_REMOVE) socket?.close() sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED)) @@ -471,6 +487,7 @@ class AirPodsService : Service() { override fun onDestroy() { super.onDestroy() socket?.close() - isRunning = false + isConnected = false + ServiceManager.setService(null) } } \ No newline at end of file diff --git a/android/app/src/main/java/me/kavishdevar/aln/AirPodsSettingsScreen.kt b/android/app/src/main/java/me/kavishdevar/aln/AirPodsSettingsScreen.kt index e815107..4e01f6e 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/AirPodsSettingsScreen.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/AirPodsSettingsScreen.kt @@ -729,10 +729,6 @@ fun NoiseControlButton( } } -enum class NoiseControlMode { - OFF, NOISE_CANCELLATION, TRANSPARENCY, ADAPTIVE -} - @Composable fun StyledSwitch( checked: Boolean, @@ -802,7 +798,6 @@ fun StyledTextField( color = textColor ) ) - BasicTextField( value = value, onValueChange = onValueChange, @@ -810,6 +805,7 @@ fun StyledTextField( color = textColor, fontSize = 16.sp, ), + singleLine = true, cursorBrush = SolidColor(cursorColor), // Dynamic cursor color based on focus decorationBox = { innerTextField -> Row( diff --git a/android/app/src/main/java/me/kavishdevar/aln/MainActivity.kt b/android/app/src/main/java/me/kavishdevar/aln/MainActivity.kt index bd76452..153d7e6 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/MainActivity.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/MainActivity.kt @@ -146,7 +146,7 @@ fun Main(paddingValues: PaddingValues, topAppBarTitle: MutableState) { val sharedPreferences = context.getSharedPreferences("settings", Context.MODE_PRIVATE) topAppBarTitle.value = sharedPreferences.getString("name", device.name) ?: device.name // Start AirPods service if not running - if (context.getSystemService(AirPodsService::class.java)?.isRunning != true) { + if (context.getSystemService(AirPodsService::class.java)?.isConnected != true) { context.startService(Intent(context, AirPodsService::class.java).apply { putExtra("device", device) }) @@ -264,4 +264,4 @@ fun Main(paddingValues: PaddingValues, topAppBarTitle: MutableState) { @Composable fun PreviewAirPodsSettingsScreen() { AirPodsSettingsScreen(paddingValues = PaddingValues(0.dp), device = null, service = null, navController = rememberNavController()) -} +} \ No newline at end of file diff --git a/android/app/src/main/java/me/kavishdevar/aln/Packets.kt b/android/app/src/main/java/me/kavishdevar/aln/Packets.kt index 82f3374..d45ab0a 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/Packets.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/Packets.kt @@ -59,6 +59,10 @@ data class Battery(val component: Int, val level: Int, val status: Int) : Parcel } } +enum class NoiseControlMode { + OFF, NOISE_CANCELLATION, TRANSPARENCY, ADAPTIVE +} + class AirPodsNotifications { companion object { const val AIRPODS_CONNECTED = "me.kavishdevar.aln.AIRPODS_CONNECTED" diff --git a/android/app/src/main/java/me/kavishdevar/aln/StartupReceiver.kt b/android/app/src/main/java/me/kavishdevar/aln/StartupReceiver.kt deleted file mode 100644 index 9cfe896..0000000 --- a/android/app/src/main/java/me/kavishdevar/aln/StartupReceiver.kt +++ /dev/null @@ -1,74 +0,0 @@ -package me.kavishdevar.aln - -import android.annotation.SuppressLint -import android.bluetooth.BluetoothAdapter -import android.bluetooth.BluetoothDevice -import android.bluetooth.BluetoothProfile -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.os.ParcelUuid - -class StartupReceiver : BroadcastReceiver() { - - companion object { - val PodsUUIDS: Set = setOf( - ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a"), - ParcelUuid.fromString("2a72e02b-7b99-778f-014d-ad0b7221ec74") - ) - - val btActions: Set = setOf( - BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED, - BluetoothDevice.ACTION_ACL_CONNECTED, - BluetoothDevice.ACTION_ACL_DISCONNECTED, - BluetoothDevice.ACTION_BOND_STATE_CHANGED, - BluetoothDevice.ACTION_NAME_CHANGED - ) - } - - override fun onReceive(context: Context?, intent: Intent?) { - if (intent == null || context == null) return - - intent.action?.let { action -> - if (btActions.contains(action)) { - try { - val state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR) - val device: BluetoothDevice? = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) - device?.let { - btProfileChanges(context, state, it) - } - } catch (e: NullPointerException) { - } - } - } - } - - @SuppressLint("MissingPermission") - private fun isPods(device: BluetoothDevice): Boolean { - device.uuids?.forEach { uuid -> - if (PodsUUIDS.contains(uuid)) { - return true - } - } - return false - } - - private fun startPodsService(context: Context, device: BluetoothDevice) { - if (!isPods(device)) return - val intent = Intent(context, AirPodsService::class.java).apply { - putExtra(BluetoothDevice.EXTRA_DEVICE, device) - } - context.startService(intent) - } - - private fun stopPodsService(context: Context) { - context.stopService(Intent(context, AirPodsService::class.java)) - } - - private fun btProfileChanges(context: Context, state: Int, device: BluetoothDevice) { - when (state) { - BluetoothProfile.STATE_CONNECTED -> startPodsService(context, device) - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING -> stopPodsService(context) - } - } -} \ No newline at end of file diff --git a/android/app/src/main/res/drawable/airpods.xml b/android/app/src/main/res/drawable/airpods.xml new file mode 100644 index 0000000..8f3abdc --- /dev/null +++ b/android/app/src/main/res/drawable/airpods.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file