From 9b4abc40ee96711828fc6b0b425c5ea869a5f771 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Mon, 8 Feb 2021 05:03:31 -0800 Subject: [PATCH] safari: more cleanup and commenting --- .../SafariWebExtensionHandler.swift | 21 +++++++++++++----- .../UserInterfaceState.xcuserstate | Bin 61786 -> 61421 bytes .../TabFS/TabFSService/TabFSService.swift | 14 ++++++------ .../TabFSService/TabFSServiceProtocols.swift | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift b/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift index d3b6843..fbe9538 100644 --- a/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift +++ b/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift @@ -18,23 +18,34 @@ class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling { guard message["op"] as! String == "safari_did_connect" else { return } // The XPC service is a subprocess that lives outside the macOS App Sandbox. + // (Safari extension native code, including this file, has to live in the sandbox.) // It can do forbidden things like spawn tabfs filesystem and set up WebSocket server. + // We only use one native message to bootstrap the XPC service, then do all communications + // to that service (which in turn talks to tabfs.c) over WebSocket instead. + // (Safari makes doing native messaging quite painful, so we try to avoid it. + // It forces the browser to pop to front if you message Safari in the obvious way, + // for instance: https://developer.apple.com/forums/thread/122232 + // And with the WebSocket, the XPC service can talk straight to background.js, whereas + // native messaging would require us here to sit in the middle.) + let connection = NSXPCConnection(serviceName: "com.rsnous.TabFSService") connection.remoteObjectInterface = NSXPCInterface(with: TabFSServiceProtocol.self) connection.resume() let service = connection.remoteObjectProxyWithErrorHandler { error in - os_log(.default, "Received error: %{public}@", error as! CVarArg) + os_log(.default, "Received error: %{public}@", error as CVarArg) } as? TabFSServiceProtocol - // need this one XPC call to actually initialize the service - service?.upperCaseString("hello XPC") { response in - os_log(.default, "Response from XPC service: %{public}@", response) + // Need this one XPC call to actually initialize the service. + service?.start() { + os_log(.default, "Response from XPC service") // FIXME: report port back? let response = NSExtensionItem() - response.userInfo = [ "message": [ "aResponse to": "moop" ] ] + response.userInfo = [ "message": "alive" ] + // This response (over native messaging) prompts background.js to + // connect to the WebSocket server that the XPC service should now be running. context.completeRequest(returningItems: [response]) { (what) in print(what) } diff --git a/extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstate b/extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstate index 78ca2358b1a2db9c12716c0d970348c6b0b25b1e..7b7b1d3434926613cd0b1d6d1e644e594946fde1 100644 GIT binary patch delta 25616 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 delta 25542 zcmaHT2V4}#`#!rnyLY#p4vO^NrT3121yF1#y@-g2h@jNFu_g9$)>yG)SM0GHdyTzo z)M)HoV{HG~JI<1P|35#UJ79Nb_I>7k-ZJmZ_~a&WuNSG3B z2y4QI2qc1tU?PMFCBlesB7%q{qKG)61JRM_M5Ga2i3}o>$Re_d93qz}Ci)R2M1P`` zC|43Sgo+qNj3LGn6NyR0RAL%2i};0@M{FcE5u1rE#8zS(v7Pvp*g@_ZljC1iiHlpH_~A?wNEP=-(eW_xqA5}v2r-oA1R1H;2 z)ltK!;nZkq3^kFOMg2m}rj}4ksb$nkYAtnuI!GO&4pT>{qtr3#ICa8;I!QgG9#M~} zC)88w8TFicLA|72QLm{t)LZo=;HxZ<70QZb{bU1VWwHv{VA&YiSlKw)c-aKmMA;joeahCHI#H$OGj;N_nt6L>?*+lZVSA zsZSw2Osmd}vSmams@ zkT=UW$~Vb3%eTn4%D2h4%Xi5S$Pda-%1_Bp%g@Ol${)!e%b&=f%Ad)f%U{S}%3sOf z$v?}#C}aw`La9(#DXbMX3R{Jp!d~H^a8x)coE7d0Uqz@QOcAB%uIQoYsYqA!QuJ12 zC^8jUifl!`qMxEfQK1;Ds8ozqj8lwPOi)ZzOj1l%Oi`#6Qx!86^A!sejfy743dKsr zUd2Aee#LK!1B!!+LyE(SBZ{MnlZx|->xvtS*Gk13#aqQY#ovneihmRz6dx6zXpENA zBCSsw(`{*gI)DzLL+MC5ijJe>=_I;6olK|DX>?b*A6-KCr%UMpbQwL6E~f|474#6g zfgVARq{q_}=;`zfdNsX`^j%nSIQD<~Qa5bA&m~{LY+VE-{yxKbYIh9p*0cn0dkyEMQ5NVr8tHRj@S6uq-RG zrfeJ5l67RASZCIoZObOGiEI+vp6$SPWIM6RYzmvoc4d3BxojTWk1b&<*um@=b}T!N z9nVf+C$f{+$?OzXsb*)e^Vr4g5_UDahF!~UVYjj;*;DLk_ILISdzL-No@Xzx7ul=q zZT1d(mwm`SVqdYZ*^lfe&X6i{@gu zo?JTDi|fs0aG6{dm(AsHxm+RFpBuzgD7jj$j;rTJa-+C$+$3%?H;em)o6XJVmT>F2 z4O}y~k=w-m%I)Beb0@fy+$ruf_d9onJIh_>u5eemYuqjF9`}%Y#J%8Na<91e+$Zic zZ@?S!M!Yd^!khADygA>BZ^K*jHoPtG$h-3%yeIF&NANLxEU!%96ZwvOC%!Y^h0owK z`7A!0&*%H_MSM9wh_B!W^F#SszK$Qo|HS{ykLJhl6ZpyeY<@n!fM3in@Svz1H>|Mpja*r5-Y^PVx?Fm4iTX^ zOdKwb5XXtr#TnvEahCXtI9r?}F7+0diOae{_^{@7Z7N7`6=IK?ciI{dn6>(}Ll?zG)d|%V)p1px+RZUE zWidViABm5`e^Q-P{jNHvIli;uy_>IwKb>;yicS5iUYfWgImiVFvIOBzs6I8=2? zHCJ^y>ql|U=uOv~fltP#s4qHN5esp(`n;o^Qrpcmd^$csbw+hob^1RrJS&D2_Zch_ zEw98LNUv1QlHQ<`V!r0m1?f_^uDN;b(yri(@g?|Dd>OtR3E70Nz*pj{@YVPld@WXj zmEh~}^;jOh9&c7Ja9V15Nu)$0)n$=a=^1`$`IjxGsIjULb%J{bz603A$}1%p}MP@ zt8VS;nsP?d-*vsc%kUfcP5c)A2YwsBgWpyC2{8_0UJ&a7v1*9TgxE4w*d_cv{ullL ze~4swgg?fg;M4GD_;dUP{t|zMzsBFFSGcZKo>4tly-?kQ7z;5*^%P?Cd3-2djoQ@U zwfH;yZ@d9lA{id5?rUf;S1ZIPy}gU@&-fQYPxY7Tf$HHm8hod}|G%0DMx&-jDu=In zI*TtxFI|DJCiJm9)g{#vm7azsgb`t^wpnOGE+kC!W~1Lsg9tM{fiTDNh}QV(9?5B* zdASvZz0uD>h5d5}7grUk^ift&5>A9O;X=3)ZmO56SE|>lH>$U)cdEZt?^XXa5gvNZdJcNdL|ej#@YQo5{8b-R zrYcwT`2sN#VwB1iVzTBv1^!qZ5v{kkk%&=!RE24Viip?SyO?N4BuF3CC)H=oCrtDf zNu4OkM5>-iBas3zy+)!l#4xq~a7S~Z8_`qGWFgU==m9YtV#GosU2iqSfO?C!brO|s z7iFzAU9pv}qdcNeYLQPAKuiuX#X`N+M7k;zwNZI>>r>XhpdzcFEWff8nP|tt0Y!uR zW{V!`$(=3K%Tx5t{+Eps1Bfzps)s3h_ds>BM{DK3C`AmypAmzJO8g};h!~2$ftbGP zImFB%#%ma*4>7YJDMi#0by`Y6%miY>ccda9A{8-=7*33Umsp#@c^wiXdxLfPPz{zStf$}VEM#3Xb>H@@?UCW$i(h({BbAXtm_FEMu%0zvgh{uQ%5|@rc%(;;`2{9LmORb4B#CeGs zXC*G7w;}N_NL+GLg{p0SHdLC}?S8H$ldhlZ#4RnAZfdCHDN*TyL?t(s*S|>gA4fyn zL#+6Vcz{^(h9) z=Q|rH&wleaK%r$sP|Gj@17Lv|0Sti=Fa{>T6qo^X&-BqH^Kb`l>tNPGZE5+6FM zLjR*)eQ~s1lx>TvvDNk48Fba~1EgvAk&5^Mk|cg~{7(nz6@zmJ4en9l?4o0e@@q^2 zy+H=Z1X=h?^jj`KRyY)5*$~Tt80r|sB=lz%#D;tqlt2L})KMh^VqL$Z3g{<|NeSo= zO2Gh#b%Pj!mkzOBU-<&cB?`zO)?MO&`ng~0d`;Q`ss7*04O+01nm7^PL0rVDigVt0sa{VU)>5Ap(RnK`kKGL=LDce=>eDsCV|Od z3dC}u%#el^dGtbv^;Jg(RO`%j)l46!nZ4V2hc z4zWszRjES)mm4DAvk2@4d%#|Z4T4w�INtX1D@y2pm@11r_`|41kmPGjJOGje5T_$HFnT05!G z`hSvx*aV%mPyXuvr~l~x<4JR5?<5K<6I<+^Y=gK>T4E=p55y*^=4!r>wX-eakq)F2 zvUL*0g(;1sGsM&y-%q-eUXrQyAU%%PR z|1oKuA%C@FGLnqK^2iwcB^gJ?lgJy*f!Jb|9>iv87_by#iy*e-J2NH|$s~yZ(GnU& z;$Oa_0GW&^K&FtXBnlO?AvOUOV(tbWWJUV3z5C1g!lVquVlWK1`E~4!gK#keXF(p{}=+P*5Y2TjeUJk>`PD&jI{Y?2c%j% z0PA&3nL{o`c0kT0=aKWt1!N<+kX%GACYL~LBg8gAY%|2RKx`|-wn1z=#D0a?jwW(h ziyf>aSCOmr9LTj0+o`jIy%0MHu|tv{I;=B<=EDUZSQ7cGWCuGSwo7LRyCpl=L++J6 z5Zev0J=$+%2?nBEC*oo9sALOAAhxfOMDwftk}YJAr^qviMBpZ<$iZ^?H`9kI?q?9}(f`X~|W6Zx6^0eF*KStnkY*xMJQX!jD{UkVdI^i4u1;sj+sN^*<Y3aXq*%mucd+dV>^~uNcB=bZRh8iN#&tj zfXbq>sT?X7VviyA1Y$_f&lXepQ~_p9^??}Tz#A1x5#Fg&6QWv`QiG%>1E?};AXN^r z7Z7_1u~!g#tzMBZg{h~MC{>_P41KFkNVL-*L5-6BM&au3Mhb?4$a0qJ_;IYQcY= zYD7;VhyPi6>Wi97GL@m~3)MueXm(2~!f=Z~^|bc(!oR9i%?I0e)>g{Y79BUo55<(& zbZjNI3i}N^hMmQ3V1HuwQ4015dxAZ~-s1YWBkqj5;_i4Fo`V(P3@ufQv0a=2qexza14Tz5G5_( z3ncX*i9?c5U+nZkd5XHG=emkIP5n-tq0Un0sPohX>LPWCx=dZ6u0ouHI1h0F;v&TL zA#MP1Lx>we+!*2}5J!ERt)i||H>jJ`E$R>IHg$)(OZ`dRqwZ6GLEIeTUm)=s5+5KC zAuxf!4T2O1sv%em!Da}ylafOXm!|p6eN%ek%6BqO&vmV6O#My0$6r$)$V%!H^_luY zJeFZHTt>)%j0ERoGMQYaAco2q84K}N5Vt`72Dg-=8Ey@6TZr3BvpC!l;?59vg}6J! zJ*6}c_lCF+#L+Cx4B`P04??e!@iIXs%JgLhGDD@zNM_CqaBN#2X>L5aLLbJrLgu@!uhS z8{*F){#oVu-E2+fq={R2>uk}#PjUak5HByUZt7k=t<=}M2;btn%w79f8};WdD~-RV z>9V%k%U0RqNX>lkRxd_PbdCA0VSx4t8};*Uq3S7J>%Y4ds=Z~Ww&}L>yUS79%MPf; z*6%LIYcD%#I(pOn`;OXcZ@Fl0?e6jYtrYDoH+6E)@b5b7s=e%i;Do9#^&I#eq;%~q zuWZp--MOcwx;CBtu3?t;Zd=W(&ZXCX*HD`R;lA0Ti`3AzPlZ>f+>%0RRKFkazS%BYkfr`05@k`0j!l~v1XWVNz7S-lL= zAQa+Z5D$lV1jHjD9tH7eh{r%Ywn?T!6*^R-!$!$Q%0}rq$bN=+94gUCMY=kOw}W^B z3LSW&CUh9erlQaxn+9>+Y+5!`-I(d3Y?Lk5cyk%@U2=#gEtD;hErob{hIq(y(K&uEqH#H z@SK5o&z4XqJFjlr-y%?UO?F++1WDs%7ZtA31TV3TPO#guKeb>{)I(r1zlAQf&3Lm+ z*(2E-N$|(AC$guqXR_zA7qXYKSF+a-&xUvo#B(8@2l0G}7eKra;(Z`q)FgZRRqhW` zwM+IH;(fo9yC2FPkk};TMwMpDZeh!?j=E$5LIOw~_v1*M7HTqB&^Oe0)>B%Hi8 z%Cqp&|0qJA>C^&AZY_63BFk;$wsJeUz1%_WD0h-O%UvK|2JwLqFNgRbh*v;-FvKe% zUIp#FKbL8ISUOfl7FT{r$expte$}lCFYqc^*N-`tjRqJGqm1K6c(PjoZK|08j zwc>Zuh+l_@M4pw1gz`i*xJr3fdAA>EBJU|r|M5bGJoCp3Ir4rIxLkRjJYQZQFO>I@ z7s>m|iy;mnJ`Cc>_l|)0NQjSu_)ic=1~9rwUZMl1oqfs?_Ax3~vBfT0s*m_MEjFcu zO$G6>I&8xw7Fo#0$j58ZpcyS<%6NoEj(jmPiwWweJ{HQU@@YScI#WLD#|v}h(u_eq zS3XZZU%o)zC|@XFBws9F0`VyjS3`U%#E~^lhxiPL&xH6ai2u?gU-mEA*Ft>uSH0*& zpQrL{-dEs}yf_yZp?LFwV;wvD&vPpjHD-0j`J;blSAinAw3=-mNBzmpYs^GPR;tj-C>rniS=w+m$|ULhz%g}%Z-VF>YNh;M}W zCWvo__!fw7h4?mzZ-@A=O$y@{(Je=5>7!@^@g3h}*VeA_UCqz?BWrd+qAL)Roh_m( zJP>=@wDwa3YUK^k$h%uIg|-?~K=lV?3W{(=#1Esah*orvM2%6zD&iFJigtRkl~rncSo2py&$mV_Hcy4)X+>Buc}4 zQa8OElwTNIR!|tfq0|vG$dN=x{_MC;^a70|N*N&26+9LF6=hl&12iyBA%~_XX#{g)W@rIYF?;Vq7`$oM$B6h zI}jhy*!`hy7--RZm146b=W4|o#ahKW#d^gCMYCd~0%`va#P34)rxsc5)&EG6P=i+G%UEFxU7{6P5k5#e}?2D&}bls z=q9lsLvd5_Koabh;t$1b#T~_6#h;3Miu(#A#tVqQg!n6nzlNy3g1?3MJBa@c@%K%N zhyM}`J@?Ol1pBBJ?6V};7l?mo5sbz)&W%>ktVS}L(Ma}5lFU~l8KvPTZ9p6Tz)#wQ zwnGU${+c$U&55C8C2c{s0q1Bd;xTPQ+oC*~(1QfBP87N}KmtI5k`iMAO%H=1K|_LF zMcdO3v?J|AJJT+-EA2+R(;l=Z?F9)Q64sFLgG2%((jid-T?q(@sgPI-iEWTL0f|3; z$Z=^uP4+}!*Nw+JUUVPkm6qt8JB+lP$%s}jQT}P=kMOzMSGc3M-55K>_%rJjnm!f9&}GSo$f{V zrZebFItvm4Bt%H)L&5+OhLA9VgfS#cAYs}>=V(g=bb+=+K=*}&Sxbq4X!W&3Kv*_E z9}<8?4MsYrDXVMELsI%x_=-KofdM-VWo=-2J8zEr>30p|m zLBbvq4v=t!gcBs3A>qLGG14kZ_mEWSVaj|HKw&LGPyzNO*sPgl8jt5E5RRf-!xRMr()?-s2j)-pJL_ zr;w{7+N!PUELxqTFKW@EN)AHn``v9c8kzKU`o0AA27QyhMgKwHrti>q=|Aavkno2@ z03-q-5d;Zj3L%g{orXaoyovs+1?*$cEai>#b4Wz!z@l1Bl_qZ_;x%9mP&KQO{sf80 z7O;$-WXcANj8Pyw3=%53kwJzQgYYep7PE|5FTq{TG%+ifmCPz;HM53U%dCS$e@GzE10YcbiGh$Phr}RA zR6t^I6SJWO?q>7EUIny999TGDjF%uHAAn^+%WFE32GHPgdNIO zvo&ljTgTS34Ukv{(e@Og2@)$Hfda@XNUVm$8c3{dVpT0rM`&Fxie4{jJdGZ?i^!+t~dQsO{{p><)G(yNlh;?qT<``yher>Q_kY zfW%Hn?1E^Q41t0higNp!*xy<}9d6MdvLjTV)dtN&U-frPYk}+~3Djjs{H6nS4e5`) z&fbtdkT?Jd6cwd!WPu)Hm`;m-viBv>D54#1WdDN15iRJ)>@%$vQN zE=+@3nvr~cu=7;&j99J{Le0f-@mxDDflK6)xb|EJt|KIFL*fo3?n2^ENT9L44+%8Z z4U>B%)}ijB$rrd%4w+RWhkW_dMh^M% zXIf~3xglC;RT^l|C5fvw&|aupO|@vM<9 zo`D_&7z6~`N;1@d+stj1WZeP*-Uu4Cdr2H)c5=U=eI(p2Za24w+sp0a_Co+5AR(Y2 zkU=1aK!Ns=a0m4qxWn8L?LHDfqu>S@2n3`6w2x$ry2}h>!*gimkvq>_;4VUd7D+e= zc(j+qE$BLTH5wFjC}0|x5rGs5*Bb5EsbpFm*L$UTF= zSnW2`&-FF;R=WBI0@FtB9Rz3-^>=d;?xVH`vuv@wW_GiGrdf|KJTkfEydID7I8X3^ zCwYoT09!${hYMIh&;|la2&^EmhQMYyui$B(;aQ&Jd0ybrf{QH#b`aP@-~fRm1WpjR zK;WwOnKhSdjXhkT`bASF<}KCNW(8Q-@%BGp=AC#KBr)#{fwS84m&op3y!Vd}`0_zW zrMw^S&j;{<5V%9&34u2RK8yKaK73tQ(O6H8I!0zAxWjYG2Iv<4Yhw zSi&KQklGL6%cS;^5JYR*S4!=xAc)enuT~$MYj0oAL#cfOujEw_#6l1ULA=y{I6p#a z-wuKV)ZRgTbdHTWeO^Sju~I+dAV}2pGf{8bg0Cx{{1krr|G>k~;Air)AZQOkM+lNt zo?4|!#>vlxpo9AHyikKispo|dbkg;_L>)Ze-nEHGM%l=(fFQMzUj;#zA9b`|JE)zr z#W>BN-s(jMwwOA4gMe-po%-@S6%`K7 z7Oi{cmlde18^auKN;05z(7dl+i@(F))e>8?5X;}^|59TMt;t3F1OB1mbMl#SeBRumV~H{ce>;5Cwhhg;b4h1!L^tV!=c( z70d*42nIn=0l{DhD%Fn`W%RNZY<_HQFF0r~bg%VxxAv}Y8A`!LK%2}L3a)}11T_%U zEfhQiWWNm%O!^6A3`t;g5eO1fM6s9qagUHNoc2yltO!Lq!f}N__-xgg0Z?t2_|Xt1ECjE zoq&ijx+PKyStvgcvau7=2ZAvuKajpqeqgA>*hlD#f~bI0G_FxVDjF{ZQFEbG7>I(T zFaTwMU;>Jx3x#sD(*{gb?`pDaHAJYjG~?(6;sh|G_}qWRKgeuDHMhY z!-WyTNMV%llkl@J8Ui&0Qz4iJ!E^{_Krj;mWS74{FuO?@t3@i?D@+n5>p2MM(K#(h z(UKY3E(sP$0jg00HC>o5L0td=0;5&=A_?kZ1QmTCm?uF+UkK_>yQsF> zIxPaUjR_%GC?VJ&Ay}mTXQhR5i-1hGB}xn1Ay|Uctz8ckb_$0iY`cWr!X9C-uus@8 z{3aX_4nnXLf@KgahoA`prDMJBevyH-a2-fK!-fAfs%k2wv;ye%@Yk@q{0NIF=83C>Iw})Vp+H8%5(<=cP zW}|>iaZ97{7J_X*68D3ap zo9gfx3hhu4-KZ5YXd8dah7r+I^io@`YfX5IZPnrHg7tkxe@O&C2o5!h0TAtmMIvNq zMF^2ZKm<7QzeLa%QFzwAe-{Kt(fjfK==~vL99}9~sSdYjLrf5pkTHpg5FBq5kq%C% zvGtb96tS0{$qF%5>@0Q>)5NY~H?h0eL+mLcTAzXdk>Pg;&OmS$f^!g@hu{JP7a_Q` zLhLPONLC?ci#cMhm?!4zIYV$6f-90?Ky=s(T!R2HH z_qf95dFu@@hoNE}3JYSjSR>X#@CO99A-Jhl}QI*!!awnQ8y z{v`e^juyv2@FxV1AwcSV1;N{|u~r-}PL?{HAWjq~L2wU(`w;xKNSq?7MP%X+Ab1GD zBlV=_MHzF&#{cmoWhX8|uSR7R@C3bD<=NS~TTEqfe;u{OCUN!uXeO=^*NW>Pcn-k} z2wtiuZnOy8ETSDh{}BbO5qF3?r7h9`(f^IgGhffz0oSwEQe`jN%yfI>YLkvQrqkYU z;xUvqBSZ(qL*gXyhm3AtBWMu3hv1*3;uOqUJSm>StTAf@QU(9{iWXC6(Tw}26ANtzk+y-7CdaE#ScgVX(wWqv0%jtDl@ORSuvB(~urbPeoPn1@uCCG2KM3M5m$G(HH5b^aqAUN1J&@WDFQ1 zbiCON6@;+QcosXGoy($v1-l3xC0@pESF$JAKiJot9Gwt$<080@Tqkq}xQr|3D!58+ z2v>~`{?>C!4sye}ndr#x9Bv+mreEA*G}Bs+=2NTCjOsY|7|k9$`6xaIWucAejO`6{ ziuNtaP5wc7$!Bz$mJv8~fL0$Jp*2S7grkrs6r+GPLs%my*P_#|yHO1IO*kkV7OrRx zxIPdb39p4Oq8uG(bwEd1L&Z2T37LB#I>K6vj<1%YqpRiU*y=EJRCN@xurcVs>I6i# zDdG}Dx~KXE`d<2J`qlcw^oQ$@)SsX~SAVhoD*e^^oAtNoZ`0qWe@OqK{yPKQ02ok8 z1Gxchz#5num>aY!5o8m28{-b43-#dFlaW|Xt3E}zrjI+ z!v@C;P8ggrxMpzO;D*61gLj6&(Adz_(A==KVH-m$LmNXoLkGhE!yv;D!!W}L!zjZT z!#KlshKYuQ45u6ZYIw(pGIBFYHYzuoXrx?gw8QAU(M6-nMpuol8{IVe!|0CDpGNnM z9vD3`dSXl&%Z+Jc)|fXIjSY;Aj7^Nqj9VF77+V@!8~Yh|G|n-uF`j0;&iJ_TBjbNe zcoRDlACpj%Fp~(A1d~oCT}*nLWSC@`qF;|;U zGhb)E(|nKlKJx?Shs=+d-!*^Iif+ZC1L84lIinus-so1 zRjSgei&a;v?pFC$g;qsY#a1O&rB-ED%-Q^tWQ{cBk!2 zJ7YT+J3qS~c7=9B?Z(*6vfE*I+wLEG(LU5Z)jrcc$3D-#(7wpN*uLI=l>J!y@%9t# zC)>}nUt+(^zR7;2{RaDu_M7du+Hbc%Y=7SVFZ-AF9~|Tkf`h(;p@Xr5h0?*&!P>#r z!QLUjA=06vLykj*L#0E5!x)E&4znGWIy5_MblBvu#o@TaO^2tBm}479D@PkgJ4Xjc zC&zThJjW8pQpYmKa>okCO2=W2;~mwG(;R0w&T?GtxZd%!<9Wx|PM8znL^{cwES;>K zJe<6o+B*3gc4bbb?MZomM;TbvoyC-|2-j<=o2I!r9W<+S%6G-r3RF z%NaV4abE1a()ob%Rp+}df{T$$q)Vbp2bWGRDJ~f}v1o=<4F??&{_0qjdFm4RQ@} z?d>|mb++qj*JG|XT_3qA+!!~`O>on9GjcO^Gk3FaYwPCg=I<8h7VH-47U$N%t&>}d zTW7a4w;Z=Tw*t35ZWV5oZbRIv-A1|n>^8=2oZA$)`EHGFi`LB3+~45t=zrc!`+ps?p@rwx_5W)>E6pd!#&GA$34%z(tU_~wR^35y}QzV znEOcgpWMf|k8^KwKkWY4gZJ?9=;=}CG23Ii$9|849)~@SdYtvR=5fR0md9<6yB_yE z{_=R}@y_EPk58U@o`fgqY3u3b>E{{f8R8k~8RHq}+0L_@XRc>~XQ^kIXPwd$dXDh? z$#b0N1kcHyYR_4o%RMi7-uHa&CG%pv?7ZT<61#dyNJ=uGz_YCh}yyto^@LuG-*?XJ!uiiVocYE*i zKHz=G`-t~(?~~q-+R|-3+orZ1-1e8YyV_oF`_YH=k^3+{oR5i*m5;5DgO9V1n~#T& zmrq-t2%l)5IG+Tc_C6hbihZhlYJD1fpwB3u(LQ5+#{10ineVgQXOqu%pPfE?d=4mm z4*4AQIqq}S=cCUTU(6Ty%6w^G&R6s`^mX=i^Y!%g_Vw}g^9}cn^G)z=@7u{Y#W%w@ z+c(!Y-*>3*NZ+4*$M}x(o#i{ncb@M8-=)6IzMFlw`fm5r_p|h~_OtbK@bmGD_e=Ea z;Fs*z*{`c#55Hc1nSMEb6@FEIL;Y&}ly!bezhQnO{eJQr<2TN)$?ve=V}IV?$G@k4 zo&RkA?f(1y5BeYRKjweV|GNJz|2zKo{2%x~@_*w0%>SeRmjFC~43G!V0Zsva0l@)b z0g(Z50SN&~0UZK*1!M;F3FsS88Bh~YAD{{t8SqoUn1FEsvjdg{91J)Ta6I5tz?p#a z%79A&R|9SYyb5?5@IK%}z^8yOf$~88K%+p@z*d260<8kw1HA&<2Koke3``Hq2+Ru1 z2^R#YXjE@HU}|5Wk0) z-XVQMibMK^^be^FSsQXVekf$LpLSBcw3;8GHQ>b33aj02n>(Dl#R-rbbuAyy1 z{gk1Bp&_ARp-G_~Lz6>OLkEP`hBkz%LWhM;44o1>HFSFDoY1DwRiSG_*M*5;ZNjX= zY{Klr+J?o2C4{vP>lBt6mKN4MEIlkEEIVvaSY_Cdu{ z40{;PhI@y153dQI6}~lmZ}@NFhr*A9p9#MjuDlU`EBsFQpW*kzAB4XRe;@ua{7VEL z0U~T7JR^J~0wRJVA|j$9Vk6=sx<>SfD2OPI=pRuQF*u?sqB^2BVob!!h&2)GBbp;N zM{JAO5wSaBU&O_TD-qWtZbtkOaVO$&#H)z65$_{DMtqKBBKb)DNW(~!Q~zau|HIY)Jg>J?QR)exnM8Xh$&YIM}N zsEJWiqLxLih*}-BHfnuTbJUKg{ZR*_jzk@gIvI5}>PFP9sN2yXT0hz-+9cX6+BG^b zIwU$QIwCqQx^r~b=6hK}K4#2C96 z#~9}r*BJL0uNa>g|Cqp-keINT^q8SBb7FSI+>VvUy2o~i?H5}STNPU!TN^tfc6{ul zSat05*jcf&W9P=sk6jhJHg-eorr52q+hZ@r-i>__`#APl?CaQfvF~F)#L;nFoJpKn zoI{*zoQE>bJI+5YFfJr6EUrUbZd|{((zt9!)|37ZnOBy3OEk#H>G zT*Bjo7m13**2+ZZ#I}ikiGhhBiQ$Ru5|a`;CMG9#PE1S8NbHkXo;W&jdgA=Vg^5cN zmnW`F+?cpIackoC#2tyd60aq`PqIkzPl`#3PfASckklzDB`H5?U{Xa=RZ?|QT~b5R zl%&~73z8NkElpaUv?*yv(ypXEN&AwHBppvWne=Yi<1W?*C$U(RwqwSo|QZ&d4BT3umar;^VkpHIG&d?oos3ZK$C#V4gOWk|}@l%*+qQ%(4NeV9jZBS6jZaNXZJ#%`MF{t!-LXT5eiFT2WfRw9>SJX%%TzY1L_UY09)=Y08mlKc|gNn~*j+ zZED(#v|rNZrp-@Vm9{2rU0QS6qqM)%{z?0o_ND9cuA91U>AJ1!j&5TcWpdiRIjA9sJ+{Y8&uJvR2(++%BxUwfAKZ0M=#IjrZ%^w9Lg^!Di; z(^JyNq|Zp7l|DOtUay2+U3+!!)w5S`Wv@}a)V-$ln$hc*-l@GaduR8~?Oo7&Qt!FF z=l5>xy}0*>40#5f!Da{;c*3*@Lr(WLIa`WjAEc&fcDVBS$aC zKBs-ofSmC;t8zBwY|Z&KXJ^jAoKrc!=bX(sugtlab2;Z;&i$OfavtWq%6XHE=gM;F zTrSrj*C^LC*F4ub*FQHgw?l4nZs**txjk}w5~M zbndv^3ArnCkLEtj6Z8D?dgV3b&CT19cOdU@-m$zBc^C3-=KYa(C-2X^`*{!YUgmwt z2l=vmC7mzi>*pKgo8&v>JLmi7C+2s^PtNb0-!;ESey{w@{G9y!{Hpxw{M!8bd}Th& zACdo4{^QV0rVg><1%Xi#WeXjR{-mcng?I|_FdUM>8mk7b{zJ_UWo z^jXvAM4!if-t_sq&xbyril`!?NWaLi$hgR~$h^q0$gRk;sBKX|QE*XMQAAOvqST_y zqO79qqTC|ofTFUZfklIgltojDrWMUBnq4%nsIh2q(XyfyMXQVU6zwlMP;{v1NYSyP zlSQYC&J>+5x>)qOuVLT7zUh7I`!4ExsPDaEvY0Q{FE%PRDYhzhE_N&SDE2P)DfTN4 zD2^>oEbdU8T%1UA(Tixp;H& zw<(r;2|sK3jag_+s&u;_JmXi*Fa-?T7WV?ibguProt!*7ZBr?^TIGN$V2J5}Ojc z6894SlE9MSlF*XylE{*nl9ZCJB|S=dm1LLXl@yi~l~k2fmy9ZzRWhe!e#yd;B_+#C zR+g+OSzofTR9Sk+P2iU)W0;aG`O@~X@}C}($1ybOVdj;O0!B!OKVDNOY2G-O2?MY zD{U-YT)M1uMd|9&b*0Uvn@hKq9xpvr`g`fw((|R4O0SmQD7{sBr}R(d0DOSWfcODL z1I7+mKj8d;*JXxf7G+jtwq^EZ9%TV#L1iIjVPz3zQDsSG-OGBHWtHWY^(pIHR#H}4 zR#&Dh8&@{JY+>1wvgKtf%hr^wFWXqQrEGiIiL%pWXUfi%T`0R$cD3wA*{!lWWq%ID z2igpbA6PVS?7;N{&kuZEZdh(nuCyw*Ew?ZCC=VzPDi0|SD~~9TDo-l!Se{;58)z=PNE&T&cKL@qVz`;IP42gNF@XKKS_HN0oG?VWml>d1dQL`$~^WugbQSzLox! zft7KUNtGQdQ!2Yw_NeStnNe9%Ikd96vZhj5S2?&nsV5zO8&;`LXg#6T%VxAt^&LhGY%N8InI_^N{^R4h%UoSNl}^RR>fDSBF(cR!3LIRky3o zuO3#twEA%M;~ImSfSPVKgKO$*R5inEM%GNInNc&VW_Hcon)x-2HEU|t*KDlWQnS5g zN6qD$do_=0p4Pmmd0X?o=3~w0TCTQLtyQgUtwXJAtRx;D8sx3-|RsJ35i zY3;z;irT8$>e{;6iM3N|r`Ardomo4(c3$m*+J&`CYM0giR(q#TR_9XJsji}KM&0JR z^L01s{;0cKcdzbQ-QRT|>OR+F^`M@rm)9HDo7K0jx2(6Rx2un;?^NHVzFU3I`po+5 z`n>vr`ilB0W&QB_pXJ&Es|{b2mdbEtJ7toxqcU09Lz$z@ zQx+)uDElh=DTgR)l=VuLa=3D&a-njqa-(vKa=UW3Qn^ogKzT@cL3vquPx(msRQW>r zR{37}QTbWLq5m<@L*=dVRRySmRbi?~Rg5ZLm8j~i%2MT^a(aQPNYzi(Uo}8guBuQ? zQmsY*tK1uC4kKYc90nWV3b-2nzZ%Z`J8A-f;}i-Nv`~6b83v2;NZ z4-gj-WaYFViX6kFnPk$;q?u$gnItolOfqSiNz+U+Nx20q6bhYih=3pqiUq{72#T^C zb@%PQ{pI^U@AEf&-Z$wqoO_&yoJX9;oN4Dt=V|9<=l9NL=MCpi&RakypwI#I0{Q~a z0E2;{zzCoSm<-GU<^Zn)^MM7xB49DF1SkU>00B@y5a56a5CvjDHIM*Q-~dn$90ra6 zjX)D{0yqtv0nP#60Kb(NloyvTD0h_0<&EVxz$`Ea%mcfD-NF9gP;dk|3VaS63yue; zg44lSU@7RB3%(An1-F0z=mOoK7sNplq`(-cgLU98a4&ceJOmyA8^QBnGk70-2)4R1 zT$!#cS0`7tE60`R8sr+{8s-||Dsqi+z2F+}n&6t`Dse4zZF2FhgRW-iNvH@ag;qfu zppDRGXe$ImI7C7Lh=D>-1QHyO2x*W3Sc(AO%Qwq$kn` z>5mLRUP5LguOV+BZz1m@e?yiaOOf@+rwE83hzF@e{0NP(NC;7ooyc*-MouATkaNfd zFIMC_n zEVLAzgT9Tvk1j<&L_b1TqN~wO=vLH;f+&n4Xcd}5ccOdHFVK3l0c}K&qZiQYXbXB9 zy^H>iK0qI%e|S23dU{5BMth$3jPp$JO!B%Hv#-rMZG z;k}7vVfon8STC$EHV_+(4aJ6IFJhCiS=b!xb!aoMv5v&nw!cJhPu&=PQ*m>-pqcXp8eC0cpTPtIgM=P)69q=xAE?$5a z;{EU;_;9=kAA`SukHd@c7xC%%EW8w-i_gR79ZmHE!a&@V)qc z{1AQwKZZBq7x5eTL%h|O;mh=8`8xTseL227UpLC%XIfi_me1)7tE+LnZeVlAcG`JhDm`G$rxEp#>ob<+27GW%>P&aCw|7i(|^u?#eda*&40sx$N#|p z$lpq}q1sZJR97mWDx`W)y{W#`L}~_AO3kI_QEyWVsrRVG)LLpCwT*I7ZVIJvilhQm zkgBFkY6rEO+D9FrzNAi2j#JcE)Y-twz{bGVfHMFFkN_IM0(hV%uscv6Xb2n)91ENa zTnJnWTnStaGzabm9tK+J3_6p}qI2k6x`6IZ_oRE%#q?}?9qpkRIz;odNXv9JT~D8+ zFVR=%tMoPcN4kZ+O+TXl2(}Go2D5^lg4w|?!5)s_py0&d{NR=#9jpp!!MfnC;NIZ= z;K5*1@Lcfw;O*eg!8^fUm^Ms1rUTQFd5Y=G^kjN7eVJ#NH<=HZ51EgcRm@tZj3Jp2 z6K84|jWHOD*})uQ8knQZake}ACw44b%uZxW*q7O<>~wY(Tgtx2zRxaYm$Qx)>}vL7 zc0KzkyOAYXo;BDsdy)Mo*M{rN6>{CV9^3$KAUBAc#{HFB$i2%g;{L|1;?{EOxDDKA z+~=H!OK>~5o!l;N4|kM1#hu~KaTmBt+%@h;u7$hJ-Q|7_WrW&=+J~M9y&3u-v@End zv?8=W)D*HqCqrL3!o}ff;pyR-;o0GEI1$#vW_U+&uG59f>d zm-tusY5WX+4*wee2LBfS4!?Se<=YQt!@V^Lcge;+xkS*j0g+dRZ zx6n^`Mi?fH6h;fr3Cn~vLYeT1@Tss(a0=xDD^v>!K^2lhO0a}4g+oGv&=}2$_KpsU z4v7wr7DdNIUyM$UPKo|G`f7AWbYpaT^qkmU>?;EcXrfwJ$#L%bmVDn6FlNbRKdQm&LIxmJo@R z!jd3KQk4{!Y9viEq`M&V0oxKLLMcLk!Q+p$YnAp`(#2UWl9!hNsh@? zvMTSE_sd_(hvj2(T0SYCmM_cS$yeoTRUcNZui8-cS=FZPH@4r4KM{X2-Z|bio*yra z_lWn7_lpmRkBt|{UyM(RmpI}t$EU_$jn9bxC0-g|5wD2X#!tq7P4q}iPQ07goNy)F z2{hqN1QL8gOvDn^iFiUusEOT)eTf5!`b0zGXreiBH}QMoLE^E}R%x$fDIJyWN>Alk zWrQ+Hc}^LxOi(5%B}%EXKv}JPtgKf)RX$g?DBF~B1yUS{5>j|2sz{2gY*!SeR!J%; z#ZpcycWMf1#?>sSan{H+hib0YwA9?Lxm)vV&11EL+EIN{?X2dgxoW=JTkWe3S4XSQ ztK-y(>ST3_`ilCR`iAQ}Ru25I2Yt=0(u99j%Wz>+$tD-8a+f_yVLOtkE>(#^R z5w%fmQctL-)HCW?^_SY*+Of57)o!j8Ya42twM;Er%hB?*0F-zo(ojHdU2UQ>oPX z)aBHb)a}$Gvz^(&>}Wn^=9%5hr_EkwA9Jp`(sY@a$(SM2!JDEfo7>HVxx@UzJZK&= zkC?W3$~3PwRc1LX$U-cSRcQq*#tK=y6}2QQZq-@)tOHiP)nKKq zlh#+(S?j#@o%Mrt)B4?Nt;?v(tjntFT-UWOzpk+E>AHS(Lz=#BI^WdXbhqhV(|t$N z!=~1BMmjUyHJzXCmVP?jE8QpEFa1pV)%41AAblX+m_C)hkiL|@mcEs~Yqz(v>>NAK zF0c#jf%af~h&|jcvPat!>`8WsJ;k1B&$4IR^X(P(YJ07{&fZ{ev^U!h8?arr+pe%_ bo3S}N^1tBjKmXZ<|D~?&{wMywC!YT|Iiw5R diff --git a/extension/safari/TabFS/TabFSService/TabFSService.swift b/extension/safari/TabFS/TabFSService/TabFSService.swift index 85b29f3..86c39f8 100644 --- a/extension/safari/TabFS/TabFSService/TabFSService.swift +++ b/extension/safari/TabFS/TabFSService/TabFSService.swift @@ -67,7 +67,7 @@ class TabFSService: NSObject, TabFSServiceProtocol { let context = NWConnection.ContentContext(identifier: "context", metadata: [metaData]) conn.send(content: req, contentContext: context, completion: .contentProcessed({ err in if err != nil { - os_log(.default, "req %{public}@ error: %{public}@", String(data: req, encoding: .utf8) as! CVarArg, err!.debugDescription as CVarArg) + os_log(.default, "req %{public}@ error: %{public}@", String(data: req, encoding: .utf8)!, err!.debugDescription as CVarArg) // FIXME: ERROR } })) @@ -81,6 +81,7 @@ class TabFSService: NSObject, TabFSServiceProtocol { return } + // Send the response back to tabfs.c. self.fsInput.write(withUnsafeBytes(of: UInt32(resp.count)) { Data($0) }) self.fsInput.write(resp) read() @@ -89,15 +90,14 @@ class TabFSService: NSObject, TabFSServiceProtocol { read() } - // split new thread DispatchQueue.global(qos: .default).async { while true { - // read from them + // Blocking read from the tabfs process. let length = self.fsOutput.readData(ofLength: 4).withUnsafeBytes { $0.load(as: UInt32.self) } let req = self.fsOutput.readData(ofLength: Int(length)) - // send to other side of WEBSOCKET if let handleRequest = handleRequest { + // Send the request over the WebSocket connection to background.js in browser. handleRequest(req) } else { // FIXME: ERROR @@ -107,9 +107,9 @@ class TabFSService: NSObject, TabFSServiceProtocol { // FIXME: disable auto termination } - func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) { - let response = string.uppercased() - reply(response) + func start(withReply reply: @escaping () -> Void) { + // This XPC call is enough to just force the XPC service to be started. + reply() } } diff --git a/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift b/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift index 8aedd87..4dd6e77 100644 --- a/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift +++ b/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift @@ -8,5 +8,5 @@ import Foundation @objc public protocol TabFSServiceProtocol { - func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) + func start(withReply reply: @escaping () -> Void) }