From 2e2bac4ccdc24e5dc095566023c50cf1ce1d2773 Mon Sep 17 00:00:00 2001 From: Yeon Taek Jeong Date: Wed, 11 Sep 2019 10:52:33 -0700 Subject: [PATCH] For #419: Create launch icon for private browsing (#4948) --- app/src/debug/AndroidManifest.xml | 9 +++ app/src/debug/res/xml/shortcuts_debug.xml | 29 ++++++++ app/src/main/AndroidManifest.xml | 53 +++++++++++++ app/src/main/ic_launcher_private-web.png | Bin 0 -> 20935 bytes .../java/org/mozilla/fenix/HomeActivity.kt | 17 +++++ .../mozilla/fenix/IntentReceiverActivity.kt | 28 ++++++- .../PrivateShortcutCreateManager.kt | 49 ++++++++++++ .../org/mozilla/fenix/home/HomeFragment.kt | 49 +++++++++++- .../home/intent/StartSearchIntentProcessor.kt | 18 ++++- .../fenix/settings/SettingsFragment.kt | 7 +- .../java/org/mozilla/fenix/utils/Settings.kt | 37 +++++++++ .../fenix/widget/SearchWidgetProvider.kt | 3 +- .../ic_launcher_private_background.xml | 26 +++++++ .../ic_launcher_private_foreground.xml | 18 +++++ .../ic_static_shortcut_private_tab.xml | 9 +++ .../drawable-v26/ic_static_shortcut_tab.xml | 9 +++ .../main/res/drawable/ic_pbm_notification.xml | 1 - app/src/main/res/drawable/ic_pbm_triangle.xml | 20 +++++ .../ic_static_shortcut_background.xml | 10 +++ .../ic_static_shortcut_private_tab.xml | 9 +++ ...static_shortcut_private_tab_foreground.xml | 18 +++++ .../res/drawable/ic_static_shortcut_tab.xml | 9 +++ .../ic_static_shortcut_tab_foreground.xml | 18 +++++ .../pbm_shortcut_popup_background.xml | 20 +++++ .../res/drawable/rounded_gray_corners.xml | 8 ++ .../main/res/layout/pbm_shortcut_popup.xml | 70 ++++++++++++++++++ .../mipmap-anydpi-v26/ic_launcher_private.xml | 9 +++ .../ic_launcher_private_round.xml | 9 +++ .../res/mipmap-hdpi/ic_launcher_private.png | Bin 0 -> 2882 bytes .../mipmap-hdpi/ic_launcher_private_round.png | Bin 0 -> 4693 bytes .../res/mipmap-mdpi/ic_launcher_private.png | Bin 0 -> 2223 bytes .../mipmap-mdpi/ic_launcher_private_round.png | Bin 0 -> 3119 bytes .../res/mipmap-xhdpi/ic_launcher_private.png | Bin 0 -> 3877 bytes .../ic_launcher_private_round.png | Bin 0 -> 6590 bytes .../res/mipmap-xxhdpi/ic_launcher_private.png | Bin 0 -> 5729 bytes .../ic_launcher_private_round.png | Bin 0 -> 9961 bytes .../mipmap-xxxhdpi/ic_launcher_private.png | Bin 0 -> 7301 bytes .../ic_launcher_private_round.png | Bin 0 -> 14024 bytes app/src/main/res/values/colors.xml | 3 + app/src/main/res/values/preference_keys.xml | 3 + app/src/main/res/xml/preferences.xml | 4 + app/src/main/res/xml/shortcuts.xml | 29 ++++++++ .../intent/StartSearchIntentProcessorTest.kt | 6 +- 43 files changed, 595 insertions(+), 12 deletions(-) create mode 100644 app/src/debug/res/xml/shortcuts_debug.xml create mode 100644 app/src/main/ic_launcher_private-web.png create mode 100644 app/src/main/java/org/mozilla/fenix/components/PrivateShortcutCreateManager.kt create mode 100644 app/src/main/res/drawable-v26/ic_launcher_private_background.xml create mode 100644 app/src/main/res/drawable-v26/ic_launcher_private_foreground.xml create mode 100644 app/src/main/res/drawable-v26/ic_static_shortcut_private_tab.xml create mode 100644 app/src/main/res/drawable-v26/ic_static_shortcut_tab.xml create mode 100644 app/src/main/res/drawable/ic_pbm_triangle.xml create mode 100644 app/src/main/res/drawable/ic_static_shortcut_background.xml create mode 100644 app/src/main/res/drawable/ic_static_shortcut_private_tab.xml create mode 100644 app/src/main/res/drawable/ic_static_shortcut_private_tab_foreground.xml create mode 100644 app/src/main/res/drawable/ic_static_shortcut_tab.xml create mode 100644 app/src/main/res/drawable/ic_static_shortcut_tab_foreground.xml create mode 100644 app/src/main/res/drawable/pbm_shortcut_popup_background.xml create mode 100644 app/src/main/res/drawable/rounded_gray_corners.xml create mode 100644 app/src/main/res/layout/pbm_shortcut_popup.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_private.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_private_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_private.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_private_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_private.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_private_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_private.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_private_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_private.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_private_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_private.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_private_round.png create mode 100644 app/src/main/res/xml/shortcuts.xml diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml index 45846ce14..922467614 100644 --- a/app/src/debug/AndroidManifest.xml +++ b/app/src/debug/AndroidManifest.xml @@ -22,6 +22,15 @@ + + + + + \ No newline at end of file diff --git a/app/src/debug/res/xml/shortcuts_debug.xml b/app/src/debug/res/xml/shortcuts_debug.xml new file mode 100644 index 000000000..0ac003ac7 --- /dev/null +++ b/app/src/debug/res/xml/shortcuts_debug.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1373ba7e3..07df0726c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,6 +10,7 @@ + @@ -58,6 +59,10 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + rhElxH8HUI#p_VJ@e z0N~(1ae%-A|C;e?Tms-^sP<8H6R)<>PS*RI?B2~?scW76&S@W#g+8d3iy(;~uT|nw zl2Fpp+*ZxuZBu#D)wEh%itVn=5n{N|HbSHumsMR$le@-AONH;M-yc0&qFA^1C%*K( zYFQ`OUYAGfA01*9A>AY%A&C9||1r|-d^f(9^Y2WG{Vq)|X>&23sAWB!>92aWG2g$~iKlaJ?oz;N>9ck#s{)s`BoY7Z6mEyE zBv<#SRCf0M;jSXXYe{zOn}?<^b-weUf3_7zbRVpgi)Ip4U!DClAeL+rtiQ43iRywn zAOM7fvZOKl1Wf5%6KR_2A73W$-dhlxQtLYxX;mse6I8j%jF12x1rDYhn`G)&?JDjq z(B&#_*WIvI>hk1RGETZ73f~d|?&&F0ma2F_Am$kz9-rW^aG}L5b+i7N{AkQqDOZbw zH+101$9p$Ku5!%SjjMRtfTCQqHz zZu&02u&YCOW$5pF6&AL>VHxIWkEfqHQ90oion6Pad+5-LRvX#ibcnjf5uy}-%bBT) zt3yLctihl11=ci{P40>eRlMi^^MwxlqFsAR>-8u%?t{Yu_pphQ&wZ&A?8s(6k+n<> zfL}+Q5-BAc$M*4R_}j{6Rdq5y2VDmO)LE|Pf!}85vT)-M#432J&|&e#b8Xssw!=Oo z>XRGR7yBwd9y+zZ+*%Y_6If$Vib$^U-&o)2ElRR(9NrjLU>EFjUheSaeJj)U7pDy> zCd$$QNda#%u{`mYI_C+Ss#=;}vt963aqfCYXF(1Ktc9*Q$2@(M+F4E`AY;bs0KhZ< zypE357J=GRWOtQ2Ro`vj?UN^?Cju#-Zr^|41eJGwLe=eP{USnzPDiv~5(7`sd8d?H~GaFfa@dg|uqR^TrNXbUnKDvkhsNAwKB1_+LUI+nO z4lPl-uWh8{ZBhLdy#+YnO|BvkoFyy8XiQ@Q=>(n_ztRJnFxSras?S9nwOJa$Sw<*%BvShYKU9(bfSg>~jUgFeg zJV}A@cY}PoH0s7l^tI;P}xuA9vQ#+5-m9g37iaZMx_>wV=|bCK@ok zZ3cycm2P!0HIH#%9;ptP$-AB7YWwdVRnVc1u1O*cmV;CBSzOe3Ny?A!^j4eZaAtrl z%1fRz>Z6lobDL7w{@@)rykfaM*j>yTzRNdcwn}d=8SHH>qO&IZznM@A4lMg7@E>HH zQrlFyc!iqav0XQIH{D$fJ%xUutTH*Q(*#`Oz6*d03hpg$gdrNByd#>ACWzklv2G#AJHpb_S`TkdP*Wl<`hWLBsZBr z`$k3|@N|n}cqaQZp;M!1$aecTL)OwSHTyTA2Kf7fon@)?>@7-uF9jjd)0qFmw=-j! z)cYzluKT-uYy7J&{oF+D0ERc`@`fTL^s|ueW2hnorBp0MXdQz;7Q}5VY*$BXb<>H6c--DLc-HSJaT4p@dYuhzvB0DXC|>z z?Z~{s^j$}m!7#?-avi5U%3OdGh={$ItmJa$A9jt8mRq`!_8Jm_$lE z`yXUN#cCi4TA%F#ULO_Cb;KbEx&gS*Cd*R8o?&nc{O7w1XFYJF7cr16P9fA(Wk+zB zllW_u-q}vim58r^@IGVyBWoxaVge#=HT$u_%4Hz)@@Z=m{oF@&Ilm1Z^P$P9c!gErKe|)182nO1$J|(6}G`XZ?6CaA+`o zFI~SU6Ww-{55x%9P&&cWivU~TdI+#4L0STW+;*@w9KZLXC4QSaK$j6RcLoa@4_z4K z4_C+oG)RFP|0@cJE#ax1>}crWbY}8jNZ<-7R=Dm=6B*o;Hjwwjkry?dZI0QUlmR5x zjT^w%lL4wgzKu-W9*+I}oejJq7-D?HfE0bg3k;4yT8<1R>e z=GDdvnBLNd4E%+M$O`|uh=gyzRyd0v@E2eI6h{WL2r$5bY0xdk36e~h$RVJlABTcw zq)Wnv#9&Qu0ip8Y9&Cj$4X6qe8GFEq%-{eEYNQJHXhtB6X(8xg5&%z;2`M1A7Yq#m z>cA#|XV9NK0Q9tN15Z<# zAoREp^e9{(^?+Cc+h!P}3}Z^jm%;g51MryvhKdfsUP-uZDuTQ5`CNnp*y^Z@Iotw1 z?nsIzDhOUHZ2-tRE&&+f1PZuDh{$XvNEaJns1eZ`jJN+P6o4ZGkgo)yhY(cde|}}- z&PLV7Xm(YLDwu#r;kgcjchZ9sm^yGB=Jyav8=BcAE7EA3WJF z#+xiLDj!4w9L5Eq|B^_TAh+%&pi2=wNACeufGv(Oh8u(kF25BD0y4>vO{xrGf)&&8 zVh~-x#vBSx3V?$)!WdBbTo8Exq#-~N*8#e>0X$<5G5`c#Aa#lf`wbCKbs9z=lK_1D zLE}B4;cKYZIx7K$1i%kgz$soajHBjaIEAodE5mQQaS#e825cC*;o<;1#Nzric3AblwN_m7}yUWdE%i-SgLZJ^tx^usMM<6vY z7}x0(g4B~)F*^OlM?Mb_(A1w`sBjEx@D%`p2>BiqXA)JPa2$sXLH>k~KSMi_9kAnI z^4GnM#7Vfx15fm6T~w|eK@T$+5}R|H6H=MwuZhCYf>9FKoCNzr6Qs5(F%uM_mIB0X z!SyN4noz)`pmLOZ#}4&C6k5;NB!65v<@O1TEjXZv&K%|eI1CRECub#*_c!63gP?;@ z?<+%oo6Y2q&xLJ-3q}>su>K&f1K=>@PA0BP==$lHFf-Eu=}+QlLH5EicyRdO|KJ27 z`6nB&hU6x>c;a^6K)ZAQC)jT3`Nms~f7*PVqxY+-@odl8`) z52F~64Cs!a5QA61Tb^!CQ0)t)1LA_P4Y$IC5N#B(T>&|>0OJ_AHk^b1sgE*axFeuX zBBHiSWB>>tdWL8i3Uv%sn_P*#V*`6|eueCewct#Q0oXBiwm!@QQE(Z*(DUs*iIfUC z+r|vPi4}Q5{)6<1zCu7EtrGHwJ>hxaQ9q39!&eB1UYc?zH$y(o=c?BtZ^hmWYy;pl z5!ASY6i>GQzSTn{5s zLfAr7WojuT1cp)qGwyl;m(<3i3>07sGI(T89hHU5+N?#+*N0qs0@Ry8=7$shC?bAr zEeMoE#sF?zLKxG!#NqHJXcpf>9T_b4*ES`hzRc@HaR7|tGCsa2mSSjO25jsgQBoM* z4TA^r>y$}E!doV^8BnXB-@}UG2NP~gy-UEA!*`i00GrL=Ri(fI0*&BzgYFUnh1e;Kq;?WsuJX&I*7((7-cJY=Lb07+ip!lM3lS zdI#WEf*>#c177_%pNkm2g`o}V8vyuw9x~Yh!hQgdb^kbT4744?&Vwgs6@ULYy~*ak z0l|#(LBKAibp`Yn2(;ku@tyt~>bpqYF>l8({JKbxIWYt?mL`$*FxY^c35_>(iSTr* zqRub&kceY>AyL26C3Uied3-euluegSwdB?)?+Tm^xn4TU-xM@ zm@M|Qc=(z5C??8w3f4yC&f05dD32dsj+ak6p-?fdf9p#_T5wNY`oihVRfiWQUlcdt z?-P+eHjc<=nt{hhBPG(TT5T_yNNdKMiAwHqJQ3c~BdJ})Vw|Rtda>d4BFA9M#nR%= z%a81fWTKPu>Ri``qu)3l{4_c4vEtN}C{^PS9QFB>ahm!k+f4K3$>q}>NVyqrn%*_2 z_nxeyZn*gSr-#sH*a+hreU&uZ%#y_X1!cp~-udZ&j-@6LpFZZ5fHk z5#;*PHCoXdMl<-*Y8=p|3KC0b+BNuMWoN}sKa~ubsq{CZ!i6EA#;-o9*;*5yJ^nI_)kH)U*mbx z% znmbFC`SCvhgEQ;J$>WgsY^8l|+pN;7Sb?hLFW*c!eC3-` zn!o?vd3)!Mx7+OvtRu_0E?sJOKi!`POr~@ zEsj>0YOf1Q7^lh}?D}L~c2z#DysN$IowvD+b@2{+eXHoypt{OtYp$xt7ah~BAKo%5 zTj0+;YxCCRt{@I)q)smMyOI9y`=go0u4yxu6%Dr3E*yKa;!2&IKC~x8Sgqx2T&@zO z)^x$&C0S&}yEk}cX*%G+fid=rr#!Dm%N{ze(>KnI+l~IQFe&pEfJpSgH+pic);690 z^6KNM7rtLl77lvZU%tiXX`RK93wf$aCABQls^+)$J)Nku&$}el(bQ9H+!0SgJr_D3 z)(AP^_M0-3NUsP|93Yz;r281K;*m!h ztYb5GT7=DF| zg43eFCj;8A{e%k^Ue}A|M;u$H+ml^Kt3oFDS6Ea%eqDDvHSz6wvMo7iyU}Z^oVi4b z(fgy`Sv^MuXzk*uI8Ia?>`!E zwpI3fWLfyAIhV@(FGZ)0-a5;d;!937S1-1^y!d%bok;Y9tn?73lWwvg9_Nnf>Wmxo z)ptb|cl&Rs=`zSgJ+7l$4zmAK!(Sv5E?zjmH)8n(7uDdwGat za{zC$Gklw+K$(Qwj(|O7er0u&^L5?xudC!)H!kmq*~biHEuut<%Wjar9gxW`#1szt zNlUfZ@@4(WUrCSZ9?+s`^FnbkqL(7qM)`DSD<%?l3P7uPi#U{z9`IiLo%>b@Dyp*J`dOH=n7vT8hc8)03*Ux~r9=?Zp?2 zhsq56R<=8uUXE$A3(VL6qYunizlVeF26T4;t|1IXPQ+Cuv(`;KK9N}_%H_WB%Kh?e zs2TLB*Dy~@4m1+h{a$~m?6G@~Y`g?;{Z=L~&NkpqT}Rf2D_D zdL)e-Il+D+x^G%>>faL=(WS{EHJ$Xw8?0b}V9SB90a!qDgyFXc^mHja_3su;T9xT7roovIv0T&8sE^{U!~mBZ^ZtOW4j=H$Cbc%`(<5mZy{Y zEY%-!>~T@(g=r%7rqJ6ZWe*T80AuLSM7cs* zTrt^LpnHd;Uo_@o(HLxizG1=6twnwDMQs8HVK4G(F4&6kn+P<#EZ~A8fEcvK`^~rN zTcyAa%qY(_bw1CrBI;y_D-vkyOO%G0FnKZ=<;frIFK6uGwASY-2~X6`^C$S&#E|Fi z?y)HB{e&!w@)ei{fq?&sfgnJTUAh~S`Mj<@*-uqb zZtG7>XNQ{eAl_YCO=UOYvOIUW(7PwrqR2-h*P?W6VXKA5+|(yW*V!u0!Yiv!rmf4n zb!c^_i;I>ezZMFW1CscJ)y&eX>K5Bx3)Uw49$dQ=ldRtJOga$5y#~Z178KVnA7xPd zomqlJ++{XkS1HA``tjTJ)N*dmRC}Ptiz}T0i$8}uU;KV~d1~-F=L?r#XCEA}jR_u^ zeaLW^q33%pTF|wUecmg_dtt+zq+LR0oBuI6Ql-O5INc(A+EnRtG)Ll>D1j ztm2!fC%T#*?6WMPJu;ibG5At%2dBB1n`B-DH{Y6+wJc41*mOLcb9lZgmXp<%mV3^1 zWk9JvInMG*ik~QXI=;sULlQS+!&^woF|^AK;*(CSPn|ksj&$EWM;xVHv1rcyA$Cuw z-2WH4IkIumfAAC~>6MJiDS@&B>JELnu`o}4=&XXzf`85f=d}H@^4d%L6J?D9{iLmT zFQ4KXSKD6T)b;N`QEC4gwX5gFN{O|tUxVvlvu*7D-BIE(Q<6G`_utRI&eq?x`FM2O zCoP>GwsYxjG zuva2Y{oC_~^xEAIB4=*#;(i`liSb-M$9p*HjmHz6oR(uci>K`dB;P8ZF0k`ZsZ8B0 zj6OBndB!SF;mp#T#D4tyu0)FR`+vMa;~W>1f^*PYF(iW1g6lb>l_1pWR1PcXyM4N_ zAmtEspfhtg-8@IBA*KFwCa>aIhhrhGT>h6=uK~}jijeTnpDI+u@;#UL76z=IKh3c^ z+~QQ3ds%Cn-9&~_f!7O@+s54fm*oS|q7dP2o2Mj?zy6?+Zn1ISCB2+C zJKw&Ac6tlPlTZMPQ-k_cBlMsTyo23 z#B{%m`Orq2sAuQWO-9;DFxrGFfElLSj(I``q7duT6BG_Jr;Kz`7Oy4;j}}>2$*P`k z&sRnq)LC<}8;5t}bh`9W! z^nRe?5b|o5qUF%X4z-1v>uCI$(UC{*Mb^y(v`tLF6i2SO-6{eui0+ktN+8TC!<50bBjnVl8(hcI?#LK*uIX}( zD2w$h$;1URe^v@AD>79_ry|~u&GuI|bF%I!oTe?T23)lEd}ng|L<67-5S~s|5x1&N zoKt#5v#@sa|J|r5Ev!g}CW2b_mp|B`J+a|&8L2<>z4*9Do0}0!fz^)L>5vlV1#?cM zsppu^zx{TuGxb|_k?x6W#tnI$M>6>{6jyR?pm&+061cZ4^`v+wwYc<7TrB^|ja#|L zNNr%n7;-)jama%#$CFQKzY@hkH*Uyj6RJoN?HRhDD?uJiyBSlP!F#sPZRm?LC84Uj zU<)q#>IFH=P$A{Zcaz6+N3|O8XbI26`TD<(6;@@qrcRCZc%=61uupd|$Hn<;4h!u} zhzEN}tf<-eb37l>b94Ame)=TC^maoSM4~pR z{>F@MCEE0RP$Q#f#e7eiB=yr?Hm?+wTU)A#kr$7tzqBG8dOM!h(@D=RDyQWV2HM=u zAD3k=m3NA%!vH%B0sD%x36%lC#1vKpCX8`UiVJtz%HB<`ZY9k=t{B3>MD>M*wu5J8 ze{T7%y4}!Qt9Yf;I_+x2NfD4Q$OsT)L@#r+*7+=$k7uxh1pGoMgze&A*eX1z^`@eM zBl7eOIkDQs=jtnbIf0`%+4}%>0ZCRVtFFA1d_r{bx0aFEjxT#BqTG34(z-eX74wg~ zHDcd6J=;16y{-vPL=!=q5IHSAYzI-KBx^UJ)oFiWd&Wl5#7HiD@N*bRm?g?AUlo$y z46d$Tg^}L<0fDu-W9Zb|?&zBa8tx6Qx@Q~tlf|H$G7bwG-FBFR3^B;?INn7+*kd1R z&GCi3Cp1JW&9P7EqBu3~J9r5pJy>6`>&?USoGE^-bq<>C@63{DF{21W#BSxeZ|Am7HeTBP*ER*MvzwO?pwN2(NA-ejqqDz$!T?9}mg zYh?25+@7Fx{mck`0BZnSgUA!Go(SF16iuoyxX*`Neal<_yJ>K$hwqW^>6+Or#oiVV z)->nNTb_uG7G8>*`D~GE&_#XVRHzT0ZRU4U!beXdNN0R)^d3R3%8+42jk%X=zrWJb zjy?a!6Z7%^3abk@#5 zF;?hN;&Jhx^KU{oAXf6s%WvnB{fJeYz3*d58bbzA5f0=!O!i6Vb=d zOE6AKY2<}=mq_66oRly0`x$>RNzc=kesR%eDXbxN=}>t;{{HMXSj&T%&A5~Pha)&0 z=auG1&j)PEcjfC@ZYtXLe0g7{@wV1Tf|O_+>GH5%O!~_fr7}>t+rY}C)Hah6ck5lb zD1ISeqhSX-z5^lqV(d1MjB}BMCFK1ln2;NSd!ka8>+U;AjduFz#p<1w9sOF|vyz5x zCK9b(f`h$#~f?5cXRD4^51aAh^k{i3qODah({aV%~_u(<6d0G7l(%hywl)WaTp$L~EhPO}<0_&uBH7khBT@9jIZlLOgpzeIbu&UA0>C%&laZn=S8 zm+j+u|FR-Cws!Ws&gw>KE+U6KCvN9&-Du@cTG|y$-}}m$)hY|+ee> zrdARv>XXGVuh6-y<9wU%=Aqn$3#lf%ls`fZ4{b9eKuhF=MGle+;lf4*?bs6w?-y(9 z*fg{kmpckZ?`N+~C_Yg2dtKaVo4H?l|6Uuy1=CBBGakj|qMiN5XZHV-29`g*35q$BER~f9>Vj z)psxKz=Ns#w5Kh(o#Cxfrn(Q_USq_oe!_6HkalGC2d*A49UE7X_$zLP2hkKV#71`0| z&cRfg-R3Jbc*U|Fpt+xEu*?0;{@sbtv*(`N ziZrotM%9L#ueyINxyl~qVlJ17L}JO&?G?!{oAT39>A?`Y&_{>sPZ5b6_=5qDk zcy)>9$4D#F{7Z~Y1M;;GpP72;S3DrO=rvhaOZTs-qV*PpuqNKH@^0}P?{^+e{xa?x zrkm9kWdaB?IKOLXVl(22Ol$=Cn_%oWU<*((R`LCbqNdDGzBGFT@t==g$`ouKkI~87 z2J14gE8>sCl7bb%^FJtef8SbmbL1f+{n|K&F0v=-wP}?X2ka;tfOT|6#nc6+AMmV5 zYCC0zVjk@mb3y}$>Ef?P1QJR@Ez7!hAc_SH(++nA4 zjSddVK&?2@jO8yFANswtm4*$nNuM1+jHLpzKCkzvE#`%y2V^+ro2G(O&YGa6ee=vF0A7}a8?7FlTAaPR$aeXN!$0#38y zMW7m#iP9)Cn7po^8P-|0eBa$^CA5FSUKoA{wI(a3HDO3JAeO=_i3DhnA0GMM_mKOI zifBdEJ>~Q+wH14q(oA>w`6%?7S|vADhHJQn`husNARC7|g~S?8S>BiTCPaJ0Gs~-byr*U2cD(VN_uIf(6d~fjPn~ zWJM-$QxI3}B59*NrEK*>diKS4EsC_AY9O7|jHn-DkpA6P0E_G0;wk4MU`*3-%Bn;9 zL@G>|M4bI}EDZ-shu3dGUSfhRf7C-?vBnM4Bh;w}f_vyCBhf4`3Y=-N=`YLNV8EqL z9>9zu0UhIEXXHsma4et8BrCX+`)?h-SrRZCn4sc+X6=x>>D**1#;X6*z88-L>o!4Al}Ur{$s#j z>FxA3*#*Qmh+?cSS|-)5C=#1_$6BYI?fbUUZvMZD1heZg4{>;7Xal?Tp<(0$C zL{X0Ug;&L$=kNIKAD3(`8a05i;1)GcHMKdw3o1p2Z?z`pAs{qBo>c7 zmUgtG)t++aju>dS%L(-RL-jF3-|2F(B1bJauU>hZ>fcG9N7L-UYhS= zH~-iTb@UF#PgpwwEPX?e>y)7v^6Kux9c2N&Xc+U89wS-=&ERX1akFmE2i~-+?k^he zzH6}&CtrMh|7XLql}(F7<$GM0K5F*Mk1V=PjsBvA(Z*tRm?JI9DK6cxpMz@uS8c!w z94ya>rFi#l+S)cEp>%aZ=mz!cPFhC3>z5sa#?GZ5D?%gMPR?`F4aLY86XUdWjpF9} zf|`m7X+Jf>gbwXdHLt!>yeygxv*dD2(7k1Jz`!)uY1W%ph3lVmb9g&io~u4bjeICOPTbRT;R^7mxeogFr+D0w-sd?YpyaWFqg=f>GnMYR&vB*2Xf)=L zk<2k}sCkcIdY$P{5udOJ_bx78QqXL?fB3qw_wJF3my}qUQ|Gn)s`)c{7224<`6K9b z0QtS`V2f+SC5tj^r>^eEly5Doxz;7d0bWiu_E zvJ?;UI)GMGEL~OZn&ozw&20=385LR?iWf$7hD+kb-Hc4XPD*5Z&p53XoFQ46~$0r&x8+KRZi}vhY$+?Nb z1X+S76PAC>ohCj~@l>j{h`lK?t`z8h9hwx>8-tDmgAO3SEm(_16fL_%>8TbaeiFgX zH|g7#J%!>XowLJ#Yf2Uc()qtir1*>w1`T_J7roxsxla0dQ6zd{dBU#tW0O%~w;>u)wrAYs(3Ew-zZve&4(bk7gnZ|q3`?XqRJ+`f zJ#;K^c7Yr!s>&BD%4bq~VK7xwO}q2gmuE0NP#p}Z!U}pP@xT){h!Cqh$b76gQ`ycf z2kH{cWWET)lGGE9)7wMX^uphrl=gH~!5=)k-RJ)FGIJ>`sZU=&_k)8{F+M#t9}uyy zG1ViGf*S^EVpLIh_N#bu67$w0WIoIYxyvdU1e`8ypQ8ypCE3?#wWm>1w;QQl?eH(B z@dMb`a*7ovuvt{{yH>VqK#$GALnHRHcXM(D=^HM>euNE>G}pnv1N(@>P}KzT5VJkV z$y4lo6`Or8El*OvSIAUdkAB_oO7Y=`hyby!N@( zx3u_}GVSRq-eUf>Y^LhJTG|Cmz-*L6_K0U3&)dh|`_QhvuWj?P1&2v#vHkQrrhWN? zz710Jg`#q`O@#UzFprY*%KO2c7q&y5wRwVXzGv1o?P{^>V||!*@z$h~*a7t_7<3bD zw)_!MbQy%J!^Sg`*DxA-%l?a2R6s2IfrSqbj44*(o|4&drkYQ5N-Ce%Iv_STQF7-7 zIdw>I+6=y_XV;~h~ z){k`0uE^WIuYc`2(tYM$>2R5}d9!HrbJfFfEPH##xG2^*{8M3r-1+N`VKaC@cq@v`-g{CxktA9*XU%OsRCjjKw{z*M`XKGf za}()<)q4kcEfqv@RWG7(CIpxw(}nfE{&9G;gaCT}`@@M2Das`r;hN2G6l zqT_+?3$M>-FB&Rq?);!A#=A zUS{aLF}e`38WD8@Hmgx1Va@}x?70k`JlAPEr(cRw%gz;j%{A@nhsWr;p`wTTJErHe zUY?Hcd$^5LVq6rq3#bvE3drll$2=gF`}&gvOWXN25~RwkiwcBe?r6iz0vm6dPN|rY znDV!;P&ME<5z3$R9A`4ug+UMMrDlW+FLjwmRkLkNyjW_R-%gq=ZI5J_MffhhJmy|o zvbWzj^sMdZZ+iAo777}kRJvajlK-Z((8Rd~_rXrsrGSgjC?#j)b0B^fE&Ipsm3RO2 z)oPNOnX1O?wpUm$|A=_`VriPzoAc&g+WDUmMqegFt+%cW1#ZUu`+*4(a0jO50Wx<4 zEviY~p<6bjYugp>Y&WW*ok!6&;$B{Sm*xJy{3O&!b}05FG&83=#jl$K@~#XM}<^7Th;vWj}XYggXX^fUh# z&cl2ArQi3lw;U4D$QtpKO(@wZxpq*t=zvH}9<6gHyH;+@b4#_j(k4EgsQcQUtYz;W z9U~viVQM6}D3(_84|cjI1&__&sZO5B$zHpZHPX43G2PB8YxQ<$GU5pHhBzU5@f3yj zdiJ*8d=uBAO;^}H?;ko_JNhgynxBg|p?KdsKajx%jm6v%M$ye@8CExKobmfZ5_&I9 z4}58OQqM7H^zWOQXZhr=?9$UqEoXM#7?O>8wC8Z-Cf1F|UM(JFX{4AfHCg@QpSzdl zyXf8UyJ>4fqs>6jMr4viWkSYGW#x^u<}xV_?C=zI{Ylc<2Y#uucyLPFe&>9{9RAKyX zHfh{D6d30)eL$cGJ_8-c)2v=tK1~7|O4v|`3u1JH6KzgGwfqnvH9{2%{ixbum~>?H z!8hE1A8Wv7XrdKC?mE_h2)mb269eQi4G(P@)Pi}iKNFiosweQ<7I~mJ^aD>KK!p)T zrzfK)op78ToRn>1W=vpg&;^U^u;UX?K(<)20(d3h&&n7~fP5cDsEoG$U=s9ngTNT( zh`@GZ612e^$Zb?00e_PZr}ql32C2fpFqzB`+f5;-0h~LJ4IaU^ zKvkh50MK;epWo2SAfwI@^1qV~ZXjqtg22-qN-jm<)$g$v2@bxcDjP?JyjlEyr3gB;w;jo{``ufB` zg4E{KEpXty1}cXC`w{d5*}&bS?%3A&^}Qhr!!TA?rT{sqcOH2kdf z|M6f%7s%E)5~<|R3TVD2nTbd=!J7n&;Bb03v31v>f#L2SjKJQnbtZ+o!MGe#iJV1Tn3ey~n*8)2e8;Vmob^Iua41it?UX*SdUK(i$BM4j5*?SBm;OT`;yM8tidTp{8`PM&Lzinb_oYggA5Je!;pP4l)V3ouK(Od_nmZRf?wd) zAtiMXU06XUhIyo8Lq03+EQ+RxV;5dv=@Jh9KP#amG3+h6euKi~4>*`2ME5WxJ_Q!e z;KivB9_(%i(Fqg&dF(6HmC^7oiTvXwNk+(f;n0PH;x-512N2mkQ9u#=3&BXiI0ZYs zAI5xub6Ew!u(RG%56DUzuqzTUP8Gvd9p!`{pi}uIA~BS3n-%$|gbTK;i@-s{X5=>+ zrs?2q9VU1zIX7 z4a;6|b@V!*bZ*Gs1#toE9YTcTQ-9aT(5H>|jp1#D7?44RJ9C;R7$Y zLnSp~!HQzPAX@a%i;P+)w5qUzjt#QmjBWu*#$P+wukJ#XW^11RkaoMF@gdMmlO&qNK+K6dv!vC1k zM|m(c-mOn&ArfP{@#M*l&h4>Uh&dZ5IEX;w_lhf@i7{VpGcEz}lRmk6#J%kwrm=u6 z2zu^#0yM;o>ot(`C8=Q{0=w;|=i*viJ!0T#S}n@8N?_1gwl1jr1*e} zcJ=h+)I@n$aW9U_3*aqaueNXYMZe=$W7aguSm)U+1AK`TX#!y=5!zy^|4MR3fg4?P zQLm<^O7BX|7GT2+_6JBm@(AmgPGq{KujuiRR4n5U2Yq5{9C6rTI;H(Yw2>`8qLT*X6vu`?Pp*E3LOWt<>bXjY6D9e3mK{O z{(*C$Yc1cZoxnkST$ab1=+w(E4Tyb4DUvvTX!-D`g^@i_g`pgz?pi+jjOXD6t=83k z|2Lm6R$Qvf!I96mT=K3~a9kUVSLJ>NCe#4wts}~68TM}@6V)wrC%1Fu$wS8F?{Z#* zZ0XyU;+T6T*MoY*6e69W$8W0Ogv!e-dddC$YcaBGCq-7KKlEst?|fOVpphgGs2aIj zKTc9^Bi(CK-Kn`+3g=z@FKHB(Jm~z^F)2G|-L}v1g?p8fWrrxYiH{l!rhy^(y(FOS zeq+IURHt=ofO;a(RaLb@Ai%CWVUvY ziKuH{8BXRteA4j2*4)-d^E~8ILM1L4U-|1@N#=-)t8#n>wda(hV!+;$(H`U=A>#ys zVG^$k)}MlD!1J0=O+h0dg2bA$z73?b-d-~jH{$=rcd#x1O<- z-CW$cL1r#u(Qr>Xd2v?SBbj0xU$Wn#%~n)W*j2B@R~9vZ>|TUj z%_DRuV}1y{mW#TJk*Zc}Df!Vg-wp2ekLbZ-I+`@G{ub>Y;aL0!u0_}#$&?mchk9L zMz)Wm>r}`({bRd6xw%Iik$oLKVDG3qm!ZpHb{?%QqF>5=5YarTwoKs-5UL+|PJNdF zs$|L4=h6kue4h+k&sux6dkdtHyKB$d1lD#!or^RGMw6JSd3+Ao+ zOWyY=y8G#xr+(6!oyzraFSyj_s)p4(-#+t(hZ@V3-S z&~NK)E?cUgiSBw<{M#{*0(I!?Fgi2Xfsh>xnEj4=u%(o;r>q^NcAi3q`NXYDE2`e? zNiM8;5MMVJ$s)_)euTVOnKEUG6L!-pS_WeJ%w+Tw=JPcpZ_cnDfRxqCCyo3YfXyurXtF05&c!t8Y|HA z`m;THb+d~oPKZ*<%%*1LPhPCf$&-@AP1emv9h2R0P;GBY0-F@Sixq#h()ZWm_lNQC zSNT}4Aq>xK-OkNulY0sFS;x5Cn)c32D+dO2ZOh#BsJMMx*3NZ4CQ_;Bt7EIm@ke~- z$2;66H^!v5HH{dQ9yslNqGjt^TPkI=hB7*q>`C8I%JEc{*^tKULJ_B~T7Z&MC<~%b z*i=35wdj<-Pl0B&SJyXl@sdI2^vc8eL=GvEm+JDt{yz1-n`G}NsH;v26>TfBbggN) zY+sRFrsd}Q#(2!ry?yUIN7z-l3(FnfRoi6d_jkT&dUawf^YH9!hw-5{<*)$rz6T@U zV!d~Gzq+OVu>ZlpxAWdRygHwFfA)Q)opeRy@}>G?Jm)y$e|-yNxlG*qyRn4@*DIwAQC*1r4BbA#QkY!f$!j-*`O9L|Chsm$9yt@(-|%uebP9MoD`?p)s?yF=-p`a{En{)^X)`Y0K57vvKU)F@jNoOr=C z{X)Z|{d7hMN1NO*G3-EPeDA4Y`xE;wTz49_6CU}taA_$g>$`F*i+5*RD~r!7(>I7! z!TC1@s%OiCOzXO=3z}Y(^?iHBk`q}%^Uq0GJt4XrsI_bBtH=7gY{!ScO(`u6yh(8K z6?_$^^>ye~u)c2pKxVsCI=q(GUsYsXP{NNf%>1V^Nw0b5&LZGb$84B~OPb$^h!72zx|!%w(W?=D zlguK!)Y2*`!+wUpG6Nr09qL@Ed-1^BQaUbk);d(DRc}vvaB8}|LdF4S>GA{9&$e^6 zH>PgqID5#LH_u$JAf#l>@qvK%ftLaIhF%^29cVS*RL!}s@xy~*-Rp=@MpWsK96%R8)x3_eV6m7eV`~OVEazDrgPr%r&^;` zj9cfeeI8%<^*yXNbH4iqT`Dagq?seYIgmabpGqmITb&-GiD!T|_G?2yOmGb`i6T`EL$+bmm{IWrm9W~#|=6;EeukCSVOR;2rsmPpJD z&?hU4VG|BE39by)EoupHP-eB(*0Ks`lbgS(0lCFn0JpW@@cy_pCILxKwO@CwYbc^6xTZx(${lIDF6nl|S$6 zmnE(nJk@8~mnB1ZC)RDnd0}ri%QZn}9swak9qF3WO?f%qCQQ~UGo4ziWADdH2jb4m z=F;!5j``Qp{M%^{e{zFMH{t&fhTvu5CJ?UudW%akq4?+8GU(totS%sgOkqR#Zc@UN2XDl5r=<^#P<<~&!d)4@VN7{@3 z?w|Yq%kO!u?#A(fjpAQ91-Zr~+Qr~Vh{+GYHyEdQA{_y;% z4yyz%9Bz}?z{IO{fF>;g$3nC3tSt;z#$X-_VpX* zS&i#ufAQ2!(&Lawbl_*<&q`Quy { + intent.setClassName(applicationContext, HomeActivity::class.java.name) + val startPrivateMode = (intent.action == ACTION_OPEN_PRIVATE_TAB) + if (startPrivateMode) { + intent.putExtra( + HomeActivity.OPEN_TO_SEARCH, + StartSearchIntentProcessor.STATIC_SHORTCUT_NEW_PRIVATE_TAB + ) + } else { + intent.putExtra( + HomeActivity.OPEN_TO_SEARCH, + StartSearchIntentProcessor.STATIC_SHORTCUT_NEW_TAB + ) + } + intent.putExtra(HomeActivity.PRIVATE_BROWSING_MODE, startPrivateMode) + intent.flags = intent.flags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + true + } else -> { intent.setClassName(applicationContext, HomeActivity::class.java.name) false @@ -124,5 +147,8 @@ class IntentReceiverActivity : Activity() { private const val SPEECH_REQUEST_CODE = 0 const val SPEECH_PROCESSING = "speech_processing" const val PREVIOUS_INTENT = "previous_intent" + const val PRIVATE_MODE = "private" + const val ACTION_OPEN_TAB = "org.mozilla.fenix.OPEN_TAB" + const val ACTION_OPEN_PRIVATE_TAB = "org.mozilla.fenix.OPEN_PRIVATE_TAB" } } diff --git a/app/src/main/java/org/mozilla/fenix/components/PrivateShortcutCreateManager.kt b/app/src/main/java/org/mozilla/fenix/components/PrivateShortcutCreateManager.kt new file mode 100644 index 000000000..d2e0316d6 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/PrivateShortcutCreateManager.kt @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.components + +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import androidx.core.content.pm.ShortcutInfoCompat +import androidx.core.content.pm.ShortcutManagerCompat +import androidx.core.graphics.drawable.IconCompat +import org.mozilla.fenix.HomeActivity +import org.mozilla.fenix.R +import org.mozilla.fenix.home.intent.StartSearchIntentProcessor +import java.util.UUID + +/** + * Handles the creation of pinned shortcuts. + */ +object PrivateShortcutCreateManager { + + fun createPrivateShortcut(context: Context) { + if (!ShortcutManagerCompat.isRequestPinShortcutSupported(context)) return + + val icon = IconCompat.createWithResource(context, R.mipmap.ic_launcher_private_round) + val shortcut = ShortcutInfoCompat.Builder(context, UUID.randomUUID().toString()) + .setShortLabel(context.getString(R.string.app_name_private)) + .setLongLabel(context.getString(R.string.app_name_private)) + .setIcon(icon) + .setIntent(Intent(context, HomeActivity::class.java).apply { + action = Intent.ACTION_VIEW + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + putExtra(HomeActivity.PRIVATE_BROWSING_MODE, true) + putExtra( + HomeActivity.OPEN_TO_SEARCH, + StartSearchIntentProcessor.PRIVATE_BROWSING_PINNED_SHORTCUT + ) + }) + .build() + val homeScreenIntent = Intent(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_HOME) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + val intentSender = PendingIntent + .getActivity(context, 0, homeScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT) + .intentSender + ShortcutManagerCompat.requestPinShortcut(context, shortcut, intentSender) + } +} diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 6f1ed818b..4cd71f06c 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -9,9 +9,13 @@ import android.content.Context import android.content.DialogInterface import android.graphics.drawable.BitmapDrawable import android.os.Bundle +import android.view.Gravity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Button +import android.widget.LinearLayout +import android.widget.PopupWindow import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity @@ -54,15 +58,18 @@ import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.FenixViewModelProvider import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R +import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.collections.CreateCollectionViewModel import org.mozilla.fenix.collections.SaveCollectionStep import org.mozilla.fenix.components.FenixSnackbar +import org.mozilla.fenix.components.PrivateShortcutCreateManager import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.sessionsOfType +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.toTab import org.mozilla.fenix.home.sessioncontrol.CollectionAction import org.mozilla.fenix.home.sessioncontrol.Mode @@ -84,7 +91,6 @@ import org.mozilla.fenix.onboarding.FenixOnboarding import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.share.ShareTab import org.mozilla.fenix.utils.FragmentPreDrawManager -import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.utils.allowUndo import org.mozilla.fenix.whatsnew.WhatsNew @@ -212,7 +218,7 @@ class HomeFragment : Fragment(), AccountObserver { val searchEngine = requireComponents.search.searchEngineManager.getDefaultSearchEngineAsync( requireContext(), - Settings.getInstance(requireContext()).defaultSearchEngineName + requireContext().settings.defaultSearchEngineName ) val searchIcon = BitmapDrawable(resources, searchEngine.icon) searchIcon.setBounds(0, 0, iconSize, iconSize) @@ -251,6 +257,10 @@ class HomeFragment : Fragment(), AccountObserver { ) { newMode -> invokePendingDeleteJobs() + if (newMode == BrowsingMode.Private) { + requireContext().settings.incrementNumTimesPrivateModeOpened() + } + if (onboarding.userHasBeenOnboarded()) { getManagedEmitter().onNext( SessionControlChange.ModeChange(Mode.fromBrowsingMode(newMode)) @@ -290,6 +300,11 @@ class HomeFragment : Fragment(), AccountObserver { (activity as AppCompatActivity).supportActionBar?.hide() requireComponents.backgroundServices.accountManager.register(this, owner = this) + + if (requireContext().settings.showPrivateModeContextualFeatureRecommender && + browsingModeManager.mode.isPrivate) { + recommendPrivateBrowsingShortcut() + } } override fun onStart() { @@ -543,6 +558,34 @@ class HomeFragment : Fragment(), AccountObserver { homeViewModel.motionLayoutProgress = homeLayout?.progress ?: 0F } + private fun recommendPrivateBrowsingShortcut() { + context?.let { + val layout = LayoutInflater.from(it) + .inflate(R.layout.pbm_shortcut_popup, null) + val trackingOnboarding = + PopupWindow( + layout, + (resources.displayMetrics.widthPixels / CFR_WIDTH_DIVIDER).toInt(), + LinearLayout.LayoutParams.WRAP_CONTENT, + true + ) + layout.findViewById