From 97b63c4112dbeaeca438afb8cc12e8e6982dd1e4 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Fri, 2 May 2014 23:03:34 +0200 Subject: [PATCH] Implement phone affordance on lockscreen. Refactor the camera affordance into a reusable view. This change also swaps the asset for the camera affordance. Bug: 14488709 Change-Id: I0633614f6a1ea81faa37923f748af3c635e64a52 --- .../res/drawable-hdpi/ic_camera_alt_24dp.png | Bin 0 -> 407 bytes .../res/drawable-hdpi/ic_phone_24dp.png | Bin 0 -> 444 bytes .../res/drawable-hdpi/ic_sysbar_camera.png | Bin 1517 -> 0 bytes .../res/drawable-mdpi/ic_camera_alt_24dp.png | Bin 0 -> 286 bytes .../res/drawable-mdpi/ic_phone_24dp.png | Bin 0 -> 333 bytes .../res/drawable-mdpi/ic_sysbar_camera.png | Bin 1060 -> 0 bytes .../res/drawable-xhdpi/ic_camera_alt_24dp.png | Bin 0 -> 486 bytes .../res/drawable-xhdpi/ic_phone_24dp.png | Bin 0 -> 530 bytes .../res/drawable-xhdpi/ic_sysbar_camera.png | Bin 1998 -> 0 bytes .../drawable-xxhdpi/ic_camera_alt_24dp.png | Bin 0 -> 736 bytes .../res/drawable-xxhdpi/ic_phone_24dp.png | Bin 0 -> 736 bytes .../res/drawable-xxhdpi/ic_sysbar_camera.png | Bin 4172 -> 0 bytes .../drawable-xxxhdpi/ic_camera_alt_24dp.png | Bin 0 -> 930 bytes .../res/drawable-xxxhdpi/ic_phone_24dp.png | Bin 0 -> 904 bytes .../res/layout/keyguard_bottom_area.xml | 26 +- packages/SystemUI/res/values/attrs.xml | 6 + packages/SystemUI/res/values/dimens.xml | 4 +- packages/SystemUI/res/values/strings.xml | 2 + .../statusbar/phone/ActivityStarter.java | 28 +++ .../phone/KeyguardBottomAreaView.java | 136 ++++------- .../statusbar/phone/PhoneStatusBar.java | 13 +- .../statusbar/phone/SwipeAffordanceView.java | 222 ++++++++++++++++++ 22 files changed, 336 insertions(+), 101 deletions(-) create mode 100644 packages/SystemUI/res/drawable-hdpi/ic_camera_alt_24dp.png create mode 100644 packages/SystemUI/res/drawable-hdpi/ic_phone_24dp.png delete mode 100644 packages/SystemUI/res/drawable-hdpi/ic_sysbar_camera.png create mode 100644 packages/SystemUI/res/drawable-mdpi/ic_camera_alt_24dp.png create mode 100644 packages/SystemUI/res/drawable-mdpi/ic_phone_24dp.png delete mode 100644 packages/SystemUI/res/drawable-mdpi/ic_sysbar_camera.png create mode 100644 packages/SystemUI/res/drawable-xhdpi/ic_camera_alt_24dp.png create mode 100644 packages/SystemUI/res/drawable-xhdpi/ic_phone_24dp.png delete mode 100644 packages/SystemUI/res/drawable-xhdpi/ic_sysbar_camera.png create mode 100644 packages/SystemUI/res/drawable-xxhdpi/ic_camera_alt_24dp.png create mode 100644 packages/SystemUI/res/drawable-xxhdpi/ic_phone_24dp.png delete mode 100644 packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_camera.png create mode 100644 packages/SystemUI/res/drawable-xxxhdpi/ic_camera_alt_24dp.png create mode 100644 packages/SystemUI/res/drawable-xxxhdpi/ic_phone_24dp.png create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java diff --git a/packages/SystemUI/res/drawable-hdpi/ic_camera_alt_24dp.png b/packages/SystemUI/res/drawable-hdpi/ic_camera_alt_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..253c73792a720f677f6a1c4709d869f40206298c GIT binary patch literal 407 zcmV;I0cie-P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 zVoOIv0RM-N%)bBt0Tf9@K~zY`?bSU>13?r3;16OWRK&&q7va-c`UvA{XYe zFeRO_OeAumG-+#5T|aSiQuggA#-Vy<zu%8}kgWZI_I!+Ib6i^K=yNsFOjZZB9W@7nkKlC7T zYmpqAHpekC)nFUuHEMGk{zY~7nUTBjJNl2`6mKC8f6Co^=7<0Q002ovPDHLkV1k{B BoWuYC literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-hdpi/ic_phone_24dp.png b/packages/SystemUI/res/drawable-hdpi/ic_phone_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..a6a644888d22d0dbb76308dd6904541475ef8387 GIT binary patch literal 444 zcmV;t0Ym004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 zVoOIv0RM-N%)bBt0Xa!TK~zY`?bJO>LopPG@#ktmM8ub&lelzu_jM5c7`4)Vv7i?MKWNH=gfTxT*#@opUhdI?%D&LC1#QRk z+~@T8LVY~9m;<^sF*z|zkuF`{#u0>fM)c9WMi5GRXp#^iWL{5|5QGM!T4Px#AY({UO#lFTB>(_`g8%^e{{R4h=>PzAFaQARU;qF* zm;eA5Z<1fdMgRZ+24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_000Ey zNkl5(I`Y+sNeuD#EptLAc{sb z;6hhUAcCS1vvAmmppsUU7?O=Bgha(5A*eAqB>f;FB4udKE>4ni?6h57fVsXg&`Io`jwmP$z*6h0K$25tH?*wHTC>-N%YhSZQDW_HU|S&ABy+17>xJH~*0TO! z5H9Vjn*}7O)&ceb@1mCa)W*&LE&@&k4g>xHF0^kIddH*heVO%3fK~y^G=U?5w}B6U zN|Gdpx~GW5Ruhr?MPzLlTOlG3ipVw*nUUUTiAXcoS_Rg1L&N&@##6PeW!%K3of+UM zv%n+3wZLRf<4rOb#4I^R7Ra3})C`uN_5FfK(fB%K%^YDw#EG8{+y<-#&TPYoGhVUg zaK?Nr1@;5K8uJstapAi&)GK!9uo?F6ER1c^0&V~vFzZOzG|zlQOcL9HjljpiZlGav zYQPF$HE=U{uW57k0`~%M1q~+Q?z{{6X#tjw)B zO+!ILWr#eoDF=0#!LgK1K$7}a@hS>b`Dj6m(iG+HX5%0-;td^LlXuxYfY2+_y*KMDc$|v3)7{* z6JhKC@J?=zfeYh_V~h1Ea6Ygq_q`ij*fprzc@_Ox?)yN6aeqDt>-%dBskd1keEf4F4}%01bDgorHcyVo!>qFm#si8%q zV~_RoVZ`^}9mbZSsd^~FB&d7T(JO&t3U$2-#e7|C?!Rb3>X=01C|)fFCJbc0zS{aK z@HJYOL9ry@b2b4#7>!7CXsOv_<(MgKp!^lF2h%uD}X103h+8`Ik3~TydSs&cpRYP4BUiP!(L$iOqLX)5ozSQ-(^u0R>bOP`` z@C=$1W;0s2X*yEiB;W<$Jv8=8zXO!DOccn^jXQx`jmarsr-=M!^Cr;Oo;B$0@^G>g zJn#pNBG0UOr084ojn-OZsk@qEIt~99-KXQcUc&g(QBlMvUB?)m%aet8Mn`@+5u3LD zFS7Guv0w%`Ch*u^%J67iM<2r%bQd2267&bEX;@sp-t|?&S(N;tb=X*xzpIWg!U!Xj z$N#GTd#8aqSRDWW03~!qSaf7zbY(hYa%Ew3WdJfTF*7YOFfB7MR53R?F)%tXGc7PT zIxsLUXlt4P001R)MObuXVRU6WZEs|0W_bWIFflVNF)%GMIaDz;Ix{yqF*hwRH##sd TI(Pg)00000NkvXXu0mjfK0c<@ diff --git a/packages/SystemUI/res/drawable-mdpi/ic_camera_alt_24dp.png b/packages/SystemUI/res/drawable-mdpi/ic_camera_alt_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..ee1187bfe2e958d1b33f02becf6e95743ec59749 GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kae-u z)5S5w;&gJt0{at*Kl)iVb87ad|7c(IP(FZ#`$O7}_C-9>drm)Sz3`!9L6JaB!-Ws? zJvy8Zd$CEgIVx;PjqvShliARrA<*Ptr^u__Xp`BtIN@6&o2Ej(ZXK_g!#zifeESLM z{qfA^7eZ3pJ&ZmGTvF&=);Rr?pVH0CD(u=ik1QG{oaj*2%Cu4R`l5 literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-mdpi/ic_phone_24dp.png b/packages/SystemUI/res/drawable-mdpi/ic_phone_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..2286bb4cfca1cc4e24e32b9f5f940b32b7e4b811 GIT binary patch literal 333 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kah9I z)5S5w;&gI?#Fhs#hwBagoPOXwr!78!_rIi7=j9J#>k{n>rOq8NjZySFthA$TKhK{d z86Hj96$cLZ^{^GT-A{O0E-BK%dt#SxHP%4hQ-Yb%PeEJ27)~Fdoh|JIvV@eqe*OS%$Ga ZgJ)lI@eRXI^MSr%@O1TaS?83{1OV$+bVC3D literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_camera.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_camera.png deleted file mode 100644 index 1c2d7aa3c480227a13b0702a997bfc4ce6a308b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1060 zcmeAS@N?(olHy`uVBq!ia0vp^N+8U^1|+TAxeoy;mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CDO3=9p;3=BX218JamsR0ASs|27CGZ+}e^C!h0bpxtpOY(Mi zVfYV%3-&Ib3>4uk@Q5sCVBi)8VMc~ob0ioTm?b@3977@wzn!)_J0wuxSbh0sZ9_w~ zgszOqP68?kBHFGS4AqthOzdbC*m6QXVR5LJwDjzT-rio14l^;WBj=p9crEVG7ZDMz zQ9bH*^UhzLcRt^qyt{jMw!}dt=Jw)uJB!oy{Y*Q@ye-9hmiLtKz@Q&DuO+Q*kWlFQ zv@_x=myGK(jVU*Jo}2Ai*|Q{~gU5$cg3+oWi%s};L;nHc1rHca64&)jY?8dk9kcNx z-vaI(JbR3;&OH#l;5tw1!6V0>)jpWg``AWDtocOjZuuD-KH3yW|6tl8-J!Q2>3_Hs zgXYXQ@c>^#=}j9StVuC6Vwl68=2IxJgF(jlFq75V^-_N)_NF?la@gtk%69MlGuM>_ zT6-$?O>eODKHsr%f?p%E21{{bqdVI!LE(w4o3l1cNOU$%KCpO7@_j?O%oK)sjNco? z4;XFWw&3bvtj>v@a+NlWv$1mRcaf*eqJViQ)>Ie`*$a;TYjzO zky*XRtBt0ChRkb?uS}bz&oIAH_<;9pd4@jkSB&=8e)aw}k7)v@3V&)` zPWc*n#$%r6CNzoGTnyToWEJk|caQ&o^X%1T#h17`t{*cxIgQO?F5{)88GPR-zENm+ zzVg>?0fFiF5BN*J&tp(x;lGgn*GZ1OvT=&X3N?l+8izENUf(O}@aM%lmT$N3G^;t( ztgd64ck9l%Z-meQxD3U$%+$!>Lb+X^31@4P( z#R_lZOg2bKaPH~&mDJ;rcZFG{)q?j9Yn->%deX^Xo7Vc<&)9TBZ)X42{`9N&rl?M0 zFTVWP;&4IQ6w7P6YcF5lKix$6b?>YEr~i|Zy*EAKU;LHX^}o-`9$?N@P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 zVoOIv0RM-N%)bBt0b@x-K~z}7V_+BsLjmM7{Kot7$~RIf{k#)f*9_?MQ<|%zZPgD;AF3sk`}CO9L~5G=1wz6CsZ zT!`=??;y57ov0wv7{rlG^JMy)L5pBU)5g*6Afu?bL;a!x1Y3~Q=m3MoA4noV>kufe zX}!#k=O{|;J{U}?Tn-a`F|tNA_( cM#0Dh09$QzD|;f|VE_OC07*qoM6N<$g2F(!WdHyG literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_phone_24dp.png b/packages/SystemUI/res/drawable-xhdpi/ic_phone_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..cd9ff60b432147b42716bce029dc970f3422b142 GIT binary patch literal 530 zcmV+t0`2{YP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 zVoOIv0RM-N%)bBt0gp*UK~z}7?bbU;LQx#Y@oxoDDeWyb1igj=rJ+rF(PIdLf(j&v z#^$0WsGzArlK(#T*MHoLC79L^rBA7<>2FJT>GER{~fRQ_qoTv=YNE1 zRZF%exIyJz3C1OXR6)E#k(2~J4S=Fi4#*e*pB#`h0)9E*$_R|g0TCmxE(dHGffG3( zWCUKQlLFd}fave&*0_RZIbgpi{*|EQUY;q4e`8p7+|~1t7e6FFQNud^oe>)&yH5kl zwoZj(2RO6^4C*xmZ4qY<5XWN&=+;M1*wz|0_1Cm$2WaA2?_|FnqK#*Vc%s)1F~^TX zr06K|885BWR!*$wPNWGKCszi=BS)+;Mh`9SPmbN3sXAY9Z7+51h5em6i3J2{Vs z@#;HMCH_SzF5IqSRrf-XU;u#0lJSar_q~`Un-dUaiI0-;6#?MmyiBA301a%EeeZt* z0G*uL1pxdUu2Qcej(PRjt447ud>* Uq6P_6F8}}l07*qoM6N<$f`qi!mjD0& literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_camera.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_camera.png deleted file mode 100644 index fbd4d6b02ca4601b727dc49b784e457d8a39a21c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1998 zcmV;<2Qm1GP)Px#AY({UO#lFTB>(_`g8%^e{{R4h=>PzAFaQARU;qF* zm;eA5Z<1fdMgRZ+24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_000KV zNkli;5V7_@E-eYmg}Mf{Kb!@h(QPj#RH#s)LWK$yDpaWOKY;5+Ba#3bCA2r!n40~Y`n0dwMN_|a4&@h#)|3-br&lw&z|FDv%R z>x1ID1Hh~-LdNqUX3*il`M@Q>>A-QR_iQfLGUR0`-VCK3|7E1rTgWU8jdAV|1Gk4V zeGCFzO4(M%S;SkzJLS)S?|`3xzwv%%Hn0F6_bg1c+iqK>6Jot^b|7OY2LUl+W47ZX z&bI?0V_`0^1h@vcEYy#uWbYuUPZE+gNoqkdh)CDns$D}5QImU`z*Nn0{x zc8X@W{v&Bxuyqu)&H!4`oTejji(exK8bj2XfEsS$igKNCMaEeMQb4y&^cxDxm$v{5=K?MAA3$#@vJ zm4x__$cVZ44c{{07<_Oygm<$~NzX_+G1RmAjc{F?!=JSDA!QTN3}ryl;>ZveelL);Ek)jt zq~WO8f5T2mDMp zoPggkTLhXH7Q>t#$#=kSz%SvQ!qcYgRb~kI-AD?GA4%d^i^2g%n|u;K@>gz&T_yw$ z>?KP`cSGlRC7YClG=PImS^3P{A0;cjCnCdgGgETP>KY-|Q+>b!jZQ&+kI!M+5kyg4 zKZ)cE-vKjHdQ3PWhB`j@GG!g`De!r?SLEoxg0Gh&`QWo_3!`@?4Iy@Tv^-L{hIe?I zD7NfcJo7q!OJH&wa4O}jVx<#eO0K}K1ePFnz=QbHJqy-4fyvnq+#Ts{%kUK?+E6MX zX6$_6Qj#I9DYjfUfVIF|BmtoC2V$$D_9qn~W<2;k$MlGl8t^J`Ek4_2 zN1P*!J`0Y|kZqdOfd_zlNTN~G`%e4{Q^Ys5MuB`toSRsmO6XXEXPKn;GV&C|8F`Ie zlGdd1Dkkq@N&7;*rrJZ#6GYai8MZn_ie=pUgQ2gOJ6m?Vq#sj8 zmO@B3a;kCkxDg-9zZBZCTQ8FOudL?Hp^{6`+FrGnv`=Go5X~di>W1T_Xd! zcP004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 zVoOIv0RM-N%)bBt0$oW&K~!ko?b$(36G0Tf@jnHMC#7m4D|+P%pb;>UctSscp2UkF zX@dbtnusPfT-8exFCIJ?ym;`U-@q6niuwUKiHX68+DfTt7;oFzO_!amyxAJ&&2eAb zU$dDvZ)U)S3m5Ge1(d=ND9IV%OCpX! zvBrQDr;nAy9EDE5`n9Z_L2uPEs2Jd^M&^ACkZwqUYFgdt;ayDQmDTFf zrVQwbmRXGb*K=C-QyI{dpV!G+Ea)?x#yi~>K_~sZvqqD7)XyK10Uh@9=8QnIe*O^| zP-Dw-*9de+n*ze1d+h;gyt3;?pc&~`Hst4>G6J3O^G{1p`%GvBYhJB8q^G@J7^h-E zSL6$0vZbS2e(6w@T3TEef2C#kE8&?5vF@|6F@D`HDXjwHgx@ z9h3~uvv*~q_$cNe^C*k9x6)NgftJ4!z1&WC(zI)b4RxN8XBdwzy6_mGz;k}N)-L4ke?((H^JyjQ{)XlD^T)1%I!i9_fE&c+KzW`X7 Sk2uBv0000004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 zVoOIv0RM-N%)bBt0$oW&K~!ko?b*#sR8bhm@vku|QT9eJ6ck8Cv=Wi1O(g_vqFnR` zM4-Jba?vJeQ44d^!WK1xP(lz^ z#&Djn%&ycwAK?s8YuS6$v*2+CZ8-n~0nRK-?fbJveg#M!mC!Oi3V^0rX%E`#t)i|< zxJOR|pr7ot2W{nhfHX#(J?WA+ZCQIzEgw8myFKZk_xR7zWKZh$?$HFBtw9-{d89F$ z62#xxW<1hsR$G%=nfFL8U=Pi#O9E82_@9H@$=TQ`spg*8N)59miRbM`WZ-_*MmYT<$Kkl2%w6h= z3_M9|;1@Lvmc(()B(;{#gvwioKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000GdNkl9|L1*1|hDg~opR0>AHs1%G!!6+D& zf>AIk1*2e83P#n~V1@vb!QV6mql%=K8oqlsurTI#UH~3Yv!@H@6yVI5-`S!j*P*Pm zJtnHgfH#3Pz-wx9zhDjkn+3*tV2|V43BU=!5uP3#fRj9Uo0)+*D09dfU>z_Va9sy* zDR40`2bi9N2lV}n>#L*<#sFJ^7X?Pu;VAS1i-CDj8di2yYDg;YmM*z7pu7|41Fit( zs;T4km`a_q{ksIjmGZyJ(@+L*jto(~z)ZEdKd-DwhNeD&F-^_rAIziDJ34ao8}p4Kn#CQz5a)OJ0C$Mjs9lX<&*wg>o0?lTtS zUgrYu07omB!}?3y+HDc8Z3C_bt_99>xWIn`?*glUwGkop0B?w^?F|gZm^goFYH5V} zTZ}Qwj4`_s+<%8L=4N9|Q-pe!r~F$(ZJn1MvtE{WTb0DC_gkp1y=_EgYEdL!RKQwIE?z3kT*$N1IOf(4I3Aw6&06 zh8@A5kA3+mjwpY)EMWEn{{)n^dVE-p4ETI+S-|)-ev)utVp+fd92M|+)l+-^Ciu8W zdzrulB@OPwE`?;Rfdp+WB$!!_vTYvP^HIXK77mOnvft>TJsT6YwQyiu0o_{h+_KUL zHbW*i0k2Om^9W8A8Udcnuq}^ZlR?JQRN$;Kfoa8_90=0Az#kd3qY6CeDDU@SC*S)q zH#y37VUxep)-4VDD)^=J;F%8jU!0xB7Cj3n3I&31|UDyLnae&;8O)Lz9(uzH` z*6!0FdCT@+DPB;NdYZ5&1A4HzVbjH!2Ai)o0DOu~7W^>cJ(~qeZ`yWmG%#RKM&CyE zr`MXr3%ovy4$+8U0G^i^XDp-o+OY4#xjd_ps!_oJd<NDV#tms$!&!Kf6B zf>EWVxDmC!FIjtxf>9|Lm4Z<)Dg~opR0>9=U=)l>!6+D&f>9|L1*1|h3PzQl{v80r W|F@#aUO%7!0000004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 zVoOIv0RM-N%)bBt10P95K~#9!?V7t!6hR!vKZIu#O#l-KhJ;ucMdc45CMFnz78C{$ zEh*>>NM#TrTKGV7hfx#%0UwQ?osUXwE)in|+R#{lQF$4Vkjou66uvThcka&KvNLzg zciR1KzMsv^&dhHHtgNi8tgQ0a079|#n-sr~v@$@NK2zeKCZ!x-AV|?|Li~0TzTyi6 z3EFkXZ)MeYe1TwZbRJ&O@cYXdEH>;(%O}W?j6}&Pk{Gay1E5dyv;|m1$y!HK*u>dI!xC7iV zHoibG?hf$DXn;v~fEA+wmfZn_;mrbA0P_LXnIJ+BE!6yOEu103d)Cbdm}Q8@obPUA zh*@(1mN-w9>-(!1PuZ=omw09tK#Ft9`;C5|YpzWINYLqP%hctoo)I`ek`CXy zz7CT50S0mm)su`9BTk$cQBF{q^|?Xa08g^Kp_WLNCE*IUsL6P?gqTi%IchWfXIaeo z`~p20&(|py4gv)j$oQUDT*|y@Mk&dw8wCjPIb)N3!;|l-!&RwNAPW%SqQlwavB;jL z%i$c>0g!aeytOQO_AWYxbA!U978pR>SNF-)joyV1AV(-;LGk}p>JvXOfK!s|xblS5 zCiy$V2RM{R2NDRbN&ds(1ISa@V`YGcl7CnD02Pw!jWWP%$6TNp;BDan)Jd*K$^Z{^ zcOiKYj}_h^mX`xZl>v@O{_gMrt_M1ijfD>|;qZ+r0gO1@AHoMnvsdy}^VPHW3)>~{ zK0V9n;lP&DBYFV7vCZKf^5nbVa8)a9D(#k1KJaPCvZ;M1&07*qoM6N<$ Ef@B7*-T(jq literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_phone_24dp.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_phone_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..4f7da0a9f14c69407e9c7597a7c4c265c090bd23 GIT binary patch literal 904 zcmV;319$w1P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 zVoOIv0RM-N%)bBt0|iM$K~#9!?c2*slu;PR@$Yzz3^Xc2%odqlNQ{P%46Q}9Driwg zw?)u0A}GX?T9mYFBa{)*1*CP*iA z=lA{r^L*x<_sqEsxVX5uxVX5uxR|n-8}#E%^7PY0fz84G+)`JZvogR5zt}*sFnz* zvjAL{2&l9GbV>y5umB7*OCBI<0q}^*17tE{0jQMNiFzymZ4vmfpDKKWBmD&8?a^ z<##b(_U>Gf=5IgVgyJ>%D9GV}@_WfcMdlfQ&R*&G_JbyM?^%YT_~%3yQI@+C0HYM? z0&MfOL5sFFc;q8&)&(Jz6+^b3OoQmHKFmRR=&rRM2|?-j0bK2Z<==b zNdUkueguAeGfSsceo_EX%*((6eo;G(@{0Duy!yN?0^0A+OO20#iGhV6MpfLKatU|2H%AeWQ8)eMMrsB+F(Pb=D` z?P{bDrHZ!D|57+Eb$cd*GOD@7n>cqe=E&b^%4R)#IYu4LbkM^`J~NI-Um_RvE-o%E eE-o%Ey7L=EYb~#7Sq#4b0000 - + systemui:glowBackground="@drawable/ic_sysbar_highlight_land" + systemui:swipeDirection="start"/> + + + + + + + + diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 1900fea1b7fff..28de6ac32d97a 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -258,8 +258,8 @@ 320dp - - 100dp + + 100dp 8dp 30dp diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index b4a13d40fbcd9..3f0a60f4ba358 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -196,6 +196,8 @@ Search Camera + + Phone Switch input method button. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java new file mode 100644 index 0000000000000..5bc7e5a6e67d6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.statusbar.phone; + +import android.content.Intent; + +/** + * An interface to start activities. This is used to as a callback from the views to + * {@link PhoneStatusBar} to allow custom handling for starting the activity, i.e. dismissing the + * Keyguard. + */ +public interface ActivityStarter { + public void startActivity(Intent intent); +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 3cc22efee2c02..58b3f2e3d6b78 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -22,6 +22,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.os.PowerManager; import android.os.RemoteException; import android.os.UserHandle; @@ -42,14 +43,18 @@ import com.android.systemui.R; * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status * text. */ -public class KeyguardBottomAreaView extends FrameLayout { +public class KeyguardBottomAreaView extends FrameLayout + implements SwipeAffordanceView.AffordanceListener { final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView"; - private View mCameraButton; - private float mCameraDragDistance; + private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL); + + private SwipeAffordanceView mCameraButton; + private SwipeAffordanceView mPhoneButton; + private PowerManager mPowerManager; - private int mScaledTouchSlop; + private ActivityStarter mActivityStarter; public KeyguardBottomAreaView(Context context) { super(context); @@ -71,20 +76,37 @@ public class KeyguardBottomAreaView extends FrameLayout { @Override protected void onFinishInflate() { super.onFinishInflate(); - mCameraButton = findViewById(R.id.camera_button); + mCameraButton = (SwipeAffordanceView) findViewById(R.id.camera_button); + mPhoneButton = (SwipeAffordanceView) findViewById(R.id.phone_button); + mCameraButton.setAffordanceListener(this); + mPhoneButton.setAffordanceListener(this); watchForDevicePolicyChanges(); watchForAccessibilityChanges(); updateCameraVisibility(); - mCameraDragDistance = getResources().getDimension(R.dimen.camera_drag_distance); - mScaledTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop(); + updatePhoneVisibility(); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); } + public void setActivityStarter(ActivityStarter activityStarter) { + mActivityStarter = activityStarter; + } + private void updateCameraVisibility() { boolean visible = !isCameraDisabledByDpm(); mCameraButton.setVisibility(visible ? View.VISIBLE : View.GONE); } + private void updatePhoneVisibility() { + boolean visible = isPhoneVisible(); + mPhoneButton.setVisibility(visible ? View.VISIBLE : View.GONE); + } + + private boolean isPhoneVisible() { + PackageManager pm = mContext.getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) + && pm.resolveActivity(PHONE_INTENT, 0) != null; + } + private boolean isCameraDisabledByDpm() { final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE); @@ -136,15 +158,8 @@ public class KeyguardBottomAreaView extends FrameLayout { } private void enableAccessibility(boolean touchExplorationEnabled) { - - // Add a touch handler or accessibility click listener for camera button. - if (touchExplorationEnabled) { - mCameraButton.setOnTouchListener(null); - mCameraButton.setOnClickListener(mCameraClickListener); - } else { - mCameraButton.setOnTouchListener(mCameraTouchListener); - mCameraButton.setOnClickListener(null); - } + mCameraButton.enableAccessibility(touchExplorationEnabled); + mPhoneButton.enableAccessibility(touchExplorationEnabled); } private void launchCamera() { @@ -153,80 +168,21 @@ public class KeyguardBottomAreaView extends FrameLayout { UserHandle.CURRENT); } - private final OnClickListener mCameraClickListener = new OnClickListener() { - @Override - public void onClick(View v) { + private void launchPhone() { + mActivityStarter.startActivity(PHONE_INTENT); + } + + @Override + public void onUserActivity(long when) { + mPowerManager.userActivity(when, false); + } + + @Override + public void onActionPerformed(SwipeAffordanceView view) { + if (view == mCameraButton) { launchCamera(); + } else if (view == mPhoneButton) { + launchPhone(); } - }; - - private final OnTouchListener mCameraTouchListener = new OnTouchListener() { - private float mStartX; - private boolean mTouchSlopReached; - private boolean mSkipCancelAnimation; - - @Override - public boolean onTouch(final View cameraButtonView, MotionEvent event) { - float realX = event.getRawX(); - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mStartX = realX; - mTouchSlopReached = false; - mSkipCancelAnimation = false; - break; - case MotionEvent.ACTION_MOVE: - if (realX > mStartX) { - realX = mStartX; - } - if (realX < mStartX - mCameraDragDistance) { - cameraButtonView.setPressed(true); - mPowerManager.userActivity(event.getEventTime(), false); - } else { - cameraButtonView.setPressed(false); - } - if (realX < mStartX - mScaledTouchSlop) { - mTouchSlopReached = true; - } - cameraButtonView.setTranslationX(Math.max(realX - mStartX, - -mCameraDragDistance)); - break; - case MotionEvent.ACTION_UP: - if (realX < mStartX - mCameraDragDistance) { - launchCamera(); - cameraButtonView.animate().x(-cameraButtonView.getWidth()) - .setInterpolator(new AccelerateInterpolator(2f)).withEndAction( - new Runnable() { - @Override - public void run() { - cameraButtonView.setTranslationX(0); - } - }); - mSkipCancelAnimation = true; - } - if (realX < mStartX - mScaledTouchSlop) { - mTouchSlopReached = true; - } - if (!mTouchSlopReached) { - mSkipCancelAnimation = true; - cameraButtonView.animate().translationX(-mCameraDragDistance / 2). - setInterpolator(new DecelerateInterpolator()).withEndAction( - new Runnable() { - @Override - public void run() { - cameraButtonView.animate().translationX(0). - setInterpolator(new AccelerateInterpolator()); - } - }); - } - case MotionEvent.ACTION_CANCEL: - cameraButtonView.setPressed(false); - if (!mSkipCancelAnimation) { - cameraButtonView.animate().translationX(0) - .setInterpolator(new AccelerateInterpolator(2f)); - } - break; - } - return true; - } - }; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 0db691414e6d2..80eff13d73fd4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -124,7 +124,7 @@ import java.util.Collection; import java.util.Collections; public class PhoneStatusBar extends BaseStatusBar implements DemoMode, - DragDownHelper.OnDragDownListener { + DragDownHelper.OnDragDownListener, ActivityStarter { static final String TAG = "PhoneStatusBar"; public static final boolean DEBUG = BaseStatusBar.DEBUG; public static final boolean SPEW = false; @@ -236,7 +236,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // top bar View mNotificationPanelHeader; View mKeyguardStatusView; - View mKeyguardBottomArea; + KeyguardBottomAreaView mKeyguardBottomArea; boolean mLeaveOpenOnKeyguardHide; KeyguardIndicationTextView mKeyguardIndicationTextView; @@ -639,7 +639,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mNotificationPanelHeader = mStatusBarWindow.findViewById(R.id.header); mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view); - mKeyguardBottomArea = mStatusBarWindow.findViewById(R.id.keyguard_bottom_area); + mKeyguardBottomArea = + (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area); + mKeyguardBottomArea.setActivityStarter(this); mKeyguardIndicationTextView = (KeyguardIndicationTextView) mStatusBarWindow.findViewById( R.id.keyguard_indication_text); mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button); @@ -1578,6 +1580,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return new PhoneStatusBar.H(); } + @Override + public void startActivity(Intent intent) { + startActivityDismissingKeyguard(intent, false); + } + /** * All changes to the status bar and notifications funnel through here and are batched. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java new file mode 100644 index 0000000000000..049c5fc5786d8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.statusbar.phone; + +import android.content.Context; +import android.content.res.TypedArray; +import android.os.SystemClock; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; +import android.widget.Button; + +import com.android.systemui.R; +import com.android.systemui.statusbar.policy.KeyButtonView; + +/** + * A swipeable button for affordances on the lockscreen. This is used for the camera and phone + * affordance. + */ +public class SwipeAffordanceView extends KeyButtonView { + + private static final int SWIPE_DIRECTION_START = 0; + private static final int SWIPE_DIRECTION_END = 1; + + private static final int SWIPE_DIRECTION_LEFT = 0; + private static final int SWIPE_DIRECTION_RIGHT = 1; + + private AffordanceListener mListener; + private int mScaledTouchSlop; + private float mDragDistance; + private int mResolvedSwipeDirection; + private int mSwipeDirection; + + public SwipeAffordanceView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SwipeAffordanceView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + TypedArray a = context.getTheme().obtainStyledAttributes( + attrs, + R.styleable.SwipeAffordanceView, + 0, 0); + try { + mSwipeDirection = a.getInt(R.styleable.SwipeAffordanceView_swipeDirection, 0); + } finally { + a.recycle(); + } + } + + @Override + public void onRtlPropertiesChanged(int layoutDirection) { + super.onRtlPropertiesChanged(layoutDirection); + if (!isLayoutRtl()) { + mResolvedSwipeDirection = mSwipeDirection; + } else { + mResolvedSwipeDirection = mSwipeDirection == SWIPE_DIRECTION_START + ? SWIPE_DIRECTION_RIGHT + : SWIPE_DIRECTION_LEFT; + } + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mDragDistance = getResources().getDimension(R.dimen.affordance_drag_distance); + mScaledTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop(); + } + + public void enableAccessibility(boolean touchExplorationEnabled) { + + // Add a touch handler or accessibility click listener for camera button. + if (touchExplorationEnabled) { + setOnTouchListener(null); + setOnClickListener(mClickListener); + } else { + setOnTouchListener(mTouchListener); + setOnClickListener(null); + } + } + + public void setAffordanceListener(AffordanceListener listener) { + mListener = listener; + } + + private void onActionPerformed() { + if (mListener != null) { + mListener.onActionPerformed(this); + } + } + + private void onUserActivity(long when) { + if (mListener != null) { + mListener.onUserActivity(when); + } + } + + private final OnClickListener mClickListener = new OnClickListener() { + @Override + public void onClick(View v) { + onActionPerformed(); + } + }; + + private final OnTouchListener mTouchListener = new OnTouchListener() { + private float mStartX; + private boolean mTouchSlopReached; + private boolean mSkipCancelAnimation; + + @Override + public boolean onTouch(final View view, MotionEvent event) { + float realX = event.getRawX(); + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + mStartX = realX; + mTouchSlopReached = false; + mSkipCancelAnimation = false; + break; + case MotionEvent.ACTION_MOVE: + if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT + ? realX > mStartX + : realX < mStartX) { + realX = mStartX; + } + if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT + ? realX < mStartX - mDragDistance + : realX > mStartX + mDragDistance) { + view.setPressed(true); + onUserActivity(event.getEventTime()); + } else { + view.setPressed(false); + } + if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT + ? realX < mStartX - mScaledTouchSlop + : realX > mStartX + mScaledTouchSlop) { + mTouchSlopReached = true; + } + view.setTranslationX(mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT + ? Math.max(realX - mStartX, -mDragDistance) + : Math.min(realX - mStartX, mDragDistance)); + break; + case MotionEvent.ACTION_UP: + if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT + ? realX < mStartX - mDragDistance + : realX > mStartX + mDragDistance) { + onActionPerformed(); + view.animate().x(mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT + ? -view.getWidth() + : ((View) view.getParent()).getWidth() + view.getWidth()) + .setInterpolator(new AccelerateInterpolator(2f)).withEndAction( + new Runnable() { + @Override + public void run() { + view.setTranslationX(0); + } + }); + mSkipCancelAnimation = true; + } + if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT + ? realX < mStartX - mScaledTouchSlop + : realX > mStartX + mScaledTouchSlop) { + mTouchSlopReached = true; + } + if (!mTouchSlopReached) { + mSkipCancelAnimation = true; + view.animate().translationX(mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT + ? -mDragDistance / 2 + : mDragDistance / 2). + setInterpolator(new DecelerateInterpolator()).withEndAction( + new Runnable() { + @Override + public void run() { + view.animate().translationX(0). + setInterpolator(new AccelerateInterpolator()); + } + }); + } + case MotionEvent.ACTION_CANCEL: + view.setPressed(false); + if (!mSkipCancelAnimation) { + view.animate().translationX(0) + .setInterpolator(new AccelerateInterpolator(2f)); + } + break; + } + return true; + } + }; + + public interface AffordanceListener { + + /** + * Called when the view would like to report user activity. + * + * @param when The timestamp of the user activity in {@link SystemClock#uptimeMillis} time + * base. + */ + void onUserActivity(long when); + + /** + * Called when the action of the affordance has been performed. + */ + void onActionPerformed(SwipeAffordanceView view); + } +}