From db4261eb7091cb6c52a1840402e1593e411e3647 Mon Sep 17 00:00:00 2001 From: BagavathiPerumal Date: Mon, 10 Nov 2025 17:25:37 +0530 Subject: [PATCH 1/7] fix-32310-Made changes to fix Android modal navigation race condition by adding PresentationCompleted event and lifecycle-aware completion tracking for non-animated modals. --- .../ModalNavigationManager.Android.cs | 36 +++++++++++----- .../TestCases.HostApp/Issues/Issue32310.cs | 42 +++++++++++++++++++ .../Tests/Issues/Issue32310.cs | 24 +++++++++++ 3 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 src/Controls/tests/TestCases.HostApp/Issues/Issue32310.cs create mode 100644 src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32310.cs diff --git a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs index e847e73e8952..41f4da4bb215 100644 --- a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs +++ b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs @@ -168,8 +168,6 @@ async Task PushModalPlatformAsync(Page modal, bool animated) async Task PresentModal(Page modal, bool animated) { - TaskCompletionSource animationCompletionSource = new(); - var parentView = GetModalParentView(); var dialogFragment = new ModalFragment(WindowMauiContext, modal) @@ -185,19 +183,32 @@ async Task PresentModal(Page modal, bool animated) if (animated) { - dialogFragment!.AnimationEnded += OnAnimationEnded; + TaskCompletionSource animationCompletionSource = new(); + + dialogFragment.AnimationEnded += OnAnimationEnded; + + void OnAnimationEnded(object? sender, EventArgs e) + { + dialogFragment.AnimationEnded -= OnAnimationEnded; + animationCompletionSource.SetResult(true); + } await animationCompletionSource.Task; } else { - animationCompletionSource.TrySetResult(true); - } + // Non-animated modals need to wait for presentation completion to prevent race conditions + TaskCompletionSource presentationCompletionSource = new(); + + dialogFragment.PresentationCompleted += OnPresentationCompleted; - void OnAnimationEnded(object? sender, EventArgs e) - { - dialogFragment!.AnimationEnded -= OnAnimationEnded; - animationCompletionSource.SetResult(true); + void OnPresentationCompleted(object? sender, EventArgs e) + { + dialogFragment.PresentationCompleted -= OnPresentationCompleted; + presentationCompletionSource.SetResult(true); + } + + await presentationCompletionSource.Task; } } @@ -209,8 +220,8 @@ internal class ModalFragment : DialogFragment static readonly ColorDrawable TransparentColorDrawable = new(AColor.Transparent); bool _pendingAnimation = true; - public event EventHandler? AnimationEnded; - + internal event EventHandler? AnimationEnded; + internal event EventHandler? PresentationCompleted; public bool IsAnimated { get; internal set; } @@ -361,6 +372,9 @@ public override void OnStart() int width = ViewGroup.LayoutParams.MatchParent; int height = ViewGroup.LayoutParams.MatchParent; dialog.Window.SetLayout(width, height); + + // Signal that the modal is fully presented and ready + PresentationCompleted?.Invoke(this, EventArgs.Empty); } public override void OnDismiss(IDialogInterface dialog) diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue32310.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue32310.cs new file mode 100644 index 000000000000..01633aa28d6a --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue32310.cs @@ -0,0 +1,42 @@ +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 32310, "App hangs if PopModalAsync is called after PushModalAsync with single await Task.Yield()", PlatformAffected.Android)] +public class Issue32310 : ContentPage +{ + public Issue32310() + { + var navigateButton = new Button + { + Text = "Perform Modal Navigation", + AutomationId = "NavigateButton", + VerticalOptions = LayoutOptions.Center, + HorizontalOptions = LayoutOptions.Center + }; + + navigateButton.Clicked += (s, e) => + { + Dispatcher.DispatchAsync(async () => + { + await Navigation.PushModalAsync(new ContentPage() { Content = new Label() { Text = "Hello!" } }, false); + + await Task.Yield(); + + await Navigation.PopModalAsync(); + }); + }; + + var layout = new VerticalStackLayout + { + Padding = new Thickness(30, 0), + Spacing = 25, + VerticalOptions = LayoutOptions.Center, + HorizontalOptions = LayoutOptions.Center, + Children = + { + navigateButton + } + }; + + Content = layout; + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32310.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32310.cs new file mode 100644 index 000000000000..5493c6a78cd7 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32310.cs @@ -0,0 +1,24 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue32310 : _IssuesUITest +{ + public Issue32310(TestDevice device) : base(device) + { + } + + public override string Issue => "App hangs if PopModalAsync is called after PushModalAsync with single await Task.Yield()"; + + [Test] + [Category(UITestCategories.Navigation)] + public void ModalNavigationShouldNotHang() + { + App.WaitForElement("NavigateButton"); + App.Tap("NavigateButton"); + App.WaitForElement("NavigateButton"); + VerifyScreenshot(); + } +} From 7d9605e88385f2c2dd9ad53c7542962fde4d5018 Mon Sep 17 00:00:00 2001 From: BagavathiPerumal Date: Mon, 10 Nov 2025 18:52:54 +0530 Subject: [PATCH 2/7] fix-32310-Added iOS and Android snapshots. --- .../android/ModalNavigationShouldNotHang.png | Bin 0 -> 10467 bytes .../ios/ModalNavigationShouldNotHang.png | Bin 0 -> 23442 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/Controls/tests/TestCases.Android.Tests/snapshots/android/ModalNavigationShouldNotHang.png create mode 100644 src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ModalNavigationShouldNotHang.png diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/ModalNavigationShouldNotHang.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/ModalNavigationShouldNotHang.png new file mode 100644 index 0000000000000000000000000000000000000000..d14e66f1b88bc982a8aad0d59ebfe9146cda5f78 GIT binary patch literal 10467 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 literal 0 HcmV?d00001 diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ModalNavigationShouldNotHang.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ModalNavigationShouldNotHang.png new file mode 100644 index 0000000000000000000000000000000000000000..6db4eb820acb2f46d571cc996c19920405134af5 GIT binary patch literal 23442 zcmeHvX;hQv+HR`5(iW9{>Q;&fv=zn55auaBbX!Hr)D~rsNo9x_AV`=(5>jQWwK53E z7zkPlRGA79!jvEmKnNrP0)`=oghXbOFhv5Ko9|ouJL{~ozO~NZZ!KhLV&1%Op7(j~ z`?{|Cx*u}qM;H4&UmW}bfk5nWIQ#w22*lq45s1&`KidJXJTLgn6CS<}IQz3R0ug@{ zf%xTL2*gKt>6iBiM6@9SF?|t%u+BjsR3q{mf3krCyDmH0e~;MQ`gy=C&45>wq8yx0 zD@`eXv0KyRHX+LxUit(V>2mH9-tVz_2!vOu!}ll8#SP7lhTQXAA&*Vrknh81*LvT4 zzT@ksdwdXgevjb~T;?plsMBlu61gum<8|D-yvGjx%{i(jvdfQ+&%0&hIem$$=Hyxm zgw9!^oGd-Z0hiz2y4?8Ni5=R%v<+Q(pt{KFQug@_v4qw8J`wRq{OIS*6C*4#w;}ts z7@xJ-5_0wGaTt|PrQ96}k5A{$>V1Mh{Nu%!2*in#+fTRWVLJ%6lVKYPwh?ig4z_7= zTN7++qitcht%|o*@wO`7R>j+@cv}^3tKw}{yse72Rq?he-d4r`f2#Q55*Y0t62n7{ z-P}ULT=0Dre*aj#Zfca6w+G&9vCC|&US$-mPuXQx-wE|e zPYvxXa138cmkd~&+;872o^*4lA)gk|4U|#As~%BHlhx0yqRbsM{W4a{Ipta2%ppcb zB}?(V)h1R?86~aOCtQraAo#9SU(i~%t2yY!m(8}jlQEQ7Kg+bD_1v7UX}On;IJqh$ zjN4qNH+@#D(910-8D9G9?QFzGFm7Y^L$gC<||rKwg0|E|1GHC@=ZGFcg9qUCs-D~c`T4(>h5 zZXs!_RIyl|jf-xcBWe1an#=RG8?$dcmt(~d{^{lU)C!ABbK$REoMXipZhpiPrp}3K zi!sM^#X)n=yqTUbQ(?azi6g#O=ZgJ1DdeN}YsPlD{mM0g%j*7pL-`G1UN$K813~SN zn~A>W`VKQ;%Ym22&ThoxHs%4ENe5u=o8=EjKUhg*ozi#+D*)d{8f4)kzl zQx-Fq5nrR*vh@94nnU{XfMS|Ed?f2=sj+F6U|d`6AW!JL`lXXoP{b37?ydH!HEhgO z>0ePU8>oRksuUl2@uMoEHgNPA>3s@mnq|{yCmY5s_4>b?bdz`C zlYgGhFSH*N3o>)ZXqmE_=&1_7`r$6Q3OUweB9(lYa3#9VfH{x7wSHJWFe4vcpVD$j zPZ=OZ4p;aw7^#lvo1zjYm!S3ENf#%~$X^sq5aygFFetHj#*DW;;LYKf`gv8R5|og;DH7tD1y257slsAtE{#@{xv zPV2eTJOpt|DAw70epvp(Hu`TDuR zGR!f`#^sIKo7(cUZZG zr9-*9lP9TF#l=>4G2&Cy@Vh!xozlp1w9c;dz=?OHP{(<1LRt3ITtL*fu2GW>0rK(g zL5bT$27fdYlQKG8OeuxbR9z09sZmHzF-C2paa^WujWq3$HTBau{$KB%?f$Xio|oga zdDeyIm@XJka%JHmRQK@lPltI0j?#U@GQpmg{>iSQS`&Hab;USczWgxBMOb}GK1&Pr z%iD7|d?`|AXOWfBz3V;NUi7cAHt2|g<@~OFzJ#df(MgGBFi`3ksnbVGZ>i; zGH|Ab6otPKPRHyR`&UUxc@A+jTX*chf8}}66LXBLx7;`9w8oS=+s)p@G7HDb(rT2| z{aW1GvpXsH>T!o)US}xr!Aw-}v8EUFbBoBm96yn*_G z$@%?^_z*;W?xDv|Q9s&a?IJNWTbc*47nSc3FI7lLB*$P^yw&9^dbX#g)H>f@8M;st z5tG%;RxJC-+nCktq!i5M_kJ6gq^S1CAprj?u^9`AUhuu)CxK};!4t4X-O#- z2?|AE8d+8IkKF$Jx`B{|{f9JpxexQze%QQ{mm#0?GS<0kUAggBUoBF&-w$n-Nozf% z-to#))YaKZ@G?cwSqtgUgy*=)B}BtgB@?U6Pv??7xU=i2;t9x`LDSm{EANhnB;Ad> zNz4kqN^NOZ?C5lm9exshQD2Si0PMNTv-=#C%q zR`-9nz;t!%9ms=2%?=9@jl5!R2kJj&)0wmGV}~yX+ZoNehGVM|i@rC(Sx9(bmc&eizNzQG*^27z&&D-pwWkU{@OLK%xp=#CIitGLac6$xlWVF2 z=OW9IVF_n{fgigP9P4j&h*K8`EQlu__T&LGvSu2;80f4oClwpvf z${_ijITOQwvZRZVfEF<1xX?HV2l(%|1goZYF<| zrC0HTw40mOsQXpN|?EGcQaw`0u?@ab+Wnbd{gU!Vr9Y9g~pk< zEh{)hm<#=QDofGW(LnBHpw<^GqYW`RkB(tAcrKi;Xzo z93FeUOxmL_XV3ACyMGxPWZfIv{0LJ)KE1IjS1ixZqREoLm~=B`>F8m3u@XRPNO)(4 zy-bHE#;pX6O(L;acDB3FLzBxB#1=6ZU*(nOP&0N~5h{%?K0hB2B7FAC-yP}rFs6KAa9N%tJVi5QE#8|Ff_|d#7J+F<#%lf zAFn{nXpO9Ng>mYF^^5+Io{odC2?@9QxX| z6w!jd;<_WNw?*-zrWd99YGqJ=xB|6#tDucsCRHU$yGYIh=&<}D%4Fp?rCLY`d!A^eusipmc1Xw%jgIn{uNNMD3;bm%K#y?AFpnqaB?XwLlzPY5{uvp10{;v?NYw&loor| z%ge|jV4s!AeV`y0ArO1_LP@bzVWR~H_x7Z0IcwG@1Cu(*sWQK{WAkZSS=WQ5kGZpU z>28Ujh%0Lef6=dXQmjqtyLri5SumEMGZt@qc*4QB?1=I({lVdh47fCa$=lrgLmjEU z*V;-S2_FT>k*i(P*o(U-Z|;Mtpj1hArz!khDPNHHk`DBL=h5yI zGnNPLO>!5uiM2KoOhTI&rnm5^o2#QXWIcUnm@7J_IM#B#2r7f>4aJmfYTDTmZ&x=d zx@BwVwuKUVlKk>7V3x}{DakN&My!~QEWv5xgC|+%2@AJEFXR)#)N(t<1vUwmt}&q7 z{cUqZC3<-UE4cjSZ!%!LC;NA&LM${51afLXoZQq1`9Z*h0>&$QQ@&Fz_v`}H9saDP z`1DYJn(IikMB1To7l}e{ykjfc7eq2-P=uaFMFa7)py?ZGcJNR3B_+MKIoYlt?!=jW zQ_~zRJ8E4P%yG>%$rJC1$I9|u0U7e!iOCLS3FEDB%^*D7vxkd#rYeZX-kmDeRWh!! zb%uZnn#w0hD?`20xCAw7R}Tv!QxlzzFCt6@ZgAZAe;q@|ygbD&Ys3V_RCY5|iYeMn zO*IS@YS3xz-6J8ph#9_gizy^pymegfvl`P_r6PLW5TZJD7Ps*>S25o=rNN!`YKRTeobDRB>1Bqd=iy^4 z*BWI@gEcGX;%`YCY#Rcu4d^#diDxbJ*`*7-jXwGGbx>6Pv+RK&`63x7>UpH@)tV&& zR%hzspP+3M`FLZUT_sEbkOXAyo4`D(^n^HiHy`xV!XYlshPH4BR63|ZvaXDk%zt93 zJY-^*yH6~ACLzg|NE?&+YT-`1BTVeNl~6J?%L0UIv;l>VbUoydUcr&xsqkv~Qv#?- ze;;qRo;%7*au${;NsB!qr+w@Q9`k-_(aI(m_m5|4s!*E|hHH%`#%WN?;*mka(vj*_ z>jV4i&u;~n#tcuQtYmQ4y5{|}itjMDWgbMC1+mW}{nI%BTTmW^sP&iX!Mo1LW~&t& zbdb)67I=)klgQ=3zIWvX!GA2I-Lav3%Moqy69pezr|&9ObcHop?ifzt&c1g_FIu;X zs{3D#z+vKfUdq*T3^y^%Cy=??AyGMas_9rgm4bzmc#jq-c$0o8eT?KJ;P!h z=Z#sKV#5TYLRY_kpS^U_0}4;zr#QC_eq}Q@3}ktEmUeDlXZ6O&X5>cSKEm`B&5_Rjt2r*G2Y*kR84U*R7 zs59f4m)A+l;Ny=w00pLSIrAON8emPnD!oZ}AGjV|P(S|7x>}7B@8&OueyhaW;>QKM zOk_*sK9A-3{mIoz{#FG$ZIeBR>W`s`W0~B8KCMX$m@`MEbEhB)3Ry^W%VF;k`_Upk7Ly%?bo2PwTI7V z>7-V+%;pgNyfsJfoz_tMie1=zZzD~yUPc(Z6%qiHtQ;)XVTcC>8ANxVW`@u?b!~C6 zr;X1q*-~D$vEswAe#^Vbj&4x3lrC_}MT>jI@_kT6v!0++%Q-s>Oz8JA+`xc9N4suF zcB-nJpi*lh{Srh1&;%YXr8p4mUdC`VHeu>vc}w707cEmI6tD&`UNFBqW%2_*N=5La z-Vs6^tTh|3UQjq{FO^jA>;Fucl3C-|qz zWMk-bEtafCeq#7S4VjQ-lmFA=LgWOd7r}AU@8miXKGG_YCuoP%vPo@J)pmKuc2Y4O$?y^y@%DNM^vIj9;Xa;` zdLS|2N4!h)AlwTL_W0{Ne)VybHGMP6#g(EX*qCpQGY;4nf@P2GSI`MvF;Vn1EC5q*J{ILRU$6)bus`Tm2rqPrYadAfS z|Jpn6pBYqa-mgfKQxGp7_ysx-zH%%kOeJ7WD*;EDTNJGC~|;qWq@b zxC1pAfhqH=JffsCD&Ah-t_LKczRXSPg8*V*SUH*8x?hWoW!zH z{STrNfbG~SPSfBdZNEqS0dScn*jcUByHiHrpJBzI+$Y8JxDoZ3521E45(~eY{JhDx zHL3h<$q^{7MGVj}L>KcjEzPgb9gKZ{#H+~==6~_vEi!uHZSL$$`0nY5!5W*I`5#WT z;k;?~7J+P2`%T7hDIsIogqjuDmmU&pT&C*d#HY0`?j9|#-5GpO7aT#^Ro9L84L0Q2 z8j7V|8Y>NWL@;j?{Y3JLWRFdF&xL@YzkBx0+Cw^F?wRE|k6*9L1`Ikro(>5C5>Htc zU-7R)BK-yi(xa8>k+*^ytVXEMRUen*6RfMu-z`6u1D-1J0;9gY%@eJjSSM{R83cMe zx+8O9SUt-FQ9f_T22|7>N5t?ybdVT%e9%T~Hglv_4>c&9Q35X3NeSe!Z5lUfR3Uw1 zJp$~?_S~go=U%eQ1vkPH{y^Frkjr$#KY*6EMRUY{hwcdDosWPy!ZIA3esS(-aGVCt^AKT%v%0-5@th$NYj4k8o z1AB8$0zo9~T@=RBNE6BD12WVOHHD@ZzNE`e#fpHIR{V{BeFi2IGs0R{oFV7A`b~CB z@s%A0EPCUP&Al0aULgJ%i8GPsIL{t+}Rm?5S6NikF645 zbiw#yiVvx*jB8MP+0UKZ6#6*7_Z-+O?H~L4sS`V)miZ8Ot6hC?hK5cnA~zgy@9K6P z%^;7;>8c>@k@LKPATJ}NW2Jn$JGtsD6nZBxG%NS9JB$_-(Iq(aTiH-ek?gqGUhshO zM^AOP^HhH9k}G~mQSSGlO=fA*RAVw3Jc}9frblrzOZLv>L`$?e!q?G0|N2|_H`RZ` zIeM^8LUsTi-L{x4od;0K*63783V!=+stYRT_Eeuq)#N0Ljk^iqPp;wmSFl$VxL^|Q zb8l+Z)B{=X&VuV{cd@aF%2sq;GrFc{fiD&WQrq8Zp|;B^R^43Y2M~VO4ak5B1Ozo| z$BW|N2r6ZP7@3T#m8J*0>g|Yw0EkT$KFy6<0z1paCn3&uXjv3I zO>DBXE4sZ**QU`;f!yYbtIum)HvDt`Ivjtc$U z!K~97{J$)L;I4Da^HjhUUmUiYH>I6fsSj;B)c-yZ)o*_(it$^{p>QeSE@QIYdyw( z$?XZ-V4~}wQDnyIU%dU6`CQ)QAywjupz%YPuc6lD#apG&P806x7u>7dl=HwwE}9(zS-`u|o}4iG>`mf_ygcdC#~cG= z|GNv_LpEk$Tqe2rOzzZRf#PQLmxiEs`W%KBKm&dj+U2i=$4#Jd|IskYD|o5Vx51#e zJ5FR(l$4O(rjS-s%0_fz5^`#w?0bJDNjHLC%P>8VKr-H0q;{|{=Cj{qyUv&xO4|y_ z7;Jba*9>GWBqqS+e5VR7+{U7|3f0sEwz3ty1{*ftPz2Q6Iz2q--#~B*a zS}10lgBJ9)vqwve8T!<0ASgX*hFl|ebg2H(qargfmi$>H&io63rPOnIk;e@mQ>K%RSlxiCB_krC<=6Xk;XxEUp41o;uulbit| zT~z#nZj=P9Cx6n3o9^U(wx;&>pnOn6kT9U%b$CYFLCs4D6x=K-)K-ZR4Qer2pD&E< zkQwa$&CnnKIO8##iF4cMo~^c`u?ZW<8kD)pM=jQSEb;_RBg+n13n zd65B)0AFmCX$*fW`gvGvQh2Ne&a68QQMD}O`E_OZ=H_$`-IVuKZ0WP{r5nppPs|PC zwV~T23mmLSD%OSt!Ypw9vmmt2=FLMv=#i@zz02dTo_{JwesBtKYVKDy0Fs>FuPRol zkGYHSZ${6>QBs!tk7T7RJEO1zbITz^Jj5V$Q&h5E($%9)%`%~C5>SR;_P$HeYm6Yp zNPS%P`b>T;deM;I9PxyCWjTytZ2?XTzt()EvSZMnqr4?l7re&e{xzkDdfqf3dWdCx zX_+`o>M6#VMeKpUk_y4w2GC$v+I0E`(zW>cl%)-hW_RQ3_urohUkdxF+nF#pMEb}& zv?X?$NyjORJ{R)vH!-W2h)+Sb7MVbHw3_gVkByG{jh&s)Y#xAOw|Rh*lx>aHOK@|8 zLVPpI&pLArRZ2ckMl?jy^3BOOhHGEKuKF_~uNzu=&|-T2dz(z(!*UNvxx)Ycp1TKA zPioCIb$%{-^yttWc0}IS16`R)yNiRUHnJ{AJL?PTs@V{#P@0jo_hn4w7ZzYEjbF*O z)~d=oP7=~sSw?O>(+19NX-RI}q9-N5A*+ksG!QH^Z69!RgNnJ7H+B+!}tkm%QQ9jOSCVi7vp>WvYSgkM#lcS|N%O@v_$Nk^r|OHTLS>@tCAn{}4L-xJo9%=ul4SD#y?|UfpY{8-AEGI-Eb^a5 zhut1gw86h>S#e5O$R*8P3^+baol{8o^0juju}4K7ADOq;q>DEliXpU@_j}}dNi~9} zM!+LO9l#tX)aX(+ud;~RYc4wM#4_Ogpo}>mK5$pRGC0X?-#<~}`b<_V=Yu6%S`Y@D z6OaK$nN^s6UyAda{%mndDKYO|{M`!Q9M@6m3eE|O2k#oIgxt%b&^;m&h>(sYM{@J8 zj*uDRz-6DWrUUH7RJE50?s#yA3b4Je?~hAJ@=OIcgD~}4eJwCT&p*KoI<K$+HgM-UR54IISb2A=8C$0TUv0`}92N4DgROQ2IP&a;WzGm**+Fg*gASe$2S zG5I4dVUw?zgU(3zjpbP%YEzbPyEhbNI4n$%dMv3xtke1i5}XUX(MelecGYxJ)myN`pFTD{LUf%Rz71Wr zLvx&bFHrg3RpPY|w^kIAFtDW@U=s1jNq>s|=F$|HO*VKvsEKYe<*{Sz&Gl~hZ){c0 z@?DEWT@=oJqM=^9eOHOb&+j^CF~4Aixkpy7%T8eISVz_x@#SbJ<|!Y;+m6D%0k5XN zB&N?k#O+-XfwiVm*bVl;hd40LH5@CWpZucEC^9L012rR9ZuEBPf)+HIpeZ<@AL^s8 zrp7C?l~c*`b&RZYN*k&Pt+71kL6dP2>gmVR{04K%$`2_j!aK@t!D0SszSzpOPZrfi zL@E_r6&%#TU|;eBz(MIlr>BnOE-9<4ND9@v!2^}4%G!~Eq;DOAOG~XEQQF^u-RLF; zjRYMQK)wlY^`dcCm&w@(Kih&9k`;i)-jx#OiDe?)rWi2XYQRGS4lK#=hV)eL+Z5?D636;`R$x%rb>7xs}H>H(iG7csm!Pdgv^u%J54Z)F2JM&hkM)o zWwhoBHn{gX!RN2b;R(|;koScxamCaZ!K6>Yk0>%3&K5%?@h4Oh95E9g+0>Z!cM9-P zi_9oe(sBW}BMv6^1n;G)-gJlkd>5K*8CzAqO2i2|>lnd(>EIQg!k8H5K`WwkS4}h_ zm;us@6xUZv8>lY)r1BQv|kyj@BUT`%IF?*ls{asoYfV=c@fA>4u1D+@dtHP zv3QPbQB& z0u$30EA1XsXEav$=M-SagneSD=NJ4lDI1lb6QGTC@rlG;qXHTvV6-O%h8pXNCxMMs zMsvrAB?%elWwNQYUW+E*Fr?~vq7QUVH=0~h3pcLK8j8*_}aK;nyRaC^~A?p z&_0BH9PtUzJ_Ke}vaVVz@9CU!i3(ooqVt-V5Mg%S)7?^9E2T)k1NES-;*cNECSQMlGH9sO>8gSAYnTXY1r zGXTcu>@v1Vkl2u+qi@jlyi5jNycYxIOE(ja3cv*mvGP^uVqzP45L{5wyAb3^DqZs+>)^&MrdTHJgu zc^eisWVKe`4RG-pj2#03aU7(u3hb@gH+*pOk>H8t%z@GO>gE>UAb2%>tu>MZDFW>v zjn1c6z?+DR0S%x51#*}<(s|8vpBFevEz4&cl|c8b_zdrEkPS=OVaaav;Vex5e&jFE zBp;T-kXFXhN*h73#osbEOfMKgWWKhF+4}is>z_dP@Jx?|y7y z*g!THw&*Tg0ACXf2bbM}$H7~iIUw@Is#Ak58@Dv-7LH_pobs+SedtJu@+-l|Hm$-(nPDN^q8WO^CA*sMz+9e%O%Ejv z-z|6*-pua$B}%_6W@1c^9b!`5n;-FKBeW1cLS&Al6^3P#dbXAa~GKE`2;|*VEl<`5IbM*N=wS6 z?iS3|C9HPcp<`u%eC^4#S?S2hmT>*DpkSBz ztt-32e$86R9h)97-P5&sg=gI$@L(Eh2LH2pO8KsEv@fS&iIqusV4`o(fxuBNe~$Pw z%%27pHN72LIW*g>O)-j(e{6K?#Yml#Q%S6)?>gbJuD|W8xQOs21!SydeYK?Xlkj~s zuN{bzr4fmusa+~YiWV=Xcjac*D)(8T@xeitkCUH+i9fMZP0cm^yiAH;5&JizV)dK) zIeQHE!KO;XiaU>NC^m%zJO4LS@@St69mUXJsp2TiG3E@|v4?U&nw9=4& z5IFbfQ4^v&?135mz1%x)iO)a?V*X=S=eT)}WG@2ocKL7?d`ZF=FcXLeUvEF%o`>xq z*iMFRB-lp8Z93Sd#cfTnt&O&Y;s1P9yt+ADwG)1&5rH_lF`%6Eo^lS&kb}DQm#Wp@}v%)rMZcBx2 zfwV0P|HrH5Pu%Jyk%Vv0ngXkRALQu}?Cgx#`qt#n5Ia8k60sAWeF8s-+aU-j0k)nY z;OnB{&yEK>{{70|0w3)B_w&!;i=+{V@%k?|;NeKrY0s#@OHo1A0g*xQfG{>RHq$pU z(l;_ZXJl+`VrXqx3{|U`R0GzdzxQb2u7KIQCzk5ET*@gpaxu z7V+PoBk**63+Mb}>ztstkYMZ6@Q-V7Fg_>>VPdKGb Date: Tue, 18 Nov 2025 12:09:01 +0530 Subject: [PATCH 3/7] fix-32310-Added Mac and Windows snapshots. --- .../mac/ModalNavigationShouldNotHang.png | Bin 0 -> 7368 bytes .../windows/ModalNavigationShouldNotHang.png | Bin 0 -> 7357 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ModalNavigationShouldNotHang.png create mode 100644 src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ModalNavigationShouldNotHang.png diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ModalNavigationShouldNotHang.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ModalNavigationShouldNotHang.png new file mode 100644 index 0000000000000000000000000000000000000000..cbdb4b9d01ff7ef9484d0345b03ba55f3f8174fe GIT binary patch literal 7368 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 literal 0 HcmV?d00001 diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ModalNavigationShouldNotHang.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ModalNavigationShouldNotHang.png new file mode 100644 index 0000000000000000000000000000000000000000..6a9684ab4b963857886ebb58de16529c3bd16269 GIT binary patch literal 7357 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 literal 0 HcmV?d00001 From 0100970a9bb5c3091b343c4ea91a293ed1da0bb5 Mon Sep 17 00:00:00 2001 From: BagavathiPerumal Date: Tue, 25 Nov 2025 15:34:01 +0530 Subject: [PATCH 4/7] fix-32310-Made code changes to ensure PresentationCompleted event fires in all fragment lifecycle scenarios to prevent modal navigation deadlock on Android. --- .../ModalNavigationManager.Android.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs index 41f4da4bb215..c4cffdb8a7d6 100644 --- a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs +++ b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs @@ -219,6 +219,7 @@ internal class ModalFragment : DialogFragment NavigationRootManager? _navigationRootManager; static readonly ColorDrawable TransparentColorDrawable = new(AColor.Transparent); bool _pendingAnimation = true; + bool _presentationCompleted = false; internal event EventHandler? AnimationEnded; internal event EventHandler? PresentationCompleted; @@ -367,14 +368,18 @@ public override void OnStart() var dialog = Dialog; if (dialog is null || dialog.Window is null || View is null) + { + // SAFETY: Fire event even on early return to prevent deadlock + FirePresentationCompleted(); return; + } int width = ViewGroup.LayoutParams.MatchParent; int height = ViewGroup.LayoutParams.MatchParent; dialog.Window.SetLayout(width, height); // Signal that the modal is fully presented and ready - PresentationCompleted?.Invoke(this, EventArgs.Empty); + FirePresentationCompleted(); } public override void OnDismiss(IDialogInterface dialog) @@ -399,6 +404,9 @@ public override void OnDestroy() { base.OnDestroy(); FireAnimationEnded(); + + // SAFETY: If destroyed before OnStart completed, fire PresentationCompleted to prevent deadlock + FirePresentationCompleted(); } void FireAnimationEnded() @@ -412,6 +420,15 @@ void FireAnimationEnded() AnimationEnded?.Invoke(this, EventArgs.Empty); } + void FirePresentationCompleted() + { + if (_presentationCompleted) + return; + + _presentationCompleted = true; + PresentationCompleted?.Invoke(this, EventArgs.Empty); + } + sealed class CustomComponentDialog : ComponentDialog { From 47bc4d6932f3632dc6ed8856862c2b99ccbec5cd Mon Sep 17 00:00:00 2001 From: BagavathiPerumal Date: Tue, 2 Dec 2025 17:03:03 +0530 Subject: [PATCH 5/7] fix-32310: Made code changes to add TaskCreationOptions.RunContinuationsAsynchronously to modal navigations and _pendingNavigation pattern based on _pendingAnimation. --- .../ModalNavigationManager.Android.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs index c4cffdb8a7d6..0f47d281caf7 100644 --- a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs +++ b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs @@ -107,7 +107,7 @@ Task PopModalPlatformAsync(bool animated) return Task.FromResult(modal); } - var source = new TaskCompletionSource(); + var source = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); if (animated && dialogFragment.View is not null) { @@ -183,8 +183,8 @@ async Task PresentModal(Page modal, bool animated) if (animated) { - TaskCompletionSource animationCompletionSource = new(); - + TaskCompletionSource animationCompletionSource = new(TaskCreationOptions.RunContinuationsAsynchronously); + dialogFragment.AnimationEnded += OnAnimationEnded; void OnAnimationEnded(object? sender, EventArgs e) @@ -198,14 +198,14 @@ void OnAnimationEnded(object? sender, EventArgs e) else { // Non-animated modals need to wait for presentation completion to prevent race conditions - TaskCompletionSource presentationCompletionSource = new(); - + TaskCompletionSource presentationCompletionSource = new(); + dialogFragment.PresentationCompleted += OnPresentationCompleted; void OnPresentationCompleted(object? sender, EventArgs e) { dialogFragment.PresentationCompleted -= OnPresentationCompleted; - presentationCompletionSource.SetResult(true); + presentationCompletionSource.SetResult(); } await presentationCompletionSource.Task; @@ -219,7 +219,7 @@ internal class ModalFragment : DialogFragment NavigationRootManager? _navigationRootManager; static readonly ColorDrawable TransparentColorDrawable = new(AColor.Transparent); bool _pendingAnimation = true; - bool _presentationCompleted = false; + bool _pendingNavigation = true; internal event EventHandler? AnimationEnded; internal event EventHandler? PresentationCompleted; @@ -422,10 +422,10 @@ void FireAnimationEnded() void FirePresentationCompleted() { - if (_presentationCompleted) + if (!_pendingNavigation) return; - _presentationCompleted = true; + _pendingNavigation = false; PresentationCompleted?.Invoke(this, EventArgs.Empty); } From e6fc5560ab714a276bf4c98947d02ff56b5abaec Mon Sep 17 00:00:00 2001 From: BagavathiPerumal Date: Wed, 3 Dec 2025 13:04:23 +0530 Subject: [PATCH 6/7] fix-32310-Made changes to move FirePresentationCompleted to OnResume() and maintain TaskCompletionSource for .NET Standard 2.0 compatibility. --- .../ModalNavigationManager.Android.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs index 0f47d281caf7..fe5f6ae29cc1 100644 --- a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs +++ b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs @@ -198,14 +198,14 @@ void OnAnimationEnded(object? sender, EventArgs e) else { // Non-animated modals need to wait for presentation completion to prevent race conditions - TaskCompletionSource presentationCompletionSource = new(); + TaskCompletionSource presentationCompletionSource = new(); dialogFragment.PresentationCompleted += OnPresentationCompleted; void OnPresentationCompleted(object? sender, EventArgs e) { dialogFragment.PresentationCompleted -= OnPresentationCompleted; - presentationCompletionSource.SetResult(); + presentationCompletionSource.SetResult(true); } await presentationCompletionSource.Task; @@ -377,6 +377,11 @@ public override void OnStart() int width = ViewGroup.LayoutParams.MatchParent; int height = ViewGroup.LayoutParams.MatchParent; dialog.Window.SetLayout(width, height); + } + + public override void OnResume() + { + base.OnResume(); // Signal that the modal is fully presented and ready FirePresentationCompleted(); From 3028c12605d764ff0f8fda1ac2fda00ff115a3f9 Mon Sep 17 00:00:00 2001 From: BagavathiPerumal Date: Mon, 15 Dec 2025 13:38:37 +0530 Subject: [PATCH 7/7] fix-32310-Windows snapshot updated. --- .../windows/ModalNavigationShouldNotHang.png | Bin 7357 -> 7381 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ModalNavigationShouldNotHang.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ModalNavigationShouldNotHang.png index 6a9684ab4b963857886ebb58de16529c3bd16269..b3466e42acb0cd90bd35469fde22852dba9ea93f 100644 GIT binary patch literal 7381 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 Q=o!kvcB>8N>)k*73;kU0ivR!s literal 7357 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