[vlc-devel] [PATCH 1/2] Made database crash (line 308) non-fatal. Implemented repeat and shuffle. Added next and previous to mini player. Implemented album artwork acquisition.

John Mooring jrmooring at gmail.com
Mon Sep 26 16:55:01 CEST 2011


---
 .../package/android/vlc-android/default.properties |    2 +-
 .../vlc-android/res/drawable/ic_repeat_glow.png    |  Bin 0 -> 12360 bytes
 .../vlc-android/res/drawable/ic_shuffle_glow.png   |  Bin 0 -> 11105 bytes
 .../vlc-android/res/layout/audio_player.xml        |    2 +-
 .../vlc-android/res/layout/audio_player_mini.xml   |   19 +-
 .../videolan/vlc/android/AudioBrowserActivity.java |   25 +-
 .../src/org/videolan/vlc/android/AudioPlayer.java  |    4 +-
 .../videolan/vlc/android/AudioPlayerActivity.java  |   79 +-
 .../src/org/videolan/vlc/android/AudioService.java |  566 ++++++-----
 .../vlc/android/AudioServiceController.java        |  529 ++++++-----
 .../org/videolan/vlc/android/DatabaseManager.java  |  261 +++---
 .../org/videolan/vlc/android/IAudioService.aidl    |    5 +
 .../src/org/videolan/vlc/android/MainActivity.java |   85 +-
 .../src/org/videolan/vlc/android/Media.java        |   32 +-
 .../videolan/vlc/android/MediaInfoActivity.java    |   43 +-
 .../src/org/videolan/vlc/android/MediaLibrary.java |   80 +-
 .../org/videolan/vlc/android/SearchActivity.java   |  373 ++++----
 .../videolan/vlc/android/SearchResultAdapter.java  |   15 +-
 .../org/videolan/vlc/android/VideoListAdapter.java |   37 +-
 .../videolan/vlc/android/VideoPlayerActivity.java  | 1017 ++++++++++----------
 .../vlc/android/widget/AudioMiniPlayer.java        |  268 +++---
 21 files changed, 1767 insertions(+), 1675 deletions(-)
 create mode 100644 extras/package/android/vlc-android/res/drawable/ic_repeat_glow.png
 create mode 100644 extras/package/android/vlc-android/res/drawable/ic_shuffle_glow.png

diff --git a/extras/package/android/vlc-android/default.properties b/extras/package/android/vlc-android/default.properties
index 0b9250e..510b090 100644
--- a/extras/package/android/vlc-android/default.properties
+++ b/extras/package/android/vlc-android/default.properties
@@ -8,4 +8,4 @@
 # project structure.
 
 # Project target.
-target=android-8
+target=android-11
diff --git a/extras/package/android/vlc-android/res/drawable/ic_repeat_glow.png b/extras/package/android/vlc-android/res/drawable/ic_repeat_glow.png
new file mode 100644
index 0000000000000000000000000000000000000000..fcf9e9d7bd6f0a5d120805fb75202d4311808808
GIT binary patch
literal 12360
zcmXw9byO667am}N1&JkuC8WUx0Rd4`Sdd&gm2PQRx?v>*q+3c5TvAe{yGxK(Iz&1a
zBqYCm|M<?H**P=k%*>rTzx&*KpXWwvsw<Kb(-Q*#K&q at Hr;XjC{@cI=*#B-Ri(%{z
z$3t6D7N{I$+{PXdSgI(>0eAoX@>`2juxE&nN(LSPaF6Q04F|}|fnrY*dMc~Q6V4OS
z0h|nHO`Plizyc`C$>{pd?FSk7un&6uiHjQPX`@&eTr&)K>AI8LR9>IVIXv_CmDO1L
zQP>?S;VwS!W{q~(pN_d+vJS0Pk9N_UMNl#jSt{Z-D)i(MT8Bnkhsy19#`vkzynFRz
zJ=n)Al!eWhF{FjC^;PISz?hL1Xb|NGkZ#7n%31@^(TnN#Hg0%BOZopJe;BRGkv6&e
z2ZA=BgPCxAkh&{nmNe=f&?32(@&tg(_VjU&nE@;0i5FT4zez9&I9==I1fBSRDHF6P
z*J4dEw at UQ^_U0Rq4+__LZ#mv*IMHD)hW0`?2~bi$I&1lUyeFvfC4pLXh!FxnzZ(lv
zLRgXgX7E`3a`3%a!JmtZ_yDS~kX?WTk9y<OQWrrK4*B`>r|5|km{p4<AAq|CV&sJk
zV6XtQ+X-jpy(<tIrKGRy3Iz at dIhsU)Yd#M|g8*QmJ%o7;BkJVrY|?{c%A-Ps8wI`z
zW`<x|2J90rMyv$BHGD}i2sms-Ka##2XPo>h3iJRSAyX|nr%Pik9=w9o@~p0(K^InH
zFtk-P0BD)BP%MlA at S3Y8%3<rxS?LS7TkI;v^=_5fzsrjgi0T+ at P4P{Dq*8|qhQ576
z3;5!3gszL4&!0ho2-!E`pByxC?QRNRJWWUNZRo!gvE2Tvb$7JY+!}I)<`*NUTsj at i
zzv;j$gC|=juiR5#!g`R7Ob(={r>OlV at ry2s7}&`V9w{mKP5JNoDJRo%(`m-tqd(AY
z!VR-KLvqM6X0*CyO9e~}Y?X4f038fSC2kqL=@Tbl|0sL;O|WNAMy1)~Pqefdv&(m;
z6Lch0$uSS7tJ-&bf$G+jh);0M`$}fSLFbD;zBnim_yaI&0ZAtjyC(5RuOS=$2u-WZ
z5yb5Tx~GpkI3Ija^uBB_E%>y&NHK8oijfFEc>yJ!2mrHHW|22HLD#NCfZF6hwzpb^
z{=MSTFm8pFSGWLtWX4MmsZOUe<;!0$P~Un(!^Q<pB(d0Y+Yo8D2lr#1<Iqz`9#3~d
zK_Bi#g&+Zz at R4MJ%(DeYt*c&3Op7BC<%i3K!(2g^dBN=_)dD#LOzpRO at 7id*ELd4v
z?>o$JZ at e?)Rx!>fo$@2D5}Xna(?2q1(KN;D9E?qHr379ZSm$lYbUA)#&s&LqKvh|u
zpNfhF^r*82Hrzet=Xvx}L3*iQv!eR*u8%WpYz53A4`iim-b%Vo9ieepl9W{0FL^h!
z2|$vYVw3>t55BME8<d7 at lO)zV>cWI<7O@=ejnp<yaoY5=l+jQNUenv at sx!j4J_AQ8
z{7_p2M=KI2DMO61h?C+Y3M at BlaaL{0z=1=v-64ct!EAxVvuaACbm4eP;c&?el at Vvx
z$J%;&?~CjQ8^xRt&DyPVCvfED#BJ2BbwEyG#RQ%A at ZkJ;5;4Q}FgWFD$R!DjuO84r
zx1{(2P{M@|NjF+O`~)Fpqr?S7-@({??_Q=TS0J~wlS<2E_2fBIc>>IW2gT8pX*pxH
zOl{d0x-7mffb~S?k^DHf9Qg-CkH;8s=u6JaF+3RvfB}FBAd#Sl15v8VN`?!-qQjF-
z3<mL7Q#FSG)Og69&&<+tahKa`laylI&J$de90*<zRT)n5X=Qm5byS3FP7eu94_QdT
z<pu at -I6YYTiC!FqEEo~JQjW7Mr69)=4y%C<S5*GtwhD*HQu8UKy^3X8Zr8wN5!JvQ
zCBfYgi<aiY>5}a^<FkAkD5R%HWW at u(5WGbIVD+vGk_50}Cfus%LB(RJ5J=^toKCm`
zs>2LV`kLWIPd@#CfSSsqESj)tLdLIz3Vk>hWe6b^mBwkGrNsi(kEvSkv?uzyBUu=2
z^-o2pz^SwYrxslaLFS^$e(`r>x=(3_ttk<bOe*(dN?(aTm`yH)#@Lq?^y&^lUvS&X
zUmM`iN0CXW-Z8R*G^FE1ou2NSese(fCt0UH$T<ROA_xE;L at ACX2|$^A((s&-i?Y#J
zU715SZ)@pLwGqVl#@tPi6v)73>0G}$*K%j#OzV1>+1sFJ3Shb|P4DG&F8DA4mKbCH
zTqC1l^t)b9Z$HjF6NAx*#}TTvno6am*0OQER;rV_Ya3?IAuUUZkI^XYg5SnUte>bE
zi9WKHDTlHv%WENc8qI<HGK_C54}!P3HhF}Xzc;i;lD#-AN~xr5Vr0#dz-4icC045p
zmRd?*dNVt_74%9WM{C38sDKkLx<E&LA`_ahnE!jh*n7J#E at JKAz|z9XinaNxvFh)W
zUveK4$CC%c(-FPz%Xn1v=su=W_9<}yT}@A}ji+`er9uqJyEEA?<%G<899K$tk92A9
z0U@?5L}>vw0OjQT-U)OrKX2p$p(w!V=|ZU!q(e|WDrE#+8Wy5xw87G8dwFc2x3ms;
zsxe-K@<EAP%77B*<{$UrdKbQ`wwtrLu8l{#zrKCz^{jdIV`AGnaZ6Q?=%X-<mdJN|
z3^vXbcxzBw7>w4qxSL#}y8l!1MXW~4f!prZ-#cb5-wPjwkOX)KRGE+W(@Sa_6E%(!
z$^_Pry1H$bLuolzULY3$EZpVWw~5nX&@+q6nD=*7c=GGWaa{KBE^}aY<Jm#;yoZrd
z`8FDDDVeR-r_CLwi2z#xDV*c%>zo}FlTk4#eUrbmS!Ib=43_Vo&c8W)!Ch=-rqs2<
zAy|m+|3|?6F;>PQSW5oBjY)LBj0y+qhvDdlX2JFz!?luzqD;=dDAO at M93{D0cGYV+
zmaU}G%F5BI*7K#l8AYGU&n>4j>MlV+f?6=^uX3`dQBulBC22XvUv-S{H)@;WZ1w~c
z@%=RbMfsAVL9(TH^kNyP+Z)L+&v%LLRvPR{V-I6uE6Qu2Jzoqy4AAcN-yMg1mMOI8
zQszqfkn+O!H4%iMBfP!5XT1^aIQz0r>fgoAT)?4;K|`PodvlXG^O&`8f|a`5iqrTv
zrJBGcM-8h}={VL4N#%@UJq_E&q8eSEBoiZ}4E8G}80Nj--KI3NKMR;(t>>iajaG0Q
z<-|WMD)b0tcA?2#T%AHL2jj4j+4`*g%a;#1*~2^-Q9QYADkiiX03WOU at apH$vQDGG
z+CP at 0>-I60m7a6__VX4;(To7R_M5NgzB7*6U_cJ(oGsd<zSqfOb$;a-KB3+uddE>;
zXG$+je*@&2(@2=>6G1p`OOeG{O2229LPFMu5`zDZqUY;fY4}YH<2K!ihM+idZ=#gI
zm}u!5O{*aB^!GU3yp}QrQO{V##~_W9ZLaioAJSgQ6#P4<!0!<_>f#w~XO;tPyRW?`
z5NtLPDw!<}4&)_>>+7(qmsoU|h6*!W$A*tjExoW&sL_xukp5$IsjBxxW!ClcUhvtk
zIF)+WcD;pP1_`!8g5YP*V_k4<SF;2m*U}mp#yIX$LVaCTx$=RBty;?>`>mU;Aw`G8
z_ at BDMrSMzebw5IW*QptIvnVvHU7d>Wr>nFWRSN&T9B*A(U3E3m_ at L{b_Rd2g^{kNt
zAi at s_Juu~|Z>p>I+bmq1_E~P$Z}7DL^-wCFc&oojYK1b_y9y%Xj-yQ+8uc)Say27w
zEvqA-YvJifji5^6K(3LXaBVm%N`R(9zhDidbt}2H<zY=d$d!s~LsB}sLG5j!JWzNv
zONa&?i1s`niyn8GG_6pOKvN#3s#FB;AIa1k-xmG*jcJ?SB^_hA&eVqc5iCm6+&Qo%
z8MU3xTn<&#S5ZHErvFWsXO&8N<w^nChcn)XPqBb+F&{2LhMecRb%ZIP-b3<M1DiBP
zAPwrhM59DBaWZtLK}^u!Vmw^dgE&?sC1nMaF(2s at sEX`MdMv?GC9*k8EvBiI4bD`y
z0xaF$*=J>XGu&wlXG^B#FUzH-5_ZlFuL3yBXTO-&3Pt6l==ByS0mWI2p=%-kD(cgp
zxrBuHtPZ8c>DIirDMO$k6EWy at 1O9ZR7}l^^fha3z4;@+b6DXu#044EEi4}+-QJmvq
zE{?uEX+f==hf7moa%`Iu1zE=Ma9H7Vc(U9*6ZWw-LWw!qDbdDcV04G>{o*-trVf)~
zda8CK{+dylLHqr~Z<o_^>!ua{RYs+$PA1H<`7yB8>io*K6Mjdj;Mo0}=Lh5aBXuVR
z&L|z3yuBR<i_?7{e!iuKnluwr{xXc{iI<dm!V-WWs&uAu$?7?i%l@^E8h4>8T>Nu}
z+(OQ~<Cr^1s(ZC}$puFLl1WWg;@2c*9YdBY36P8kr`eZ&%`!E%_Q=jowWrrf8QgZ^
zVN+s7Ns!fe<&tEp&6VpJIJ%D6AMQUD-#9jHH*8(5&@W%84O~lbAX;;?+3r*OR^6z4
zdCK12V(dRFbRRVIMDE5?S1b9XxmhJ<w#xap{>zN7);w=lJJg~C*hL6X&4t-dnoY#*
zgq7~975)}BJ#l&#so%a_Pv}1 at _#KDE5XSj174euq9t8eCJ8{bHrDb8f93Xnw*x|UP
ze2)!3W1;TBY%Oo9wgR>y0McXy;Ea*|r3F3QI&0a?x8~c6|Ni}37<xx at zf_JJCjvBE
z7d5>*Zc#2D at Qug*x!>B?^RxKow4rrV^ks?9t8(IgO!T3dXzOKhh<H1ubN}o3ws2;F
zgTT%c at FxC>Jtq)XeY>8CMqjT at J3i`NT>Lh59hhE5oEha6Nz?zZ&C#f5=ls9r?}AqK
z-ylBJFMrV*JS8li%l>8lx%b=dI!9;|vM~Z?B3r^?%{GirRrA-LDDA{FPyQVUP0rSo
z-fJ at HS*-NQT;f#&4~%N;HTt(CVR#Q$L5@{`VyI(g&)(_Q%7w4>(F4Yx-}@7G7u~nD
z>J5WFGe4N-+*CkafPk%;T!{#VklV at O(trP~Pj{=@&wvtDWwP&1pa~ce{61%rkx}-e
zgT2qMX)@k9NLEHrKA^fMK9MQ#W>39TP8^Nbti$u|>RWfMsWcDW{#nwm-ER#xbbvX2
zG6P%cpTOx}mg4n`@xzl at 9=nHPZSP-aiKogo0B}^In>++TwBQwuWUTgoUdH at j+~pf$
z?&|9G=1Tq&cLtN^qqJ6;)}>V0_ivu!0QruGZ5i#S86n at kAWwImrcS_n4nI*Ff&n%*
z1=QFl+^@PkV)c!BBNY|j`=4Y|+mQ5WwN*dejn+R9$2xd0e>{H?fj<`zpdS!&*I-m3
zx&6{H;L@#iE$cO{LWNd(J<<i(o&=7{UT=?RGe9eeJh?>gTWlE??KakcC at 9dN)uwPG
znpaKgr-kfu+-XVyA<J8-h{#36KdoY2e<3Gf!>Fw%5r2h}hmPl6ZC!5n9zS~=bktd4
z{jpluPMFEy#&qPVTKgpeR2wD?<dpKT at L-<cps+A8T2=M<)1S?I2)2*0Urfgbb82L)
zyv4u1ESCvz9dp^=pAMKF3R7>qMj``^sp2Q`Q5Ile_4-*?d2W7$22MB&U|AeR-ho2N
zpc-Vhw<z-7FY<5C?taw~N4b;=+Z{49o;gfM=4x-Vzyp~ENXk at 1T#H<SF};8OkV~~B
znHV&xf^iBbxic3l`<&+qQHMmTYGk>zgzpmpRlWaKt&_JG`u)J><h!EMLd#N$tZtRw
zMJ-78p11wo5oGQv!28O)eW_fJx$gYDouSS!vde7_$PWOjCD(1TE<&a~{vs7LL9LwU
z)EFG<B6}`9>i8%n2oV-(EFguGtp2T|*!A;EN)(Fy*oNo%p6xo~q5{o}{A_be;w*sX
z(ED2CzTxGZ#;udbZlT2NpJyWVU#*2~PyL(59k|cT^ZlQ{?ffg?mt_sfe2rKAiZ|WF
zbg<~%i5Op!l5c at 3L7_|M3IQ=rygg;%<Qo at sS92Po*{D>~<#2!TBx)Iik^)G84si6{
zmxenp)t^0Ij!$ubC;<!(+~%Ewmi+3{T)tygk6pcTm40EayMZTy at W!RlcweuKTzo@&
zaLZGC$?)PbTU&mdrqcAg at zrFWlXFnu=Fq~-i~?`UAOMhLsac+0y+bmRqW?OhkZGqn
zinw78a6PM<SN`^bw8O6_oOC;5s7T4ycW8i4leMfr19{HE`5~U7Q{)Lem*eA0)xRVu
zE9cLmssaFk=LbHrO=eQ~B5nLEpvfv|l7v=fnPI9RnJ6(YX|~!-`Lx~D3d&~~tzK-*
z at AD|F|Hk2))7SY$6oVpw((3!#SW$7k(d;8qf3VPKxG-m$VEctm<2&(}S at c3J^|rej
z at yE9S{DT6%oc<NIb4uy8WJ?;ewJh~a<{{4hj1>F#m3hdMFXmMfnSZMbc|3#KO at ryq
zw8PWYrdD8;5C<b2cV#9rZi^3pe^KWu!Hsz at 54#@~^}1LkATsjvxB5*_GP11J?m5#c
z!=R~hT?d8c#q*iYhi$k3)?fOo$BWD^&LP)>X=|gShHPd703Z|HwQ~xqcj7^t%OW{f
z2x?D=UyKUjK7 at Bz3O@btoog-A2{A4lr%9i9-nmB;nu_~rH?-Qh`c&%uVx|4pd9PN}
zD!1VsKafbvB*|8=*>56WwJ at qYDrl!^>&g~wjKFJ3gozyY>1EP{|Mky3Mn*>O^0dfS
zhf}R8!wQD|GXZO97?4lx<9$4z7ueKz^2_$+pDJSmmC^4uM4Tu}bSiGduJ)i<lCc0>
zS2j(?R-aHU1z3Fr*t{z%i4HH~qI9E);Z7BTM{5b{K$}J4U+lH<JDD6BwYqdOZa>Z2
zvgjh at yCYh=yFG93pMCoHM;<|4bv5AO;gP>9F8c60T|SKX_sKu=0(`tSk at JJ$QGPz1
zA?Wz7*M$FZ&rYh!6&86+>$UxUNQst6guTH_`Oe4#R5w=aFKjeRFU;LspOnYUR#p_h
z>m{*?&6kUYY5jagQAY~nl;QqWa))#uSup4y`2`<>VeJ*r)8n?{t%m#Z%s&Jr$)b=Z
zp3d_%kzs9EB#+poM+)8RCyELb=@1h#*D-HjCInE16$DY>*qRLO<5ONjG&Pu0tFwRw
zSkSG3)joQ}!(v%)eBgsX8&(<Kl<Dv<yFT}uSV_Mh%YV5OHsb7TTXlQUZzPcy<n4^P
zJXK-B$PlxRm)9QCE8d(Y>@;y{+(Qi<n5HJ<0)_7iH03cWh2xw4vandhl12jo7KlZS
zn-*5;o|8~4ZTd2?o~_>AT!Dea at 2?eCt;NcC9KRW^h>pUh5oXIdDzZeH5x8%KmRJF7
z!kLVTkxc)t)H)8u2J*63dD?Q_*;(*x;6?Su_j at E7G&;u&45g1kjvq4oXIl`qdyUg|
zlTw4xQ7u<hies97!;H8=@~LCG)QC}BTsDYo=~%EZ;&0?V#uiKPo2Yo|uD64iUKE|D
zI;VkBdCVcjSXK{80DX%wM8Uc7hqi==<=%1tYBVu9+4{>5=*h7u(|f%$Y<Z^rrY<5l
z0%P5m#*Gne{@Y4UBXSt%>4$X=1%`-KW|Wz5KGed8TiNadAXz~HwhaUN&1m3DVmY#$
zHmY)v8`UneX79LgPeFn=*u`U)MUdkGC5vP)XklZ~M7#mSp6A<W<6b=V$5xRZ6~T8u
znYOyuBguELgkTd{3Mo36><unZ^iIB_;meaev-Yn!1Dj8xl9j}S{)IZ;pZ<!g at e3aC
zfmGm at Vcc;_a(n6l?Uni`(-%*jQ?*!95wfK at vc5T%;p#`TuQq+nJ`7s3qzt0$v(_C2
z)I2!6Ohe;VmQ%{g*4=7u1sTZ%(-8O!#@8#Pgg~sV(8As+{psOB8q at U}?M)Q2StF1L
z=+ITuvou_Ad`PJATd^(`f95hX%g#0pfcy?jJq|w^+o`21cIjtxGd!{Uu|gt$pR4@?
zL`abTX_8XMpFdn+)|HhN0BVJ0Q|}SJDS)A(APN0r9(Z9aZ~*Qi(XGCXVh%aaWjD?s
zJaBe8@=IuA;*3(#LL|xpHckauS>cGG(CB(vP8>Fq?jv83oS9h~|IzZDB#O at 5{BkkA
z1qK&CDSTW2=!5R<?Eyf?($bQz^-au5U?23id!vCB4%Pa+b}!q)U9U9xXH!=o<@A!H
z`WCU`@nJk}>JYyJz9TBPr)9F?p)1cl)&%oae{RyDF2mCE66ZKJ3lDem at ROj9rd>b)
z!`b<Hr`O_UIw*C*_ScsVLR`9d0#yYyiH~o1Efcw6fIw<;*QZx`#_L}k*b4WPi{0 at G
z+wBcW19Zbay*!m22saA<_?w8-IE;i!T90?FdYY1T)E`YDBMU~3TDZEBLn!L%>PCg0
zbzcFwPtQgPgI=*wM!Wy^PT+U|uU1`p*k)$%Aeo>_4mX at MF}gSc;07s;${;hq8C36u
zExV*1gY at 9Fnk>zE%W;mG!gnDdcjsXc(a}A>4DGJlTPfH(+^*drKds0r?V$}JFsr$<
zGpS|G&+v at 3(t#4S`~m>dmJt0u<{?gjnB-?l^@L2nXsflNsoE>r at F*5zpQ-L=P|8^$
zEn;pk8k!`Y_K}y~Dd<?)fBR3|r(e6<rX at cUsx*)^tRPR5yasSc{9O!J+hd~Z<wR}S
zR#PlEH8zSV6;Eohh(3y at wmDHPkxNZRu&VzuUgb(w7FQM6P|1XZLbCFnu!e>MF7rJz
zUJl;kQ+D;82fLL>M#ZK|h6XLpj_+3UEBo!2%Mld`hrH!A4f9yo9s88TO+Z5uw at S1N
zA=VyBO1Pzb(c9yAQO)bfn7em=m54yIWDLhGPN6y(H~y at pe#+JeBtTL3`4SskQ=ol<
zO}T!gyrFQ|ZUm6;E at Vns#0XcL3cJR<vv(8~KfNp`J-r;SF_m_BUr0tnc^uI1-MPVh
zt9(0`ck}D}-tqB7{x8w3)ZzPwK{9KTEMUfAy7mDmo|=xCvv8tzwKD at rH!xq<>Bgu@
zjZYlWB^UpDwL219DeJlGSK_ND%oM`Gr;So&x%}219~n=1hMq))Ab4O;sH7XdWiEpt
zKV%9=%<{+#`R1zhm9JJh_Vjt~SJmwgJS7oH+ at NoUtLhE@QDnApz3shgslnbhAXX6l
zvclWh<eX3qKW-q}w7w=yx^JT#4-N(Ac-Vb2T(`c at Ci_uSbhsj(z8Z~-Dl5rCz$RNh
zF<^9uiOwSp_X4x;Ddzr6hKQeZz-;u_sAO9e*}D0`^`BWVA6wg9>&VG?S`AN4H&<3_
zOsmfEGWnT79l~+g8bNt=P9xaeW`FT~N#j1TQF<jaX?(&{ThYHbkk3xJsrz!cp&*5{
z*$=E7;jxRog at uJRZTi%l12<ZX%pVF%IFJ8%vSp|Us_FE{6%>YW=^aL0$hoUGSgBY@
zFh<CUwmw{aG7nIhDS$I$|M>OPUj_-;eY305esgx)HZ3Mv;{9mj3R_NN8;Y%t!4D!*
z=PADY#U__4XA9HJcNfQ(=WXZuuie}-1ZXCipF5Dw^Er?c1X~o|(|KgX$<kC6aWWP|
zj|)ugdNl;!h-XrsgA>vcaNs#Y=>xovH?S$nfG<ru?AeQ+YNEAL)5IK=)uu|wf=nu-
z`k at MxPEl(VV}sX2hywya*l++XFkH@)B#g|6?~g}ty>TVhw#Z!fe^}e>2zY&^e-Bdr
zleIkQX6AJXIo>|oX+AXl&dYCFP?qIRnzE~?=!sl_f0;)wbzSH^EiN<i_Ni)hlZa7`
zE)9>C_WES{+J;lQzO^;c)NsUM at YBxIq!r&b85VjN8q_I<9LBY^LmvFBLoymQ9Po-|
zJmKuvUL%kdwTab<h$}ZWnGEm52=321{NPR-G5uz^um6Y~+cOt-V%+Yji@&4;G-ac*
zVAR?S%XhaE2b(@VFPDRSB<gEx3pgm<sAb9M`>}m%)VNFG%el{fJ?ES<)q|@o`4GPs
zfPgatUEWsk)vIKCL;qk~pVEfb*3_&=MVV#VjE(e3X8aMrc2l^-S&8#^fyhextO>7N
z)S at RBIF*i68V3mFdDl&y)?I at 43d>BOUzR7SH#&JgN^_{v5Beb{`jdf?x&C<<{&4mb
zmcRZpu|NN)*(b!;?=;t^u6Fp5JSS5EUIBGH`~E7*z5jKW*Ub!1-c^|13n6L-UmYCe
zQXo2d&;dv^ZSi)t*>64PzwhHin;an<$cVfrZ%#q+DUn6&yeRU07abW%=i(bjXnF>6
zP3QRWg)ji6eWuxGT;#z2Q5Qf7H=E3q>)96 at KWp01M*F-9_)(#sN0R;hSv<8zb+r~&
zV91Okmo{F$xjr};sxZoKOiL5vWO at nFDu7G~lCU{N=0jAGvzzfHhB9Ua15xmyY?gyU
zprZ&GLJ!o2CpuYJdHCJj96DFFU5%pmjuGi)Jg4+70y!7QwKYA=WftU-6HisUcTO+Q
zkaiu`Zu?J^Q3GoVvQaPSJOKDv0 at +6o&53|%MB~fypjqy;4_lFuCSr4nd`d7rF_Da4
z7f0PH8HY=)E$+MfaeK$^qwG=zkSOf}B%?UuDf<i7>(M#$47KXtSsF=z>rkK0YAaRO
zOxxqjNmad*%(OIgZgZa5uj{SC;oge<USBRM_Hfj1#^Mb_j?LQ(Xtlpd|HSEsaTg!0
zp%QJ0f5Ojzx1SYp0De8{$X?-W9%2zgzOA%J{`J~oTj`J5U6~oNjedEMtFP>jpX2Vk
zyNz-4%Vx`$7o!I|^M_8aX=tAyBu6!eFax68asuem{M0sI68B&vqeOyIK?@NmPyRfi
zS6XM<$;HdrZS!C=qh9KIYo}|v{1KKa0a=i6Y*Mm6gPp}m4~jLsmH8ZOX4oWEeHuKB
zHBscL=bssIPPq%D-$_Gln!q2J;YgZn)a|%Mm5*=9c>-Ao)^|*2LpF=$@>Viyw9iED
zWlLWmJ+9UheA1WvceR^dsXoGprsX8q5)`DuT88wC%HX at pBy#{j-tylpfSx=?&f1?C
zvserQ{NgS{=6qYjDHCjCBqUTaT$Yy>F1JS0BFbOBoanX85>P<uUWwG+7XFpq>=7if
zBqzXz*Qe>j^H}v_n>a*CSZf+%0fW=)bYPu}P=3<5$iC8%zQ|NsYD<4eBP)Sv at sM$k
z961%6PvG+G!}3qq-coCG<LP*AxeB(&;E3s^*3sh;JAY)T*yJp%LAY&KPx2#~JFcv(
zeUjj9SAXXp3O|C6W+GrVqg{ZdsAqi;%X{Q4x3*N at -d<%7yDm2gx3_+I52H?2os8=L
zH{sY6_w_nr9VLMaK=<qHy_@;UXC=;FKMLRHqDXSc8zeYN>c&Cw)Vz<;Htg0f7b}@f
z*jc{4bvs$@mWrQC?91lV?pr&_cuXrIeQg)8yPoj)@p4OJIxjV4xHeYxbNj>vP$VX%
z^bo}KYNk+5#N5-3>rDX?Nuf!C(5K1aM*V&FD!Ecr<NCK53dpW62Ppus)|9mn)7b0D
z2$c+Ctb}u~H#ZmkpS1PbLXcr>BQW=|7D7zuT3!3D6O at QFS%bcnRt_hhuZaJ(tsAFa
z%&Bq7-(@;E;s(Sf0 at Q#gn|NrmLX~#Vl<$SP at 5T4Srl=BpvAj|TOKi#Co2wzcxOm+e
z*^K21(O4M51r$U!W9l%Zxg4S;1?IfDZ?ET?YA;76PR`()x_W%FQSz{-L?8KWMmSU5
zWe0s-5`W`P$r&rt#1J`uWmnWp!$AaYus~gXp3KRIQzGalb^i;~L0-PiC&R=4un!Q=
zeBATCOhAJkL5-`(nO>~O_pe}ixBgSNJ{3X5ALLIb{mAdHd-puWqoCH5x4b}9GJp$|
z{9d?U=gb^@@;w;K7&gqlDf?$!#zi@}QNLt3cYCouoFUZ^<ac|#f%fI6Rb<s9ego6G
z)RyL{P;TX3i<XsX#`MybWBaUUkI|`Jb&4jn;b2)X!47dpOfm()qN at iz^}&cfKaUI#
z@!09Xa93$CY(d)+egw)2QF?|$5Sdv at b~T=cI%{rv<H88ogQx!B)yE at KI9OE&sYaF4
ziGo(p&@qZ!RFB)ySLoX#0|PmXXRGq6^QOU)I>aQ|d_Kqps4$Z>n?iF1!54q5Y+B>K
zJ99j0n`dGYbd|e^<w`bQiC27tz>E*5f{S?W7r_!uUuk|B9?p6wrat2>cRe6W{k|k4
zWRk5591dAiBj)_D$v(aTH7AaxkC5iCt#QT%+0>rrR{nSgHtE^^blNA+{*L!$*0FmV
zBfchyhnx`w=<tKZ4^qs6OYikZ6G|zrHyUHJH91x~Yx3~AxjC=0*4L-`Cdc+x8&Q?g
zOa6MK&#Ta_f|8R`7R7?A8KJhv<nC}i55wP0$do_E9VQ?`uYcV&VBf%HTfu%wdK}FL
zMnLm&ifl|Dym@`Iyiupd*v+C}rFeOIX*bj5*7})wmU*|oUvJRQw=MKuF at v)$0id1)
zf-ydX{{9#p$l7*_$xR#fIW#qE at xF2Jwz1KQ>wlW6O*}T2;K20!g%2+As@{~+k=Td%
zK-E}tSq{~bL^)pz0Q`Dw^y<L=kjNz96P$!L(6=?Mhlxz_NjjP1SF`e8H*>2W$6cg_
z#B-A?c5egG)fX9K$t3UI;mZ|KZa%ADo6ifb4c-o$ucxUpX-?0|Gt(93;}T=0kao~V
z+5sm9^Gz&lmpYyOV}4%8Nrwqp3(tpJI!eaB=(LHri~GH at zB(i#56!Wt6^+eyQSeA^
zTt`*xPVJnRno1Y6I(*+|W?~{Y`X1S8xStg4sT(=j{Vg<iW^)FAG?|n{1y5=8JGX?7
zwAm6CJu4y}y>#I^{&!#2P8G?oiAa?-ulDKATM&zTp-lY{bUt%WIGf;nmxzk3gsrdf
z<Y>xOjzuQ^jEL%~fcwy)den|)u{ts at 3<(u!`ISn&X3aqFdVOQ(3S=~-KV?Eoh)QwY
zbZ0#mbz$6&TMr0ZUtium^*3;5%Bg(ay}j*l at tFtJLHC_*I|85cd3&PrZ}$^yf`p-Y
zIB7d&DgJuBo&p`($8o-?Db+%;#;Pq+hjv(__eu?}JGFO8at8{)oSd46A`}!`0}gqN
z51E1fi*dY6jo&)wL;?qoN&ft6+@;)Z>bZwWwrG|o>?hrNFhkJ&`sBx+=K(o=TmaTR
zg7u%D<)|8BdZqL9&d1nrltAa~z<|Y<?Y|Dw`u=V;sxXt-O?TqSuOMILkg_u9hgAt@
z$2y`#+N8hWV1-MbRmmH=Qy<OLD at GA?5bwp{it8nla>tX*%VwdqW*fV#EKd_QyrvIE
zG&O{Hmb>Cl#UK3GRSf)L=NYTtjHNBf|Mp?JExs76rcb{~8TbE_x{?scbRU?EA_v at m
zI{YFJ#>DJY|GM5k{+?~<;v8p9lQFaY%Skr6pXdds2*&<IYTz4Akc8F}b*0;RS9qHe
zi5n-~%b`oPl*u|vQu25*7yi}qbjUy#UNL)X{EBT at wp#eJK(Ny_9L&0YLvT&u-?i?0
zAi4s5u|uM0)CJvt#w^V6cHBi|#N~Xj`d6T^lknMhmvbn^71L^@ZA0)Akw{53y(2jn
z^Pdix33nT2Lki^&jDoLdz7XPJXJAZJzK=Z=mcy-q3doDOxxr2)R3FL}w-2<HQ0JtK
z|K1zNRoknl(&h|S`TH6F<EHapQ5CqI_ql~TGl$s&@Tj6!VEl^)D=HU5Y$SCGzBTt2
z$C4+i%~d`lF7>ZZ{jb9GJv5}nu~S0<I9&`+E^o#bp`nu#-M|X*>{G|~o2pvJ%reLK
zx()n@(b<WZ7;frNxDe5l$3~wqbfqbOID9E5 at PJObt1cRn6RR5Yr6Pdx{WMjh^9WtD
zw|uMZj-~3s11Q-{Ub+)<;_K=gdXss!<a;Yc(ed`g{ZNFDo#+|Td at f98dFIs0h*|e@
zaFvkLHwXQy*<<j5N1$)RjE9=u^C~tw2mhbVfF7}hFq72hf>c#eG9`XU#4D_8iUAZ1
zBPt*-LuWTj|JV|4Mm!qr2(|ucuTwb9rr)k%(%qx=X3(xX9;O>$Wd{MXrq-PFwJRRd
zN;+z8l4z{vY-%;|gAWkYp&rBO3pFM#zlyBrUsy;4^+W57yPaP7w at cXx?~I!NkncHy
zJ<mI`$d%TaIyBG&6s!q at 04&d|G at ACOQ1Skt*!>0hRZ(q34H>WvWqTus`_pdycXThN
zx9#sG5uZu%%^a)q;r=iG^`FU=yGpE1LqDUV*sZ6sAwMvwg68ka6b5!@^|-tp%1T!%
z;oM at x7ApL_vvnjc22G9zCN5c6+41ts{D%)|;h~z&JxWPQ^~WQp8hn>|{RH3)Q61=h
zs!Y?ggBtO+;t2<<CmvWC59oYFQc}P|db#wFMw|jG-%oOMzwWLGJk|SmaqDxXI;lGJ
z69RE&=^+3zAYC|c2%`TA!V?`%sZy+?syB`5JS!XSKFWzIlVderZ6ZT#gGc#%L>Y-k
z)n<j&WJ}qd=8w6;Bm{zTOsCXW$0Rj%{N7~~CrC?tW4~X|yT$w<-Y6AK&4T_pz|U8V
zlO&*q_d|HO33tb!55 at _u`tfGI?vZivZq}a~$1MMWtr|Q_*9GSh-L$Ml{=(Q+qEnz4
zSn<*$;*Ow>?<Qi!r7+oU;zw-z%YW at 8-eT#r&HQ{eGO3%VkDF7>g)*Y~>!3#zuGGFp
z8}W01m(SK}TbPbC-V%Nv-=?Jhy98sZJ5VSyag*5Y7-6}%&PF7-L-olOjA1V<iGnV4
zz95Ji!Yg}v9YWEt%(BYaf)Z@{G6z at _Kys8kXM0CGr3`OA0CMr#h}Gk`ziYBwNsnRg
zidbK8OnFc}51G3o&E|P0EoT_H<#x=do{;^fW1&?9ft$0crq(d?QIW!b?Ca~XO+=7X
z97yyYsJN>)DoUZ5kG%axzbTzFVx2hE9S=ChIH}8UYen~hKT at M1>%4Ryr_iaHNFn6~
zLRrz at ++*Vy*LR?(k<aQlp|JvcY(#g=cmMJ(rd@;aLT+Y5NULxGjYmX%wDVQdpOB2K
z5y*z!hJ~7X_ebTua#B^e1st(S=Dz8gJYcjw%a$O?zs|N`Npiq7`5{V&Lx!3KNj%;k
z_GNZvW~KS++-yLeXAG%h{f;cld&uGoccXLjnfVHGxQ=5p0}VNeHs&vi50#g>Gk_?l
zy~k#U904W}&}JbgO%B?unAWAZn+^$#fCOM at OC;CT at cVP3xcPtd*zYzuN&0r+ba18q
zgkj$O4ix0JN$$0jbC){a=H5sZ^gtYS6P2JuT1Ac|XCdZqwfOJOLheYJpZoru;Meqv
zXSf#%A5B(WOXo~DT=a-=&W3$r6>Dchzfz$g7UK at jP-E3rLHo%yJlP^^6lfLvttK_P
zc-H4-a-H4&kKu<f>FvScE!l^?=YFNMpISPylQy>`K>)Y$OUC7PR~1&()h2N)Inh&>
zrG!NSTs`U^6Wl|((-eizHmk`cYchTu9xirgi at 02W#Lia(2aC;-*eO)PZh at 6-*ESrr
z$(75~-Td9lNA2mGOK;bi?=Z|5Tj?tUD9E-E&IsgS!6DtVF&>2nR44ahssCdDKINN(
zrltM(vO>Kai36ZQZjMzz0CY?IS+?2_LcFM6%Q0aAjLidCuo72_fV4EZqM~ATd;6Wj
z8%)Gr_wh!C*;;X4Fg*cIUcqwTV&8sP5Ebw?^#=}O+adF>9{lV3vL;on!aumG0Ng)K
zgtp%iJ5mmBUseq9A%EXC|I+vIgKt6Au9OOqx_TAYb8`@|GLPX%Q5ofdn?%}nLF}7)
zuYG(@GZE~&(#H|-^YQ|6#mQl;Hqv?d0BT}s{z+yLouQC at uh6z$8LU-K>an at IQKn8b
zc?1N at -K{i at +HuUUgyvV>$6lYSPIxb(>nlo&8i2CZVm<M?R<rt at goNTdnr>gNfJ)*Y
z9C#p5vm?BpCUM9Xu0<`Nb`n}!br1Nk8s<d3DnSmq{qc}X>>*Zfn2SYEhK&p%4AnUO
z!U+ZJLAO^Kg^&LdhrcfhErT6Nw_R9DPM)v%l42iwv8 at sE?(VO~om^4)v#{L$b&PA5
zm-6<@cJE}52pM-5{;k8jA-}u*<y*d)>^LIhkBrkxHz#8uWXy|=co^SnT+pWc at P{JJ
zV}lU(Bj~~yze7m#k@?n%<!{>lY#y9ZA}Idmj!M+hzJsCD_1Xm<9-JBiDLDVePT>{?
z(^$iv!Sao3YQtNd)B?t+6>=yb6S_{q(m|KkEP9IqAo6lTcovVrcgtXawkPNXnSTxF
z|0DC)HB6w#+NJ-Wm3PBI#jN83wEfJBm^&PWqKwe}rOF)aD+0>$>T;E`=Ar)s?KW+9

literal 0
HcmV?d00001

diff --git a/extras/package/android/vlc-android/res/drawable/ic_shuffle_glow.png b/extras/package/android/vlc-android/res/drawable/ic_shuffle_glow.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f4349d1f5905e9742cf8513c4cf3ee68106ab28
GIT binary patch
literal 11105
zcmZ{KWl$V#u=U_>fxzNUaCdiy1PJa9i(7!8fndRc2X_L&-Q9zGa25{`BtUTZ=DqdZ
zpSQMVr*^h>=6QO%`<y=AQSa0hu+T}+0RX^KQk2yM&%ys4sL0 at Zzqt7rc!KlLRFDR$
zCdqz-ACN6n6l8&y|6X~W-;=;AXs(L-9sq!W|K9-zWMo0WizuE-YH}#6Xv6>mF;6<t
zH~>%qO0rV#eOCSi+$E7N1svRTF0Bh9L&is8<LCRBgZ&>0LWLO(W`8Eq4}WQNOEgwV
zl~sz#s!RHz)*<od`E`5uALl<M%w>()g6*mNQL_3?MTt1eb!3U#iv6uh*ryLrAfT&R
zB9HX)yyR0W+p at H-7aT$e(AJ%M_7spC0kNDG5${AfT at RrEJ}Te<orNgD8#4%!XNPck
z-dDi1$VcFiTnxC1`~P3>ct3p|Ai|aIZ2!w7xJL1HzWp`j7&VmmVL&f<qxPWh-$yJj
z0R9+m%Uk9)n<787C&*Ir5N=C=_EG&iqt(Tl2ksS6b3-Mm-n4fei3m4`9q)$>KKh@|
zc~#9_lIzs^4X66nqrJz}4I-i#a3Y55)2lK`3k%*dfHOHfjmlE^#RA^pJhK+Q>f9QZ
zfC{)GxxfYg1_pM;r#77a=jJPC(Dsw8pVKhffbY4te?J%ho;`7>CS)Eh8inieR7V3a
zv1L;)Tien9d#*S_PuAiC&?E44-XAd;urp;U{rNT`p1hsl>AHGuOv3k#?$`mJ!Ywjz
z7!th|Z;T*?1Nd?H(*RVG{>t4PWa7IxH<T?qW#6%L{7)`+xAJAuHeTAhjeihDV*%4y
zH|=ilC$CXI0>3&WoBxt<_~_n#!2k+Pa8^>o;3WS>Jlu at +Zk=aOiS8^pG*X&84WDs1
z?71)aN-XF3G+6$(o!aTakhmp}i_YV5ao`q?3Ka;j>BO^2Zkm;lrsH-!->UWFFnL56
zo8HXu-AkeG)GTua4j1!R at xX^3I(D^ZLl$+fgzo|*07NpF0Nixxjm8)a&;#K_1~Bny
zu*iknch>}-A2p!*UGdL%xkOjc6wf>C=U*QxC09y_*DCbaCVM}euQ+2+cnfthe^dm5
z`{43$0BHcXPL1afK3D`!<rRhahm);4m%w9csQ&D=N*du6v at sLu93Fn>i;4&`u=0s`
zt?c}6D01m?9gq>|#ix$N#}K4}bg%~ZWd@=E=1_xx at g^<=<QOh*<WM+(rY;8j2Si+-
zGdDj5Ysl{h-ri>+gs7(~Rp3S5IIIGPpB*{yBl%(FP3Z6 at B8)x)DiFtRol`HTf*yJp
zLAh_X<n#pmm0|dX0+ZK-$PVElHz28(Ix{jqKXB&~a4ZT&VaNn;YSS)uk=py(4rkoc
z0wlZW)V$2aOEtV|EyQ7)Pt!^}QD2)zjS$bY2WiQxOflitAykNf`6{o>d=r`_W-u4<
zd0;axvLJ8f_ir~8#KZgJw0%r%IZ{11{3bo&jTnr>BH~lp{Q~U{1eIx}TmFjb1TC1*
zIy~+>qDrE$Q+$for<-!PK5&xT+`*}@&6?IxV({#K1YO!t&m;C{D1qxW#$Ce!T%WF0
zE-9!E_dg0CeriDa^Hr2r=5&j627A0a?VL at oJi(A6$OReIgu!&)Ck(&ER4 at S8!obA*
z7aMe1->=MhXq&7YqlsDJwcZ192;{f?w$d~JNhxz0i_xU4cakXN<@DS=#7%hJdc9+$
zQuA!ma%%SYDA4UI0pu+&nPdwbU#r7!j>tI+A@>+Nf2~Hq<#cpe(Yv}!#_#gWm at MoS
z6F{PhWSe*HOA|D$bnU}-wVkGnx_aw>>hX|l#>wltwY8P~RwBUE)s7J!7#}_8)!zO0
zF#Ht(b%0SWh6^)>nr2MXZnG3IhOhSseUp5|sSQb-Q<ipaZs(x;ZURi6_0`W~9m{q;
zXdQ+XyXnM^1PJE>%6Q}YlAN*rd7qo{5F&{zFbqx?NA9!^dbV<$Wn)AuK0UNYDuhi=
z?Hx%0hnEU82s^oV<IlBP-`|}2AC-CZ=I5iPS_=sZLWb&M1PaY_h*X(8Sj8OX{Lc<(
zP*2kk0uzn(B1>#+3qLk8Z?Md07dYEfzhbg@$MdE)<U_+<t)Gd{MbS*@Lz(>@>)g4<
znC3U9vH2!?vk9Lbspox}zm1ZS at bF(aOHip-OP5G%S#;gQfAEu;JH%}bD&S$Bs^P)~
zBf&1iGIXj=kIyJ?Pm<nle3-iA5QUJClA>W_hu6}X??WrUL0b)2#J{{OcIfGzI{|+S
zj-^mr%V^*Mt4sz5g6IV(f2QBd+4H}NbX}9Xch&FRfp^HjYXAyNZzT^Li#K$Y;{zQH
z8=X?H7hZuEQ%LbQ4dri6mcs)u_I+0jNni+t^V*{Jv3m1v(r<8Kp`eTpdVwRZNc!W4
zFwrs)+;&;&X2vPB)I+4eNp!-LMene8_^fDU_ma+oZ`qtJ>Ux90kwqyK=>JOPm3u>@
z+O4B4qDn<lP5TB#3?65Asr7Q0VY74RjX==l%EHTK{1O at NdotX4q_8c^LViGz^jpwH
z_#GS-gp5pdtqqPn(f7080}t#kQY9{p`3>sXro`=ZbGMiyX}CTM!OyhrhxMCTkENuj
z^z@?qAFrvAVa7N+&^=K=b^@pMuC=;5=#b~FxbJ-q#*_rXO0x@{ATNPD1fg)=IsJq$
zmkm0(Um=<1U`m8p6 at +7%3@?p}OYL)b4wJbt>9~~}{m#oCbar+et67WvCzOHI#>x;4
z-cTS`;|N(Vxm7?$wn__jgbS;>@ihq&fzAkU&*A`#y!`yPTc$79uJkECP46~t0 at HJH
zqv>sJUVUsd*#69MZ#@7P?DPJhFYY`-;xeT=tLtpa<i2m at Vh0768WmC)!}TRYpsT&x
zJE(n$mg6?|xqHch9XHEwV)0Y}9TSu6Zd^C#ksFw=e(aYhy_U}3$QNv^l>VwqxaDFG
z5B#yI{}2^|EtD4f4j(gNYs>5~-zCVeG*R7l6U3eXzx}<mgDdE3VS+D4fEhIhj&L82
zM_-WD?(K!r at c2sAvaJb8H@)Q)|IG at +vqT|*<D6`2l}xAJz_q`LbF%WVLP^OfsfZVJ
zZ)hsWWUbQKOaS+McKvvP1v3M#nADN_GZ!{CmfT~4;_U_z$IrScj=j`WXE~0S;~zTg
zmrVJnfbN5#csKoHbkM(%|Jm_S43|y+z1f+i7{uv_gpaMLT>Jfmjhhf5?Sg8?VqL2p
z^k3mkB4wc7^3hpJ(=?raG#a98)1AM-w|viR92rP+24$s!@=_;u3|!y0VdBdX2rdI6
z4yDM4t;?XhG}AJo=+W|*+b3O)pquukqrn1Fpe at 7}J2If-_l*LLjBSq3_El?I*F{)<
zp~4$H>Tx%hWUisL at qtdliyMvA4P{{IABAe<!9m;2c;_27m==1fIaR%m%z`5!k*-U^
zEHpW#U?%f->+wtSw{(5Z_u7|?;ZE(i^H{iB#6VPuX$v*Go&nJ!?Aogb`jVCUMi#=O
zih4>)Onjw4lb;kX_FO!^=5GU=pj^s2OmmZCisE^q22jr=JobCmr at GI#&TB1`B5_?C
za+>~n_NMV1AOdDhSo00I#s5}Z*2iN9Ae;>9SdiBBynU~~duDC>#%1=@W7GK>%;tPa
zy~RFR$va#+M#jc!CYio`ViL_}_6F;P%xw<9;jcI+`_Gnei}o#<F6bm7D-N4EXI`8A
zpQl{pU=yTMR|Z%M?n1db?D2x|A9xUcBFUf=T}K4K&Zj}7?43S5WbA{8i0ATK1`HYK
zsCM8rVWryBKr_tvNk(S9cJKGRUW-xhP}hyuu!g=u<=npfRK$p>GTWAy-c6KRMO$y8
z(CAN5zRb!#yi=5 at Jfq1<qBc3+kz;I>)y!M at vp7H}0(zJV^t2`0I!*fXn25+?Y+V~H
zb^B7goWH;Uj&q2GI{i?F(6J~)_Q4%l-E#kjRCg?v+~Wsug<ECA-JYvrL^<6Yg1qww
zc4B)WtJj;ukY6QXti}kH27?C0Aq~pJ$0^Kpm<Uc*NVw8ecmCs>n^Pg7p}c~ks$A5;
zXy!Rf6A-=dPatYT*&|eD7?}nw-WeHJ at +%h`*#w>{q~G27u5$iVCzmBs-W6#AEcBbS
z<Gki*h9EqASWbh8&Xcm+i?LEw_E*!g^)r&!7I-Q6Xht#e`B{;=F(22rX##JA*Jdid
zg30Opit at 47>A>WEC=|pt{5Xy#kquS_#*)IQYtTfkWI8;=6*l!1sZ;h%<_16yZZBrO
z&BVxz#V%qEs(Fl65P*b?toO2uNO5*dt8ALv-00dh^-jCUroIJYOh0JYOx51<P2K;z
zcd8M3t;3cUy&Rr!fG$CT0 at U6&vtev8`2*9XPFg at -qa)#QBS}F?REK5{zt(B~)Aq4m
zDsdl#E;oMk6JVwUucQI#Yr#T|(d6_Zw_kv2JtU!xR993CRh#&VG&j882ZCD;B~XF<
z3m#jBGvAAC1aLb^ap$YNrUb|ye6<F0Q1SS&+Hd7iu?FnA>ZZBbGY*Zf`hE?dMlYk7
z_s|V}g9p&1M<USBFv*34Z%2Z}KMHbl<$FGL8DSF at mKV8RGVG?N&R($SZj4q}j4zk`
z)_MA&{yPmNSeLA(_yZ>nJO$uP-evw<n5D8xIpsaNz)$NFo$tSFz7R`?RUo~J`84t>
z=?Sg`F?5_ViqkYm;`;g;PJ^K5Gv{ZwIo=EgZU?^iQwMJJ>2!N~9b^G7Pr1caQyUFf
z{RGImYg-&epQZo%f0AG`GkB_~1x-%P3*4e1`eU45P09)k#3L}8ofEf at n0E<@JTA(0
zIhLXaJqz`~RhFTz9KiQ at Fe{>ku}Y5=?W8VhlE0Z<DreU8&^K}q>+Z<<V%m8`|H!P1
ze)9#ciSJd@<iX_%4&Z)N7;h1lDX^!^%tYEqlHU{?%r(vz%)f-;y19vn(DymG==N)O
zcP=Km*wHa5G4;P5085r8`PM&D at f8BH87VUFPwU-p<^~*uf3G#UoJhkby?W at _Z;vm-
z`V+vsBOdUt72^geBK+Qn1-av&N8k6RKet;Xn)SpRn6{Q_9NmU3zL&_26|a^erjY<M
zXPS{pF+D(%UjJ0#bIV!&>CJLU6iDPJPDJ{GM7ldfZ8L2)?C;+T&28c~m?HMX838WO
z>&42q>n|6ZFAjxzSI3PRxfvz#D@}clhBh%#UWeFnSlEm)=IUmz07Z~?jm*p7WK#%#
zYzR7^&Zh#lB<ZAyi%}s6#@ZU4?|MKe0Q0QR<IzH{PU0xp(ygQsPCpLN3lg`XvreCj
z=b5rHG!$3=fbI#BR*g>m at _YmFW`>yJV%7hC^4ewHpdeM7fP|y%T`&z95c1e<uJnU8
zhUq(^BbH-MU-yRGZCk|IW{PmI9h^aI>Tz`^f4j;hV1mJz;?6y@#F&<tFggn33A&AF
zjvxCgu8Nxa6lh~eXt&2*_4;p1qG}3gu@^cXiEb-W`B;|c^L>H5&(aAq_-`1b3m at b;
zskch}=9`Eq4I9u!FneabrkP*ASE5rCA_;x`sm$<U at 8??#0cTdhzOAQfyFe+x%+OJi
zpg0^Yzj6h>xCg}_^aAScx<pm~^H1e>t!n5&Dsp+1h at TV>>sph9SFjmE2KMIIfM4Mn
zU|bNW)at#${lWNYONdnoKefbsj5i@;bjyH$xWQd$jxl9how*2YL4p`~RA!tHI=bK>
z?|$gJ^hSw54vpbzUKti0u7w1bIVkFC8~q2u3BivOr0Ku*#w6I*TDYdrLeDynrSFl9
zc9bwN at e)!<sOCv_7FP=cQcX?N8LEu^SehGnyU}2V<OR><)fiiFTh|$_6X}xk`I}VO
zdAE-J?{tH%%fGxrEzNyu4!Ux6^|`HCu=@(-m-+GAll=}hzMA663|qrZYQJOqvl(=M
z^{bPJV?#igj}P|#!Lj+*4lJXmY1{@zpE(E>R{I&%LelQO*ZKJKX9#Uf;<Wb?;^kC(
zo>w0VplVeXhg%TCWyWv4;Ay~IRh8H`L0aK at ti$T|XC<?>xEN`b7h}>}TlBNbhv`SQ
zYuh3$<k#PZt(b6vvsIC3&6S58RL5-XGwL3ba!d6Rp;|a%SAsxR>E5MkwGRHZ#YIW6
zJw0rwd8jt!9iynQSf>Q9u<&;3$1*1#v!0cc^f`8mn2^fjyp%D;32Qg{YzvT1Pcx<z
zWZ_h~u8cSou$2T;^fN*L)YLs;h5?)8Iw*f=ba}H8tQxf9gSoS>?+pJ0H_`8MQrU;q
zSI;)ez1w-zltd>(ZNYKQ!6Mf6Go|dEm+HiLnya9d(ypPet<wl!TC)@fvPicBQymfr
z=n2qsKb~9^dP}_Yt%LEEw{w}fwB0*32tiuq{HjyA4P}sF9wi{q)zt!1YG8>CH=5LW
z_7{%#K(KC>j8$$oT(G0clD?alHuHu-ak1Ws{NH{Y(+M^<w&ieGiFZ|InH&CF8>0H|
zJ<CGPnmk%I+!IghuW6)*4U96#!00<|`@3v!=0+pu6a&JdgMD<HPG at vDU6$(=aJ`3O
z99=%nAmc<+MHLk4t|uw)+?dqkIr9F9t~X)jN}v92N4M%RglAB at _soH!D;IsqR;YVI
ztq=_`+txZl{iJVXOdm$dQb7>QPH!vz7_=M~CZ{rIWZu5xeBB9J%L1tG!SzK9Uo|F;
z6t;`nb$eB5#2~O4(2RJj-;8VfoLTZR5cQNF at DNT0(^5F6K=`J<av=KzWsfdj#w;g_
zzWZ1U@%UWrju#{|?LX$QudY~ZoTdZ-W8&R9EChK3(X;NNTxl6khc7n!2ZY&iIipzZ
zP(P-}i8i3R+uOsdW{HLXW3gKLudwy0pP~KIuhFDJZ~s4K?IEEu)bdOSizjD1^4WiR
zp!VXH6=hF9zBnwimhr0vaR*)>O+j0YLU``@aA4lhPMTh81OE?JhBmEa(Uqw?QT`uK
z at 5joPmyzmcrp=yi+u8NfjbA^1Sm~{a){-ohQ45aeLiN7vFhV5MWDm;xr-I0(?4)pO
zlosDOE1_^(nmV-uWe#I0vzoi&U}yhTqJO06cFEl4<E6FkP-|qy+I6in{?6fLqI5~|
zYN?z3aN!5`pJ+2x*cv{}1qtxuIodP!KO%5#>pKW#?b<#7p#+v>>VI;$e89d&PDXa(
z(U9AS$j+Mwu{1jtK3sr~T`jq{`giKZtd at -G-XBreY;H*6#*C at n7Oyst#jh at zJWGWl
zxPBkx+?I|9_c4qW>>QjILj0N*%79J at JX(HNk6pjqjy{n8UNVd)-@{l>TsRSB;@$E&
zQ?MX4EJhvyq^L$}#rXu$^!PkH5?VazMO!zG?0bvqW;PU!1hu^kgi9SGG`~&IUXqZ3
z8BdyCHmY-zEf_*@FbCNwrI?$AXoJh<S6cs-S6xeXX-=WV_F%-em at u}Kyri`b4$2K*
zEq#`b*KKP~ko@*e#oQR(k(4cTGYM|tEset0mahq3r6f&y%~>{6zy7?OZf?GYKv20>
zDsI~PY$@ua=Ig%dlx=;?4|ZrJ<NY!iVtFsHb0a{D$)LxjF>T at 7NveO9qxL3fR;fTZ
zf&DyMBt)5!fH*xP12sMtt2H3d+hWuqF>-~U`^amak+3#n0*qK=wSe0hKPW at et64E)
zyZVpS7;BJ$M-OJBCHe6;e!{8jPlTwONscpkfw>%H6oPky!zGjA4{Ks at Z_bb39l2on
z8dPRUL at YRlFZ{jh$e5yc>M!;A7ErEI^<o&L*o|bsF<aT7wiJ^sD&+RBFYE!V^@i~J
zB<-~xGVKGkwkGezfuUdno%-dZF&K0O?NR)8>mcr*_m5_8?%vX|V_ at AkmERrCBz4!D
z0<f^2R=GXxixa0OAc3Uk<bb=173}*S<Nk at V`c8dweV*4&@RKQDw&s6iBhApjph>MB
z{`iew2fC<T(lu_i1KyOn6xFt5jjbP&|16tiv)3cFsi3IODs8-aE=XSd;1Lj{l%0kS
z4YuA)9`X$J%wk!UGFK6S8N?>vgq4uASo0_U1hdcE>qvM+oP1CGarp+1kwV8cr>S6L
zluuV^Gd?$m16$OZm0`o`Iaw_acL!&b;vXFQ^h*|apN@&h1Rai4t)N)%SqN(~Cbpmq
zl?=8v8 at lz&tPM9;cj0j?jDclB+q?~=T(m2)@r8!eksPRSCo_}OxdbKC>Q1nxV4PcR
zF_19k*Vf`G+|Fy=#_jX0BF|wxa_bw79q4zy8v!|DgA;`L;H=CnK-LCN{PkycLa7Ea
zCrqo*2pp8R0l!u7o1FjC+SuOD*(0nRu-;<Pei%n?!v`K2zDaiqhgkd|g7+p55)}2^
z#)wzlyuP;0DA{z*2(<layYAB_0(B~72CD~6HHLhG*pgRERZp4|R&`lZL_&x at oNe&1
z+-Rm;y?WeA#psx$0U`<^pCz8DKm_xXGg9(^yUv$u2_ooS2W$qjuLi?0ZxyM>geR<k
zePtUvw8dug_4Bz?yy(Z(PL9s2JDBD05Z;g^Te;Bo9$|pdOZ+>YgJxDMev(ohyNqXL
z=HelC(?E&t4*!0BHE%p72{pvteCo|84pDAY)QaNfP4)6+$83jj$d=fhtcYH)*C{47
zfksF#Sk7$r^1Kzrn_oB at d%4d(W3}I_GxT)d!JFM{|1e1I{|dCizePMIqdtJM=4>Ep
zw4R7P%jGU$tl)V6p=F_cvJZQjIb}b_lz)lrf;lZ|(gHi_@)!~D2k~&rcuLgo>gM at 2
zKDP$5(0m^H;`eVscgG0IC^RJ}x5a}@cYEK&I%GGGFyF*QMR$#blY75L8IS^j{+Vsm
zH8GiGdF}nPrFRhRQEY{q^ibWn$AmlVLk7lG)V?WNn0$CVxdbjKHbL-1K)H);j-x`&
zb7|4AZR6-tS5t{mPFHI*-J!c;&s}KptbMZ at 092o!|2&94>?WCF#l~jO{M@^mo+%uD
zN{B2;89Ob)o_h7eqdW60X{V7sOElMUEL9`xt{&Sf3ewEBCkIo%KJF_4iTku5eXjQl
z>zvXdvHDWph#~ROOax9}|24u%qJ at Q*PzL%ORoUhUkw(gfs81`TJNXgXt!eXDhP>qu
zWf at H->Hc{A1X3w1XQniVduyQQS#dz(qs4uV#H(~!RJ`Rg%C0{N3Y4*3FM)p+{mur-
zD|dZE*R_nkj<(l%eX1zq3u&@{b#Q|qt at tG-p0fS2>^nWw;B4IFqtkN5Qh8PgjJ at iE
zg8laJ1i^~E1K-jM%AT34*-?H(+`9M0)G0-J4uu>9q24L;18!IQbRXLdzwKjPg$DCQ
z$!74s*P;VUo0Ni=1NaI-XK$ac at Pr^_MNJd9Lj#+e65{?RzhDF7G0uy}KZd==Y69f}
zGyv6ok=2USW at MS8r#Qn>FYz2~zC at gU{I?uYW_`E6aSN+kw(~^jsXAf!r(}kHZ9u-8
z6x#crwlQ*eQC183(c|;T)m0>|zcO3-j_|Y2ylFYifL($4H$k$+%=^Fn>8A7Ut(X-F
zj4N5yIz!IwPA}wd#hzTPEVe;mgzJ0N)>*u4;0w4^sZO1w{Y{^p at M8PdcDV-sdhfZM
z-0TeuvHJOA#ckQ>Jy?=~EzNGVoPg6-lo~puzbq^lSC2+(6-%{SaU!kDY at vCXNQVRX
zzq}8Yx&votJ-eMU#K)!sVl=~+-<LG8X+ZJk=^9qENbUBWAi%pM`(&jU&Eg<`8u#J3
zw?X{eTr-qpWSFjf->KYr-34ac6*@r71gSk=N)-c`ztisa_N=S652~mV0m)R*1cy=h
zI|2Ru4`i@*Dg;(M`}6aJ(fTQ|8_?l4w+&s^Yj`IbgH4j8PjPnOrsY+wN#!Fom2ss<
zYOT~h at uAg>fL at D#@UqR(m1k2QHn#b6`t~63YA6c<z9TBeL51qq2)vIM?4IJWy!$ym
zhHIRWe!h;AGd!z%z3n)4PRdpu2M#ERp;pq^?Sh$0(0~MniBD|>dhwCaKd<%2us%On
zXSnjESX}#yZ!)IsOiE)k&&+W at fzT;<{cA_z)c^kY;PL5++GaJzfN+X9IFdC1MyoJ<
z7Wf?IG2WCi*u2 at b=ZTF#evd+h*x<wkG*;jiCP&6l1>?$~!Z9F%VSa-`lQ6w}kmHAn
z+qY!e?YTbNFflveLV~zzfqs2+LuumCDzZC$?9Qp2PU~~zdGn3vg3c1N)QPrU$01R0
zV5jKSTS+EDm6EEd=c3dJ26HF3utC$!XRYty|GD3#j6$3$ytLZfS at 1X$E7uUDFY&W{
z964qC!C>@_nLak5^TxOp5#is-g7?O#h{hO4%for8<QB=wk4TZ33RE#*Lybh#-)9>P
z<U7$qg8w`jwC&++H17AWZ9i=dRr4p&NzG0Rrvp~`0N0h%YjOuIlM3Q1?efyr91gfa
zJKpq`f4zp2(2YdPDmC?obPlrA8xZeT$Y}dV_$PF1q at 2=<D at NrPi+t10M=r`{P+s~?
z*LBstv*>oeJRPUJuZuzBf}_U3?`sESoiYJS?nWnKh*qgJ3Z(e?Q-4Hw4eOZ6$=2y!
z+m-J(Twb5s^IhX9u?GMl91H@>$yr_wz()<+NsoVnLaTJn-RtsvaRS~&*eD0hhW4k?
zv&T1{nN{cCD-n)s{+p!>H5m^34`BJL1xhL#>>F)-XRIfsZe5g89={==3f|>D!u4bh
zU5ybEL$d9UTXeC)p2V{ZrVr_R_;($4^XE7^CLV02TGPf5L;n&-VL~JMgmBly5I747
z%#{+Q`}<!NCiAN-kCzvm)a6mDqLK*vTm5I*C((K*J)g^o<J6L<%P^Dr&vu15y*8{p
z_o{iso?Ou78u{-Bi?CMDidc3cU+Ag9Qd9O at yUsq0u~xgeS>fZm3`gqUm{oL%3-bz;
z&*OOFZwstkSK at Kj0{vddP5q8OjSLJ(MFeDOW;QM2 at WL@(5!xl~XY+-{-pk9w>m at dI
z$YEQ?2-Sw;&NjqXRbOx-oV!vP008>Jf3pC6kiuS>2!=@$pJ!330m8t?op at F?d~Y>8
zf$?8%xQE(k$!l;Jfg2kv^!QI#$O6_{xv>2^kczJJK1`HtSS2RoyXkNcdKeVDt5CU3
zxA?cF|DdtbS}kd^Ux~}TF%o7lF^!hN4gREt2O`Y<iP{jK(VBwDBDZK3HBI7YWE}Dg
z(TBCLO9;Nhvx191i1El3o4hh>oEEE@@?PlZhN`Keg~g?VCYa_XMD6<gwS4=k^+NOd
z?3R4lL!gRNnvPjn!c#l`xE8;l%7E=q?t5&saTfPY1uR1Ac&a=8PLjWs5F?3{4PPyF
zLV{<x5NJ>h;DLIpE$UQz7^AfxKN%Db%Y{Z at t8Ltk^Wf0L#I_0qmZo2~Wk!t{S-WdB
zLhLhp^>w+2Ck(<Sph3~fP5Lm04>w at WQ~IvRmmZ=ltPNtTk+bjJFqrxD<CMl00(1CN
z;ev~F%dfAlm#y5cb>h at jvCXAX6RgAO(IQ!Sa94klm%1(!a_3E4x#$x?1CXbSR25Kh
zC`1K)!5k|QLto|wc4EC`wC_6MBNYa}IuQXTDvgVX^~5We>Io)kK?hNZplEHZ&}2<5
zqpeY?*R$|G<GrR5D9o$b?C%Hu&@G=aU?=iW4U#*5B23F{k5{&^Vet5aBH{C}OGJ5j
z^H!BCH9(vd2_DR8G+$=7aiI3aieAm-^%{LS at Z?>gtur)WyPwPL+{5(g$nx9P{YkNk
zHrVW!vQ4aFb0QfOM%_RL#+(}4oIM26rPnjJJja4(8Qemb?Wj5p2BG2+$9JMS^+E<p
z^!UG*mjzU24zuc0<KMWIdaSr$EU5sJV6XQGO#W<oSZb|*YKOZZ#FP?@naHWh3>x$a
zbUk$^j at uDSF37cGOC8}z5pwI%eluu2e;71M#vT2RddR)~%OJ7xE?p1KZsj~AnK0B>
zqcmRooQ at h}7EM*OM~x!kOGqD9<*n7udl==K>_e;}BT(M2W%i2Y$!>*4L)ZQ}Wy?l#
zy5+5Fv$KYA=PJ|cTU72hkx5OJlZD0hd!*ey-jhwL?qF#kPC`N|LiO;Z_xspVnRA3L
z7bmiyrfR8aRqt?%8B#pySQwr)LF3An`#n|@Z8f~MlCqiYhu&%(V<W2p2SJTSc_R(X
znDLQ!>4X at W``F8B{&-}bWW>=<v0BHj^Ie7Ag0gsb-CvJNqqqf(u%epevFJ{jH9-q<
z>*!*8pX;ZaYOU39%bVO6f#>Jvgsy~yn%CHt^pGNUCpLzn!P9lZ>BckEed8-!wqbcc
zG&J_!34c#*Ij}pBw&SL$_B}mgVr_(tturSlb4=<W0KwY|Zc$^9<i}5NJOvc=^>npC
zdp0X~OA;d)3VhY5)~M9fU{h;`6suO3?e)cyO1LB|M}5ry>b`$_XKmE67(LGhI^s&3
zLu!c>SkUKa&;3 at mb9DTB*!nPqrK+x;kuOg3fS`(v2+<&rw at Rm$HVAp6HZ&D?A?2W<
zT)%qoL?OO|2XA^4pdNvL!Q>*8qc<@=)tS-lX4yO2fb417-twEuRp!U9lWmI%g80!!
zM;(3=tUkx~R+jz6;oik3NvM90Bf5N{$s`BIi?Z$l4b6aAQ{|6z)y3b3d at V`eHMsIF
zNuJe7l^d&;`7tvLO%}hDmkU8NRuUd212%}TV{acG`n%pi at N?m16Nyvl<gJJ!>9}MS
zS<D<4;M)+RPW@^S$Rb+YE3cR^8`=V}`_0)Z>9mRxRckDGNv6gpI!}|^v=7zkW at gYG
z9d<@6aYS7;IdmUW^B>rZZ at 4m<F~5yxR2qc{QV_Z&p~jCIZ|pVl#}uU&m!+$2 at T&#l
z%j&ids?o~z`r$D|ldF$f8kJ9pMHR>*W0OJ7z!si_>%*TLrht6BVh#vHT?kkK5u}fb
zODMug&}t^_by%+LAX6j`L>2 at WF{=K(`&PtQ;WP$;iNjf%tv1!0%VMYPplK>GfO68{
zTz$O at sKiM$sPQ1Eol1+}u74H$SQtw?XsypJfYe}!KwTk28#*O;OYG}*te5RKp>n>x
z>-ZgpABY%xwt at slr3mVM>EFn3V&h`YM7)knq>H4WtEl)PyJnLA!ukUexBDGhg%NhW
zeouzufpG!W&b*w0ihGj57p#W`d#?I34ukL at U=?LW$}o|r6;+!C)f2=9{`%BX2bX<=
zrH2w6pTtbq2IS3c^wPLsyZmE4><Sg!q+V6+DMtvlA(iiRy_9bxi>IG=bbbxo2XlpS
zGlMkh`N?)ND}}&RqLHm*h;RIBPgWeBwBp~p1P(F_SnZSE--jqN)CQ;Q9dS)t`Xr6=
z{ExN4U?sxxXmx*o-K;!w==G`3X4Uf|n^m&eTFtLE!2f%8ztiD(=1!xb;Cj!E*Rk8k
zme>tr&gr{SRf0jV6cGQ6iw#&ta(^K%emsS~vQ$O3?MDU9X{8?#P_QvKZe~>!!sE%b
zJDBrRs|3<&tvx`!QIUxvLX$OP9Q2ppsHVF(|F&6A+g#oWV4P<beEGAFZihlOjV*m+
zF>6L at MEYktkd^w}$&%gcbuT|=na{BfVaJlP&*0k$rUSF-K3QSlG#n3 at m~3;REmtxK
z167Ffd1G~k?X2 at oyPftwL^Xdt;hJpuNxdH9hoS4CNO{kFXhQ1AXRjLGm1OU~*Ki%}
zzrRQgI}rU4<^lxE5zxyLgjp!{P2TF)_srSl$+vz6)g&-iYmV9I(`SFN-QVA29k#4D
zN;f3vBC`A)cLeyUy>3s*`}#@16nj-Ve(<<mc7<>T{rq!EM-RQ!;eZTUBmkJmFeU7g
zq|&YYy=lT~;~6Wp;Vw#4|CBNLo^((1zYO<5h at zbx)wHN~nLll7Snc&HnyX3hA)RBB
zOixsBUQJHT><Nvh#%%%8d8nkI6oI}RWZ9W#!c*`|c^LuIn^zSC#%k6?L_zr=vdNbb
z5Rn))VrO)-vG=}(*FLf7!ucSzwF(FSm-A0)^zo&^PD`BA=Mi at -TGi}I`)?UjN()wX
zOpiXS3F(<Z?F8|ytFz~%vc5A5r;&13J4IifipWhQ0llfC#`HNXcrgLjWP)6DfWJ6-
z0RzcMji0YOOI5ZW14DxO&9=&Xol)$K1rt%!k7hMGCaJSus$Ws3vx%hq>DJxd3P!w!
zzFE&hD-u-|Q{E at 0CPig}O0r6^-TWR4R8V>|WxW at i%`?84p1Ag%8E(i1`v6VW`cQrq
z<|w*yy2P=&l$0Rmjkd-^SHeT1YD?V at D93PSH*hn*`6%evD^(3YscQPi%9jl=kJ42Z
zX?e7!>`@XpZy4>~Q}|C6;%on at s)_su)Cf>XQG^vYKEXSdSJ-fuH~O=iwz%!2to{Al
zQEV^lb4Fy=!+wI at l%nbS_OpltZpG%W0<Um+h0vYcr?r+cK1Hxkh;GnY5h|dREO^ve
zh*i*`+zSpzk^=*Bd?NW#tJ*M^d5lBy_5<{f4 at g&%(>g<hEHNfVy}9>K at PSKpNX%9!
z1dGk%&9e{SC}uM*>U&1Q8EgPJcm5Cn{nZzwJ10efX at b?@tXB2*PdHw8G}Yn16&sAV
zV!$KeFv7VTS{q96rue%@dF-{M!S4@}F|`}Uw*-`87}Njvoaq0Kk>2u>y-*5p+VWlQ
Ts<nXguYi)Ax@?uSS;+qb#fhB?

literal 0
HcmV?d00001

diff --git a/extras/package/android/vlc-android/res/layout/audio_player.xml b/extras/package/android/vlc-android/res/layout/audio_player.xml
index ad93f5a..140ee5d 100644
--- a/extras/package/android/vlc-android/res/layout/audio_player.xml
+++ b/extras/package/android/vlc-android/res/layout/audio_player.xml
@@ -24,7 +24,7 @@
 	    	android:layout_height="match_parent" 
 	    	android:layout_width="0dip"
 	    	android:layout_weight="1"
-	    	android:background="#ffffff"  
+	    	android:background="#00000000"  
 	    	android:layout_marginLeft="15dip"
 	    	android:layout_marginTop="15dip" 
 	    	android:id="@+id/cover"/>
diff --git a/extras/package/android/vlc-android/res/layout/audio_player_mini.xml b/extras/package/android/vlc-android/res/layout/audio_player_mini.xml
index 37fb5d4..54dfc89 100644
--- a/extras/package/android/vlc-android/res/layout/audio_player_mini.xml
+++ b/extras/package/android/vlc-android/res/layout/audio_player_mini.xml
@@ -49,6 +49,14 @@
 				android:singleLine="true"/>
 		</LinearLayout>
 		<ImageButton 
+          android:layout_width="60dip" 
+          android:src="@drawable/ic_backward" 
+            android:scaleType="fitXY"   
+          android:id="@+id/backward" 
+            android:background="#00ffffff"
+          android:layout_height="60dip">
+         </ImageButton>
+		<ImageButton 
 			android:id="@+id/play_pause"
 			android:src="@drawable/ic_pause"
 			android:background="#00ffffff"
@@ -56,6 +64,15 @@
 			android:layout_width="60dip" 
 			android:layout_height="60dip"
 			android:padding="10dip"
-			android:layout_marginRight="10dip"/>
+			/>
+		<ImageButton 
+		  android:layout_width="60dip" 
+            android:scaleType="fitXY"   
+		  android:src="@drawable/ic_forward" 
+            android:background="#00ffffff"
+		  android:id="@+id/forward" 		  
+		  android:layout_height="60dip"
+		  android:layout_marginRight="10dip">
+		 </ImageButton>
 	</LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioBrowserActivity.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioBrowserActivity.java
index 0e3f235..5eef171 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioBrowserActivity.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioBrowserActivity.java
@@ -24,29 +24,28 @@ public class AudioBrowserActivity extends Activity {
 
 	private FlingViewGroup mFlingViewGroup;
 	ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
-	
+
 	private HorizontalScrollView mHeader;
 	private AudioServiceController mAudioController;
-	
+
 	private AudioSongsListAdapter mSongsAdapter;
-	
+
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.audio_browser);
-		
+
 		mFlingViewGroup = (FlingViewGroup)findViewById(R.id.content);
 		mFlingViewGroup.setOnViewSwitchedListener(mViewSwitchListener);
-		
+
 		mHeader =(HorizontalScrollView)findViewById(R.id.header);
 		mAudioController = AudioServiceController.getInstance();
-		
+
 		mSongsAdapter = new AudioSongsListAdapter(this, android.R.layout.simple_list_item_1);
-		
+
 		ListView songsList = (ListView)findViewById(R.id.songs_list);
 		songsList.setAdapter(mSongsAdapter);
 		songsList.setOnItemClickListener(new OnItemClickListener() {
-			@Override
 			public void onItemClick(AdapterView<?> av, View v, int p, long id) {
 				mAudioController.load(mSongsAdapter.getPaths(), p);
 				Intent intent = new Intent(AudioBrowserActivity.this, AudioPlayerActivity.class);
@@ -55,13 +54,12 @@ public class AudioBrowserActivity extends Activity {
 		});
 		updateLists();
 	}
-	
-	
+
+
 	private ViewSwitchListener mViewSwitchListener = new ViewSwitchListener() {
-				
+
 		int mCurrentPosition = 0;
-		
-		@Override
+
 		public void onSwitching(float progress) {
 			LinearLayout hl = (LinearLayout)findViewById(R.id.header_layout);
 			int width = hl.getChildAt(0).getWidth();
@@ -69,7 +67,6 @@ public class AudioBrowserActivity extends Activity {
 			mHeader.smoothScrollTo(x, 0);
 		}
 
-		@Override
 		public void onSwitched(int position) {
 			LinearLayout hl = (LinearLayout)findViewById(R.id.header_layout);
 			TextView oldView = (TextView)hl.getChildAt(mCurrentPosition);
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioPlayer.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioPlayer.java
index 43c1dc0..32d438e 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioPlayer.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioPlayer.java
@@ -3,9 +3,9 @@ package org.videolan.vlc.android;
 import android.graphics.Bitmap;
 
 public interface AudioPlayer {
-	
+
 	public void update();
-	
+
 	public interface AudioPlayerControl {
 		String getTitle();
 		String getArtist();
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioPlayerActivity.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioPlayerActivity.java
index d7a4210..81e80e8 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioPlayerActivity.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioPlayerActivity.java
@@ -2,17 +2,16 @@ package org.videolan.vlc.android;
 
 import android.app.Activity;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.View;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
 import android.widget.TextView;
+import android.widget.SeekBar.OnSeekBarChangeListener;
 
 public class AudioPlayerActivity extends Activity implements AudioPlayer {
 	public final static String TAG = "VLC/AudioPlayerActiviy";
-	
+
 	private ImageView mCover;
 	private TextView mTitle;
 	private TextView mArtist;
@@ -25,15 +24,15 @@ public class AudioPlayerActivity extends Activity implements AudioPlayer {
 	private ImageButton mShuffle;
 	private ImageButton mRepeat;
 	private SeekBar mTimeline;
-	
+
 	private AudioServiceController mAudioController;
 	private boolean mIsTracking = false;
-	
+
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.audio_player);
-		
+
 		mCover = (ImageView) findViewById(R.id.cover);
 		mTitle = (TextView) findViewById(R.id.title);
 		mArtist = (TextView) findViewById(R.id.artist);
@@ -46,36 +45,36 @@ public class AudioPlayerActivity extends Activity implements AudioPlayer {
 		mShuffle = (ImageButton) findViewById(R.id.shuffle);
 		mRepeat = (ImageButton) findViewById(R.id.repeat);
 		mTimeline = (SeekBar) findViewById(R.id.timeline);
-		
+
 		mAudioController = AudioServiceController.getInstance();
-		
+
 	}
-	
+
 	@Override
 	protected void onStart() {
 		mAudioController.addAudioPlayer(this);
 		update();
 		super.onStart();
 	}
-	
+
 	@Override
 	protected void onStop() {
 		mAudioController.removeAudioPlayer(this);
 		super.onStop();
 	}
 
-	@Override
 	public void update() {
 		// Exit the player when there is no media
 		if (!mAudioController.hasMedia())
 			finish();
-		
-		// mCover....
+
+		mCover.setImageBitmap(mAudioController.getCover());
+
 		mTitle.setText(mAudioController.getTitle());
 		mArtist.setText(mAudioController.getArtist());
 		mAlbum.setText(mAudioController.getAlbum());
-		int time = (int) mAudioController.getTime();
-		int length = (int) mAudioController.getLength();
+		int time = mAudioController.getTime();
+		int length = mAudioController.getLength();
 		mTime.setText(Util.millisToString(time));
 		mLength.setText(Util.millisToString(length));
 		mTimeline.setMax(length);
@@ -85,7 +84,17 @@ public class AudioPlayerActivity extends Activity implements AudioPlayer {
 			mPlayPause.setBackgroundResource(R.drawable.ic_pause);
 		} else {
 			mPlayPause.setBackgroundResource(R.drawable.ic_play);
-		}	
+		}
+		if (mAudioController.isShuffling()) {
+			mShuffle.setImageResource(R.drawable.ic_shuffle_glow);
+		} else {
+			mShuffle.setImageResource(R.drawable.ic_shuffle);
+		}
+		if (mAudioController.isRepeating()) {
+			mRepeat.setImageResource(R.drawable.ic_repeat_glow);
+		} else {
+			mRepeat.setImageResource(R.drawable.ic_repeat);
+		}
 		if (mAudioController.hasNext())
 			mNext.setVisibility(ImageButton.VISIBLE);
 		else
@@ -96,22 +105,19 @@ public class AudioPlayerActivity extends Activity implements AudioPlayer {
 			mPrevious.setVisibility(ImageButton.INVISIBLE);
 		mTimeline.setOnSeekBarChangeListener(mTimelineListner);
 	}
-	
+
 	OnSeekBarChangeListener mTimelineListner = new OnSeekBarChangeListener() {
-		
-		@Override
+
 		public void onStopTrackingTouch(SeekBar arg0) {
 			// TODO Auto-generated method stub
-			
+
 		}
-		
-		@Override
+
 		public void onStartTrackingTouch(SeekBar arg0) {
 			// TODO Auto-generated method stub
-			
+
 		}
-		
-		@Override
+
 		public void onProgressChanged(SeekBar sb, int prog, boolean fromUser) {
 			if (fromUser) {
 				mAudioController.setTime(prog);
@@ -119,7 +125,7 @@ public class AudioPlayerActivity extends Activity implements AudioPlayer {
 ;			}
 		}
 	};
-	
+
 	public void onPlayPauseClick(View view) {
 		if (mAudioController.isPlaying()) {
 			mAudioController.pause();
@@ -127,26 +133,23 @@ public class AudioPlayerActivity extends Activity implements AudioPlayer {
 			mAudioController.play();
 		}
 	}
-	
+
 	public void onNextClick(View view) {
 		mAudioController.next();
 	}
-	
+
 	public void onPreviousClick(View view) {
 		mAudioController.previous();
 	}
-	
+
 	public void onRepeatClick(View view) {
-		// mAudioController.repeat();
-		Util.toaster("not implemented :(");
+		mAudioController.repeat();
+		update();
 	}
-	
+
 	public void onShuffleClick(View view) {
-		// mAudioController.shuffle();
-		Util.toaster("not implemented :(");
+		mAudioController.shuffle();
+		update();
 	}
-	
-	
-	
-	
+
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioService.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioService.java
index 7c7eb05..094c2e5 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioService.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioService.java
@@ -1,315 +1,355 @@
 package org.videolan.vlc.android;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.MediaMetadataRetriever;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.RemoteException;
 import android.util.Log;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
 
 public class AudioService extends Service {
-	private static final String TAG = "VLC/AudioService";
-	
-	private static final int SHOW_PROGRESS = 0;
-	
-	private LibVLC mLibVLC;
-	private ArrayList<Media> mMediaList;
-	private Media mCurrentMedia;
-	private ArrayList<IAudioServiceCallback> mCallback;
-	private EventManager mEventManager;
-	private Notification mNotification;
-
-	@Override
-	public void onStart(Intent intent, int startId) {
-		super.onStart(intent, startId);
-
-		// Get libVLC instance
-        try {
-			mLibVLC = LibVLC.getInstance();
-		} catch (LibVlcException e) {
-			e.printStackTrace();
-		}		
-		
-		mCallback = new ArrayList<IAudioServiceCallback>();
-		mMediaList = new ArrayList<Media>();
-		mEventManager = EventManager.getIntance();
-	}
-	
-	@Override
-	public IBinder onBind(Intent intent) {
-		return mInterface;
+    private static final String TAG = "VLC/AudioService";
+
+    private static final int SHOW_PROGRESS = 0;
+
+    private LibVLC mLibVLC;
+    private ArrayList<Media> mMediaList;
+    private ArrayList<Media> playedMedia;
+    private Media mCurrentMedia;
+    private ArrayList<IAudioServiceCallback> mCallback;
+    private EventManager mEventManager;
+    private Notification mNotification;
+    private boolean shuffling = false, repeating = false;
+    private Stack<Media> previous;
+
+    public void onStart(Intent intent, int startId) {
+	super.onStart(intent, startId);
+
+	// Get libVLC instance
+	try {
+	    mLibVLC = LibVLC.getInstance();
+	} catch (LibVlcException e) {
+	    e.printStackTrace();
 	}
 
-	
+	mCallback = new ArrayList<IAudioServiceCallback>();
+	mMediaList = new ArrayList<Media>();
+	playedMedia = new ArrayList<Media>();
+	previous = new Stack<Media>();
+	mEventManager = EventManager.getIntance();
+    }
+
+    public IBinder onBind(Intent intent) {
+	return mInterface;
+    }
+
     /**
-     *  Handle libvlc asynchronous events 
+     * Handle libvlc asynchronous events
      */
     private Handler mEventHandler = new Handler() {
 
-		@Override
-        public void handleMessage(Message msg) {
-            switch (msg.getData().getInt("event")) {
-                case EventManager.MediaPlayerPlaying:
-                    Log.e(TAG, "MediaPlayerPlaying");
-                    break;
-                case EventManager.MediaPlayerPaused:
-                    Log.e(TAG, "MediaPlayerPaused");
-                    executeUpdate();
-                    // also hide notification if phone ringing
-                    hideNotification(); 
-                    break;
-                case EventManager.MediaPlayerStopped:
-                    Log.e(TAG, "MediaPlayerStopped");
-                    executeUpdate();
-                    break;
-                case EventManager.MediaPlayerEndReached:
-                    Log.e(TAG, "MediaPlayerEndReached");
-                    executeUpdate();
-                    next();
-                    break;
-                default:
-                    Log.e(TAG, "Event not handled");
-                    break;
-            }
-        }
+	public void handleMessage(Message msg) {
+	    switch (msg.getData().getInt("event")) {
+	    case EventManager.MediaPlayerPlaying:
+		Log.e(TAG, "MediaPlayerPlaying");
+		break;
+	    case EventManager.MediaPlayerPaused:
+		Log.e(TAG, "MediaPlayerPaused");
+		executeUpdate();
+		// also hide notification if phone ringing
+		hideNotification();
+		break;
+	    case EventManager.MediaPlayerStopped:
+		Log.e(TAG, "MediaPlayerStopped");
+		executeUpdate();
+		break;
+	    case EventManager.MediaPlayerEndReached:
+		Log.e(TAG, "MediaPlayerEndReached");
+		executeUpdate();
+		next();
+		break;
+	    default:
+		Log.e(TAG, "Event not handled");
+		break;
+	    }
+	}
     };
-    
+
     private void executeUpdate() {
-    	for (int i = 0; i < mCallback.size(); i++) {
-    		try {
-				mCallback.get(i).update();
-			} catch (RemoteException e) {
-				e.printStackTrace();
-			}
-    	}
+	for (int i = 0; i < mCallback.size(); i++) {
+	    try {
+		mCallback.get(i).update();
+	    } catch (RemoteException e) {
+		e.printStackTrace();
+	    }
+	}
     }
-    
-	private Handler mHandler = new Handler() {
-		@Override
-		public void handleMessage(Message msg) {
-			switch (msg.what) {
-				case SHOW_PROGRESS:
-					int pos = (int) mLibVLC.getTime();
-					if (mCallback.size() > 0) {
-						executeUpdate();
-						mHandler.removeMessages(SHOW_PROGRESS);
-						sendEmptyMessageDelayed(SHOW_PROGRESS, 1000 - (pos % 1000));
-					}
-					break;
-			}
+
+    private Handler mHandler = new Handler() {
+
+	public void handleMessage(Message msg) {
+	    switch (msg.what) {
+	    case SHOW_PROGRESS:
+		int pos = (int) mLibVLC.getTime();
+		if (mCallback.size() > 0) {
+		    executeUpdate();
+		    mHandler.removeMessages(SHOW_PROGRESS);
+		    sendEmptyMessageDelayed(SHOW_PROGRESS, 1000 - (pos % 1000));
 		}
-	};
-    
+		break;
+	    }
+	}
+    };
+
     private void showNotification() {
-		// add notification to status bar
-    	if (mNotification == null) {
-    		mNotification = new Notification(R.drawable.icon, null,
-    		        System.currentTimeMillis());
-    	}
-    	Intent notificationIntent = new Intent(this, MainActivity.class);
-		notificationIntent.setAction(Intent.ACTION_MAIN);
-		notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-		notificationIntent.putExtra(MainActivity.START_FROM_NOTIFICATION, "");
-		PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
-		mNotification.setLatestEventInfo(this, mCurrentMedia.getTitle(),
-				mCurrentMedia.getArtist() + " - " + mCurrentMedia.getAlbum(), pendingIntent);
-		startForeground(3, mNotification);
-		
+	// add notification to status bar
+	if (mNotification == null) {
+	    mNotification = new Notification(R.drawable.icon, null, System
+		    .currentTimeMillis());
+	}
+	Intent notificationIntent = new Intent(this, MainActivity.class);
+	notificationIntent.setAction(Intent.ACTION_MAIN);
+	notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+	notificationIntent.putExtra(MainActivity.START_FROM_NOTIFICATION, "");
+	PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
+		notificationIntent, 0);
+	mNotification.setLatestEventInfo(this, mCurrentMedia.getTitle(),
+		mCurrentMedia.getArtist() + " - " + mCurrentMedia.getAlbum(),
+		pendingIntent);
+	startForeground(3, mNotification);
+
     }
-    
+
     private void hideNotification() {
-    	mNotification = null;
-    	stopForeground(true);
+	mNotification = null;
+	stopForeground(true);
     }
-    
-    
-    
+
     private void pause() {
-    	mHandler.removeMessages(SHOW_PROGRESS);
-		// hideNotification(); <-- see event handler
-		mLibVLC.pause();
+	mHandler.removeMessages(SHOW_PROGRESS);
+	// hideNotification(); <-- see event handler
+	mLibVLC.pause();
     }
-    
+
     private void play() {
-    	mLibVLC.play();
-		mHandler.sendEmptyMessage(SHOW_PROGRESS);
-		showNotification();
+	mLibVLC.play();
+	mHandler.sendEmptyMessage(SHOW_PROGRESS);
+	showNotification();
     }
-    
+
     private void stop() {
-		mEventManager.removeHandler(mEventHandler);		
-		mLibVLC.stop();
-		mCurrentMedia = null;
-		mMediaList.clear();
-		mHandler.removeMessages(SHOW_PROGRESS);
-		hideNotification();
-		executeUpdate();
+	mEventManager.removeHandler(mEventHandler);
+	mLibVLC.stop();
+	mCurrentMedia = null;
+	mMediaList.clear();
+	mHandler.removeMessages(SHOW_PROGRESS);
+	hideNotification();
+	executeUpdate();
     }
-    
+
     private void next() {
-    	int index = mMediaList.indexOf(mCurrentMedia);
-        if (index < mMediaList.size() - 1) {
-        	mCurrentMedia = mMediaList.get(index + 1);
-        	mLibVLC.readMedia(mCurrentMedia.getPath());
-        	showNotification();
-        } else {
-        	stop();
-        }
-    }
-    
-	private void previous() {
-		int index = mMediaList.indexOf(mCurrentMedia);
-		if (index > 0) {
-			mCurrentMedia = mMediaList.get(index -1);
-			mLibVLC.readMedia(mCurrentMedia.getPath());
-			showNotification();
-		}
-		
+	int index = mMediaList.indexOf(mCurrentMedia);
+	previous.push(mCurrentMedia);
+	if (playedMedia.size() < mMediaList.size()
+		&& index < mMediaList.size() - 1) {
+	    if (repeating)
+		mCurrentMedia = mMediaList.get(index);
+	    else if (shuffling) {
+		while (playedMedia.contains(mCurrentMedia = mMediaList
+			.get((int) (Math.random() * mMediaList.size()))))
+		    ;
+	    } else
+		mCurrentMedia = mMediaList.get(index + 1);
+	    mLibVLC.readMedia(mCurrentMedia.getPath());
+	    showNotification();
+	} else {
+	    stop();
 	}
-    
+    }
+
+    private void shuffle() {
+	if (shuffling)
+	    playedMedia.clear();
+	shuffling = !shuffling;
+    }
+
+    protected void repeat() {
+	repeating = !repeating;
+    }
+
+    private void previous() {
+	if (previous.size() > 0)
+	    mCurrentMedia = previous.pop();
+	mLibVLC.readMedia(mCurrentMedia.getPath());
+	showNotification();
+    }
+
     private IAudioService.Stub mInterface = new IAudioService.Stub() {
-		
-    	@Override
-    	public String getCurrentMediaPath() throws RemoteException {
-    		return mCurrentMedia.getPath();
-    	}
-
-    	@Override
-    	public void pause() throws RemoteException {
-    		AudioService.this.pause();
-    	}
-
-    	@Override
-    	public void play() throws RemoteException {
-    		AudioService.this.play();
-    	}
-
-    	@Override
-    	public void stop() throws RemoteException {	
-    		AudioService.this.stop();
-    	}
-
-    	@Override
-    	public boolean isPlaying() throws RemoteException {
-    		return mLibVLC.isPlaying();
-    	}
-
-		@Override
-		public boolean hasMedia() throws RemoteException {
-			return mMediaList.size() != 0;
-		}
 
-		@Override
-		public String getAlbum() throws RemoteException {
-			if (mCurrentMedia != null)
-				return mCurrentMedia.getAlbum();
-			else
-				return null;
-		}
+	public String getCurrentMediaPath() throws RemoteException {
+	    return mCurrentMedia.getPath();
+	}
 
-		@Override
-		public String getArtist() throws RemoteException {
-			if (mCurrentMedia != null)
-				return mCurrentMedia.getArtist();
-			else
-				return null;
-		}
+	public void pause() throws RemoteException {
+	    AudioService.this.pause();
+	}
 
-		@Override
-		public String getTitle() throws RemoteException {
-			if (mCurrentMedia != null)
-				return mCurrentMedia.getTitle();
-			else
-				return null;
-		}
+	public void play() throws RemoteException {
+	    AudioService.this.play();
+	}
 
-		@Override
-		public void addAudioCallback(IAudioServiceCallback cb)
-				throws RemoteException {
-			mCallback.add(cb);
-			executeUpdate();
-		}
+	public void stop() throws RemoteException {
+	    AudioService.this.stop();
+	}
 
-		@Override
-		public void removeAudioCallback(IAudioServiceCallback cb)
-				throws RemoteException {
-			if (mCallback.contains(cb)){
-				mCallback.remove(cb);
-			}
-		}
+	public boolean isPlaying() throws RemoteException {
+	    return mLibVLC.isPlaying();
+	}
 
-		@Override
-		public int getTime() throws RemoteException {
-			return (int) mLibVLC.getTime();
-		}
+	public boolean isShuffling() {
+	    return shuffling;
+	}
 
-		@Override
-		public int getLength() throws RemoteException {
-			// TODO Auto-generated method stub
-			return (int) mLibVLC.getLength();
-		}
+	public boolean isRepeating() {
+	    return repeating;
+	}
 
-		@Override
-		public void load(List<String> mediaPathList, int position) 
-				throws RemoteException {
-    		mEventManager.addHandler(mEventHandler); 
-    		mMediaList.clear();
-    		
-    		DatabaseManager db = DatabaseManager.getInstance();
-    		for (int i = 0; i < mediaPathList.size(); i++) {
-    			String path = mediaPathList.get(i);
-    			Media media = db.getMedia(path);
-    			mMediaList.add(media);
-    		}
-    		
-    		if (mMediaList.size() > position) {
-    			mCurrentMedia = mMediaList.get(position);
-    		}
-    		
-    		mLibVLC.readMedia(mCurrentMedia.getPath());
-    		mHandler.sendEmptyMessage(SHOW_PROGRESS);
-    		showNotification();
-			
-		}
+	public boolean hasMedia() throws RemoteException {
+	    return mMediaList.size() != 0;
+	}
 
-		@Override
-		public void next() throws RemoteException {
-			AudioService.this.next();
-		}
+	public String getAlbum() throws RemoteException {
+	    if (mCurrentMedia != null)
+		return mCurrentMedia.getAlbum();
+	    else
+		return null;
+	}
 
-		@Override
-		public void previous() throws RemoteException {
-			AudioService.this.previous();
-		}
+	public String getArtist() throws RemoteException {
+	    if (mCurrentMedia != null)
+		return mCurrentMedia.getArtist();
+	    else
+		return null;
+	}
 
-		@Override
-		public void setTime(long time) throws RemoteException {		
-			mLibVLC.setTime(time);
-		}
+	public String getTitle() throws RemoteException {
+	    if (mCurrentMedia != null)
+		return mCurrentMedia.getTitle();
+	    else
+		return null;
+	}
 
-		@Override
-		public boolean hasNext() throws RemoteException {
-			int index = mMediaList.indexOf(mCurrentMedia);
-	        if (index < mMediaList.size() - 1)
-	        	return true;
-	        else
-	        	return false;
-		}
+	public Bitmap getCover() {
+	    if (mCurrentMedia != null) {
+		try {
+		    MediaMetadataRetriever m = new MediaMetadataRetriever();
+		    m.setDataSource(mCurrentMedia.getPath());
+		    byte[] b = m.getEmbeddedPicture();
+		    if (b != null)
+			return BitmapFactory.decodeByteArray(b, 0, b.length);
+		    File f = new File(mCurrentMedia.getPath());
+		    for (File s : f.getParentFile().listFiles()) {
+			if (s.getAbsolutePath().endsWith("png")
+				|| s.getAbsolutePath().endsWith("jpg"))
+			    return BitmapFactory
+				    .decodeFile(s.getAbsolutePath());
 
-		@Override
-		public boolean hasPrevious() throws RemoteException {
-			int index = mMediaList.indexOf(mCurrentMedia);
-			if (index > 0) 
-				return true;
-			else
-				return false;
+		    }
+		} catch (Exception e) {
 		}
-	};
+	    }
+	    return BitmapFactory.decodeResource(getResources(),R.drawable.thumbnail);
+	}
+
+	public void addAudioCallback(IAudioServiceCallback cb)
+		throws RemoteException {
+	    mCallback.add(cb);
+	    executeUpdate();
+	}
+
+	public void removeAudioCallback(IAudioServiceCallback cb)
+		throws RemoteException {
+	    if (mCallback.contains(cb)) {
+		mCallback.remove(cb);
+	    }
+	}
+
+	public int getTime() throws RemoteException {
+	    return (int) mLibVLC.getTime();
+	}
+
+	public int getLength() throws RemoteException {
+	    return (int) mLibVLC.getLength();
+	}
+
+	public void load(List<String> mediaPathList, int position)
+		throws RemoteException {
+	    mEventManager.addHandler(mEventHandler);
+	    mMediaList.clear();
+	    previous.clear();
+	    playedMedia.clear();
+	    DatabaseManager db = DatabaseManager.getInstance();
+	    for (int i = 0; i < mediaPathList.size(); i++) {
+		String path = mediaPathList.get(i);
+		Media media = db.getMedia(path);
+		mMediaList.add(media);
+	    }
+
+	    if (mMediaList.size() > position) {
+		mCurrentMedia = mMediaList.get(position);
+	    }
+
+	    mLibVLC.readMedia(mCurrentMedia.getPath());
+	    mHandler.sendEmptyMessage(SHOW_PROGRESS);
+	    showNotification();
+
+	}
+
+	public void next() throws RemoteException {
+	    AudioService.this.next();
+	}
+
+	public void shuffle() throws RemoteException {
+	    AudioService.this.shuffle();
+	}
+
+	public void repeat() throws RemoteException {
+	    AudioService.this.repeat();
+	}
+
+	public void previous() throws RemoteException {
+	    AudioService.this.previous();
+	}
+
+	public void setTime(long time) throws RemoteException {
+	    mLibVLC.setTime(time);
+	}
+
+	public boolean hasNext() throws RemoteException {
+	    int index = mMediaList.indexOf(mCurrentMedia);
+	    if (index < mMediaList.size() - 1)
+		return true;
+	    else
+		return false;
+	}
+
+	public boolean hasPrevious() throws RemoteException {
+	    int index = mMediaList.indexOf(mCurrentMedia);
+	    if (index > 0)
+		return true;
+	    else
+		return false;
+	}
+    };
 
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioServiceController.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioServiceController.java
index 0619b46..d207a4e 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioServiceController.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/AudioServiceController.java
@@ -1,11 +1,5 @@
 package org.videolan.vlc.android;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import org.videolan.vlc.android.AudioPlayer.AudioPlayerControl;
-import org.videolan.vlc.android.AudioPlayer;
-
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -14,293 +8,324 @@ import android.graphics.Bitmap;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
+import java.util.ArrayList;
+import java.util.List;
+import org.videolan.vlc.android.AudioPlayer.AudioPlayerControl;
 
 public class AudioServiceController implements AudioPlayerControl {
-	public static final String TAG = "VLC/AudioServiceContoller";
-	
-	private static AudioServiceController mInstance;
-	private static boolean mIsBound = false;
-	private Context mContext;
-	private IAudioService mAudioServiceBinder;
-	private ServiceConnection mAudioServiceConnection;
-	private ArrayList<AudioPlayer> mAudioPlayer;
-	private IAudioServiceCallback mCallback = new IAudioServiceCallback.Stub() {	
-		@Override
-		public void update() throws RemoteException {
-			updateAudioPlayer();		
-		}
-	};
-	
-	private AudioServiceController() {
-		
-		// Get context from MainActivity
-		mContext = MainActivity.getInstance();
-		
-		mAudioPlayer = new ArrayList<AudioPlayer>();
-		
-        // Setup audio service connection
-        mAudioServiceConnection = new ServiceConnection() {	
-			@Override
-			public void onServiceDisconnected(ComponentName name) {
-				Log.d(TAG, "Service Disconnected");
-				mAudioServiceBinder = null;
-			}
-			
-			@Override
-			public void onServiceConnected(ComponentName name, IBinder service) {
-				Log.d(TAG, "Service Connected");
-				mAudioServiceBinder = IAudioService.Stub.asInterface(service);
-				
-				// Register controller to the service
-				try {
-					mAudioServiceBinder.addAudioCallback(mCallback);
-				} catch (RemoteException e) {
-					Log.e(TAG, "remote procedure call failed: addAudioCallback()");
-				}
-				updateAudioPlayer();
-			}
-		};
-	}
-	
-	public static AudioServiceController getInstance() {
-		if (mInstance == null) {
-			mInstance = new AudioServiceController();
-		}
-		if (!mIsBound) {
-			mInstance.bindAudioService();
-		}
-		return mInstance;
+    public static final String TAG = "VLC/AudioServiceContoller";
+
+    private static AudioServiceController mInstance;
+    private static boolean mIsBound = false;
+    private Context mContext;
+    private IAudioService mAudioServiceBinder;
+    private ServiceConnection mAudioServiceConnection;
+    private ArrayList<AudioPlayer> mAudioPlayer;
+    private IAudioServiceCallback mCallback = new IAudioServiceCallback.Stub() {
+
+	public void update() throws RemoteException {
+	    updateAudioPlayer();
 	}
+    };
+
+    private AudioServiceController() {
+
+	// Get context from MainActivity
+	mContext = MainActivity.getInstance();
+
+	mAudioPlayer = new ArrayList<AudioPlayer>();
 
-	public void load(List<String> mediaPathList, int position) {
+	// Setup audio service connection
+	mAudioServiceConnection = new ServiceConnection() {
+
+	    public void onServiceDisconnected(ComponentName name) {
+		Log.d(TAG, "Service Disconnected");
+		mAudioServiceBinder = null;
+	    }
+
+	    public void onServiceConnected(ComponentName name, IBinder service) {
+		Log.d(TAG, "Service Connected");
+		mAudioServiceBinder = IAudioService.Stub.asInterface(service);
+
+		// Register controller to the service
 		try {
-			mAudioServiceBinder.load(mediaPathList, position);
+		    mAudioServiceBinder.addAudioCallback(mCallback);
 		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: load()");
+		    Log.e(TAG,
+			    "remote procedure call failed: addAudioCallback()");
 		}
+		updateAudioPlayer();
+	    }
+	};
+    }
+
+    public static AudioServiceController getInstance() {
+	if (mInstance == null) {
+	    mInstance = new AudioServiceController();
 	}
-	
-	/**
-	 * Bind to audio service if it is running
-	 * @return true if the binding was successful.
-	 */
-	public void bindAudioService() {
-		if (mAudioServiceBinder == null) {
-	    	Intent service = new Intent(mContext, AudioService.class);
-	    	mContext.startService(service);
-	    	mIsBound = mContext.bindService(service, mAudioServiceConnection, Context.BIND_AUTO_CREATE);
-		} else {
-			// Register controller to the service
-			try {
-				mAudioServiceBinder.addAudioCallback(mCallback);
-			} catch (RemoteException e) {
-				Log.e(TAG, "remote procedure call failed: addAudioCallback()");
-			}
-		}
+	if (!mIsBound) {
+	    mInstance.bindAudioService();
 	}
-	
-	public void unbindAudioService() {
-		if (mAudioServiceBinder != null) {
-			try {
-				mAudioServiceBinder.removeAudioCallback(mCallback);
-				if (mIsBound) {
-					mContext.unbindService(mAudioServiceConnection);	
-					mIsBound = false;
-				}
-			} catch (RemoteException e) {
-				Log.e(TAG, "remote procedure call failed: removeAudioCallback()");
-			}
-			
-		}
+	return mInstance;
+    }
+
+    public void load(List<String> mediaPathList, int position) {
+	try {
+	    mAudioServiceBinder.load(mediaPathList, position);
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: load()");
 	}
-	
-	/**
-	 * Add a AudioPlayer
-	 * @param ap
-	 */
-	public void addAudioPlayer(AudioPlayer ap) {
-		mAudioPlayer.add(ap);
+    }
+
+    /**
+     * Bind to audio service if it is running
+     *
+     */
+    public void bindAudioService() {
+	if (mAudioServiceBinder == null) {
+	    Intent service = new Intent(mContext, AudioService.class);
+	    mContext.startService(service);
+	    mIsBound = mContext.bindService(service, mAudioServiceConnection,
+		    Context.BIND_AUTO_CREATE);
+	} else {
+	    // Register controller to the service
+	    try {
+		mAudioServiceBinder.addAudioCallback(mCallback);
+	    } catch (RemoteException e) {
+		Log.e(TAG, "remote procedure call failed: addAudioCallback()");
+	    }
 	}
-	
-	/**
-	 * Remove AudioPlayer from list
-	 * @param ap
-	 */
-	public void removeAudioPlayer(AudioPlayer ap) {
-		if (mAudioPlayer.contains(ap)) {
-			mAudioPlayer.remove(ap);
+    }
+
+    public void unbindAudioService() {
+	if (mAudioServiceBinder != null) {
+	    try {
+		mAudioServiceBinder.removeAudioCallback(mCallback);
+		if (mIsBound) {
+		    mContext.unbindService(mAudioServiceConnection);
+		    mIsBound = false;
 		}
+	    } catch (RemoteException e) {
+		Log.e(TAG,
+			"remote procedure call failed: removeAudioCallback()");
+	    }
+
 	}
-	
-	/**
-	 * Update all AudioPlayer
-	 */
-	private void updateAudioPlayer() {
-		for (int i = 0; i < mAudioPlayer.size(); i++) 
-			mAudioPlayer.get(i).update();
+    }
+
+    /**
+     * Add a AudioPlayer
+     *
+     * @param ap
+     */
+    public void addAudioPlayer(AudioPlayer ap) {
+	mAudioPlayer.add(ap);
+    }
+
+    /**
+     * Remove AudioPlayer from list
+     *
+     * @param ap
+     */
+    public void removeAudioPlayer(AudioPlayer ap) {
+	if (mAudioPlayer.contains(ap)) {
+	    mAudioPlayer.remove(ap);
 	}
-	
-	public void stop() {
-		if (mAudioServiceBinder == null) 
-			return;
-		try {
-			mAudioServiceBinder.stop();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: stop()");
-		}
-		updateAudioPlayer();
+    }
+
+    /**
+     * Update all AudioPlayer
+     */
+    private void updateAudioPlayer() {
+	for (int i = 0; i < mAudioPlayer.size(); i++)
+	    mAudioPlayer.get(i).update();
+    }
+
+    public void stop() {
+	if (mAudioServiceBinder == null)
+	    return;
+	try {
+	    mAudioServiceBinder.stop();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: stop()");
 	}
+	updateAudioPlayer();
+    }
 
-	@Override
-	public String getAlbum() {
-		String album = null;
-		try {
-			album = mAudioServiceBinder.getAlbum();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: getAlbum()");
-		}
-		return album;
+    public String getAlbum() {
+	String album = null;
+	try {
+	    album = mAudioServiceBinder.getAlbum();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: getAlbum()");
 	}
+	return album;
+    }
 
-	@Override
-	public String getArtist() {
-		String artist = null;
-		try {
-			artist = mAudioServiceBinder.getArtist();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: getArtist()");
-		}
-		return artist;
+    public String getArtist() {
+	String artist = null;
+	try {
+	    artist = mAudioServiceBinder.getArtist();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: getArtist()");
 	}
+	return artist;
+    }
 
-	@Override
-	public String getTitle() {
-		String title = null;
-		try {
-			title = mAudioServiceBinder.getTitle();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: getTitle()");
-		}
-		return title;
+    public String getTitle() {
+	String title = null;
+	try {
+	    title = mAudioServiceBinder.getTitle();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: getTitle()");
 	}
-	
-	@Override
-	public boolean isPlaying() {
-		boolean playing = false;
-		if (mAudioServiceBinder != null) {
-			try {
-				playing = (hasMedia() && mAudioServiceBinder.isPlaying());
-				
-			} catch (RemoteException e) {
-				Log.e(TAG, "remote procedure call failed: isPlaying()");
-			}
-		}
-		return playing;
+	return title;
+    }
+
+    public boolean isPlaying() {
+	boolean playing = false;
+	if (mAudioServiceBinder != null) {
+	    try {
+		playing = (hasMedia() && mAudioServiceBinder.isPlaying());
+
+	    } catch (RemoteException e) {
+		Log.e(TAG, "remote procedure call failed: isPlaying()");
+	    }
 	}
-	
-	@Override
-	public void pause() {
-		try {
-			mAudioServiceBinder.pause();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: pause()");
-		}
-		updateAudioPlayer();
+	return playing;
+    }
+
+    public void pause() {
+	try {
+	    mAudioServiceBinder.pause();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: pause()");
 	}
-	
-	@Override
-	public void play() {
-		try {
-			mAudioServiceBinder.play();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: play()");
-		}
-		updateAudioPlayer();
+	updateAudioPlayer();
+    }
+
+    public void play() {
+	try {
+	    mAudioServiceBinder.play();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: play()");
 	}
+	updateAudioPlayer();
+    }
 
-	@Override
-	public boolean hasMedia() {
-		if (mAudioServiceBinder != null) {
-			try {
-				return mAudioServiceBinder.hasMedia();
-			} catch (RemoteException e) {
-				Log.e(TAG, "remote procedure call failed: hasMedia()");
-			}
-		}
-		return false;
+    public boolean hasMedia() {
+	if (mAudioServiceBinder != null) {
+	    try {
+		return mAudioServiceBinder.hasMedia();
+	    } catch (RemoteException e) {
+		Log.e(TAG, "remote procedure call failed: hasMedia()");
+	    }
 	}
+	return false;
+    }
 
-	@Override
-	public int getLength() {
-		try {
-			return mAudioServiceBinder.getLength();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: getLength()");
-		}
-		return 0;
+    public int getLength() {
+	try {
+	    return mAudioServiceBinder.getLength();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: getLength()");
 	}
+	return 0;
+    }
 
-	@Override
-	public int getTime() {
-		try {
-			return mAudioServiceBinder.getTime();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: getTime()");
-		}
-		return 0;
+    public int getTime() {
+	try {
+	    return mAudioServiceBinder.getTime();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: getTime()");
 	}
+	return 0;
+    }
 
-	@Override
-	public Bitmap getCover() {
-		return null;
+    public Bitmap getCover() {
+	try {
+	    return mAudioServiceBinder.getCover();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: getCover()");
+	    return null;
 	}
+    }
 
-	@Override
-	public void next() {
-		try {
-			mAudioServiceBinder.next();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: next()");
-		}
+    public void next() {
+	try {
+	    mAudioServiceBinder.next();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: next()");
 	}
+    }
 
-	@Override
-	public void previous() {
-		try {
-			mAudioServiceBinder.previous();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: previous()");
-		}
+    public void previous() {
+	try {
+	    mAudioServiceBinder.previous();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: previous()");
 	}
+    }
 
-	public void setTime(long time) {
-		try {
-			mAudioServiceBinder.setTime(time);
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: setTime()");
-		}
+    public void setTime(long time) {
+	try {
+	    mAudioServiceBinder.setTime(time);
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: setTime()");
 	}
+    }
 
-	@Override
-	public boolean hasNext() {
-		try {
-			return mAudioServiceBinder.hasNext();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: hasNext()");
-		}
-		return false;
+    public boolean hasNext() {
+	try {
+	    return mAudioServiceBinder.hasNext();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: hasNext()");
 	}
+	return false;
+    }
 
-	@Override
-	public boolean hasPrevious() {
-		try {
-			return mAudioServiceBinder.hasPrevious();
-		} catch (RemoteException e) {
-			Log.e(TAG, "remote procedure call failed: hasPrevious()");
-		}
-		return false;
+    public boolean hasPrevious() {
+	try {
+	    return mAudioServiceBinder.hasPrevious();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: hasPrevious()");
+	}
+	return false;
+    }
+
+    public void shuffle() {
+	try {
+	    mAudioServiceBinder.shuffle();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: shuffle()");
+	}
+    }
+
+    public void repeat() {
+	try {
+	    mAudioServiceBinder.repeat();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: repeat()");
+	}
+
+    }
+
+    public boolean isShuffling() {
+	try {
+	    return mAudioServiceBinder.isShuffling();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: isShuffling()");
+	    return false;
+	}
+    }
+
+    public boolean isRepeating() {
+	try {
+	    return mAudioServiceBinder.isRepeating();
+	} catch (RemoteException e) {
+	    Log.e(TAG, "remote procedure call failed: isRepeating()");
+	    return false;
 	}
-	
-	
+    }
 
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/DatabaseManager.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/DatabaseManager.java
index a56aecf..3a76258 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/DatabaseManager.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/DatabaseManager.java
@@ -1,6 +1,8 @@
 package org.videolan.vlc.android;
 
 
+import android.widget.Toast;
+
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.text.SimpleDateFormat;
@@ -18,16 +20,16 @@ import android.graphics.BitmapFactory;
 
 public class DatabaseManager {
 	public final static String TAG = "VLC/DatabaseManager";
-	
+
 	private static DatabaseManager instance;
 
 	private SQLiteDatabase mDb;
 	private final String DB_NAME = "vlc_database";
 	private final int DB_VERSION = 5;
-	
+
 	private final String DIR_TABLE_NAME = "directories_table";
 	private final String DIR_ROW_PATH = "path";
-	
+
 	private final String MEDIA_TABLE_NAME = "media_table";
 	private final String MEDIA_PATH = "path";
 	private final String MEDIA_TIME = "time";
@@ -38,29 +40,29 @@ public class DatabaseManager {
 	private final String MEDIA_ARTIST = "artist";
 	private final String MEDIA_GENRE = "genre";
 	private final String MEDIA_ALBUM = "album";
-	
+
 	private final String PLAYLIST_TABLE_NAME = "playlist_table";
 	private final String PLAYLIST_NAME = "name";
-	
+
 	private final String PLAYLIST_MEDIA_TABLE_NAME = "playlist_media_table";
 	private final String PLAYLIST_MEDIA_ID = "id";
 	private final String PLAYLIST_MEDIA_PLAYLISTNAME = "playlist_name";
 	private final String PLAYLIST_MEDIA_MEDIAPATH = "media_path";
-	
+
 	private final String SEARCHHISTORY_TABLE_NAME = "searchhistory_table";
 	private final String SEARCHHISTORY_DATE = "date";
 	private final String SEARCHHISTORY_KEY = "key";
-	
+
 	private Context mContext;
-	
-	public enum mediaColumn { MEDIA_TABLE_NAME, MEDIA_PATH, MEDIA_TIME, MEDIA_LENGTH, 
+
+	public enum mediaColumn { MEDIA_TABLE_NAME, MEDIA_PATH, MEDIA_TIME, MEDIA_LENGTH,
 		MEDIA_TYPE, MEDIA_PICTURE, MEDIA_TITLE, MEDIA_ARTIST, MEDIA_GENRE, MEDIA_ALBUM
 	}
-	
-	
+
+
 	/**
-	 * Constructor 
-	 * 
+	 * Constructor
+	 *
 	 * @param context
 	 */
 	private DatabaseManager(Context context) {
@@ -69,7 +71,7 @@ public class DatabaseManager {
 		DatabaseHelper helper = new DatabaseHelper(context);
 		this.mDb = helper.getWritableDatabase();
 	}
-	
+
 	public synchronized static DatabaseManager getInstance() {
         if (instance == null) {
         	Context context = MainActivity.getInstance();
@@ -77,8 +79,8 @@ public class DatabaseManager {
         }
         return instance;
     }
-	
-	
+
+
 	private class DatabaseHelper extends SQLiteOpenHelper {
 
 		public DatabaseHelper(Context context) {
@@ -87,76 +89,76 @@ public class DatabaseManager {
 
 		@Override
 		public void onCreate(SQLiteDatabase db) {
-				
-			String createDirTabelQuery = "CREATE TABLE IF NOT EXISTS " 
-				+ DIR_TABLE_NAME + " (" 
-				+ DIR_ROW_PATH + " TEXT PRIMARY KEY NOT NULL" 
-				+ ");"; 
-			
+
+			String createDirTabelQuery = "CREATE TABLE IF NOT EXISTS "
+				+ DIR_TABLE_NAME + " ("
+				+ DIR_ROW_PATH + " TEXT PRIMARY KEY NOT NULL"
+				+ ");";
+
 			// Create the directories table
 			db.execSQL(createDirTabelQuery);
-			
-			
-			String createMediaTabelQuery = "CREATE TABLE IF NOT EXISTS " 
-				+ MEDIA_TABLE_NAME + " (" 
-				+ MEDIA_PATH + " TEXT PRIMARY KEY NOT NULL, " 		
+
+
+			String createMediaTabelQuery = "CREATE TABLE IF NOT EXISTS "
+				+ MEDIA_TABLE_NAME + " ("
+				+ MEDIA_PATH + " TEXT PRIMARY KEY NOT NULL, "
 				+ MEDIA_TIME + " INTEGER, "
 				+ MEDIA_LENGTH + " INTEGER, "
 				+ MEDIA_TYPE + " INTEGER, "
-				+ MEDIA_PICTURE + " BLOB, "			
+				+ MEDIA_PICTURE + " BLOB, "
 				+ MEDIA_TITLE + " VARCHAR(200), "
 				+ MEDIA_ARTIST + " VARCHAR(200), "
 				+ MEDIA_GENRE + " VARCHAR(200), "
 				+ MEDIA_ALBUM + " VARCHAR(200)"
-				+ ");"; 
-			
-			
+				+ ");";
+
+
 			// Create the media table
 			db.execSQL(createMediaTabelQuery);
-			
+
 			String createPlaylistTableQuery = "CREATE TABLE IF NOT EXISTS " +
 					PLAYLIST_TABLE_NAME + " (" +
 					PLAYLIST_NAME + " VARCHAR(200) PRIMARY KEY NOT NULL);";
-			
+
 			db.execSQL(createPlaylistTableQuery);
-			
+
 			String createPlaylistMediaTableQuery = "CREATE TABLE IF NOT EXISTS " +
 					PLAYLIST_MEDIA_TABLE_NAME + " (" +
 					PLAYLIST_MEDIA_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
 					PLAYLIST_MEDIA_PLAYLISTNAME + " VARCHAR(200) NOT NULL," +
 					PLAYLIST_MEDIA_MEDIAPATH + " TEXT NOT NULL);";
-			
+
 			db.execSQL(createPlaylistMediaTableQuery);
-			
-			
-			String createSearchhistoryTabelQuery = "CREATE TABLE IF NOT EXISTS " 
-				+ SEARCHHISTORY_TABLE_NAME + " (" 
+
+
+			String createSearchhistoryTabelQuery = "CREATE TABLE IF NOT EXISTS "
+				+ SEARCHHISTORY_TABLE_NAME + " ("
 				+ SEARCHHISTORY_KEY + " VARCHAR(200) PRIMARY KEY NOT NULL, "
-				+ SEARCHHISTORY_DATE + " DATETIME NOT NULL" 
-				+ ");"; 
-			
+				+ SEARCHHISTORY_DATE + " DATETIME NOT NULL"
+				+ ");";
+
 			// Create the searchhistory table
 			db.execSQL(createSearchhistoryTabelQuery);
 		}
 
 		@Override
-		public void onUpgrade(SQLiteDatabase db, int oldVersion, 
+		public void onUpgrade(SQLiteDatabase db, int oldVersion,
 				int newVersion) {
 			// TODO ??
 		}
 	}
-	
+
 	/**
 	 * Get all playlists in the database
-	 * @return 
+	 * @return
 	 */
 	public String[] getPlaylists() {
 		ArrayList<String> playlists = new ArrayList<String>();
 		Cursor cursor;
-		
+
 		cursor = mDb.query(
-				PLAYLIST_TABLE_NAME, 
-				new String[] { PLAYLIST_NAME }, 
+				PLAYLIST_TABLE_NAME,
+				new String[] { PLAYLIST_NAME },
 				null, null, null, null, null);
 		cursor.moveToFirst();
 		if (!cursor.isAfterLast()) {
@@ -167,7 +169,7 @@ public class DatabaseManager {
 		cursor.close();
 		return (String[]) playlists.toArray();
 	}
-	
+
 	/**
 	 * Add new playlist
 	 * @param name
@@ -178,33 +180,33 @@ public class DatabaseManager {
 		values.put(PLAYLIST_NAME, name);
 		mDb.insert(PLAYLIST_TABLE_NAME, "NULL", values);
 	}
-	
+
 	public void deletePlaylist(String name) {
-		mDb.delete(PLAYLIST_TABLE_NAME, PLAYLIST_NAME + "=?", 
+		mDb.delete(PLAYLIST_TABLE_NAME, PLAYLIST_NAME + "=?",
 				new String[] { name });
 	}
-	
+
 	public void addMediaToPlaylist(String playlistName, String mediaPath) {
 		ContentValues values = new ContentValues();
 		values.put(PLAYLIST_MEDIA_PLAYLISTNAME, playlistName);
 		values.put(PLAYLIST_MEDIA_MEDIAPATH, mediaPath);
 	}
-	
+
 	public void removeMediaFromPlaylist(String playlistName, String mediaPath) {
-		mDb.delete(PLAYLIST_MEDIA_TABLE_NAME, 
-				PLAYLIST_MEDIA_PLAYLISTNAME + "=? " 
-				+ PLAYLIST_MEDIA_MEDIAPATH + "=?", 
+		mDb.delete(PLAYLIST_MEDIA_TABLE_NAME,
+				PLAYLIST_MEDIA_PLAYLISTNAME + "=? "
+				+ PLAYLIST_MEDIA_MEDIAPATH + "=?",
 				new String[] { playlistName, mediaPath});
 	}
-	
+
 	public Media[] getMediaFromPlaylist(String playlistName) {
 		ArrayList<Media> media = new ArrayList<Media>();
-		
-		Cursor cursor = mDb.query(PLAYLIST_MEDIA_PLAYLISTNAME, 
-				new String[] { PLAYLIST_MEDIA_MEDIAPATH }, 
-				PLAYLIST_MEDIA_PLAYLISTNAME + "=?", new String[]{ playlistName }, 
+
+		Cursor cursor = mDb.query(PLAYLIST_MEDIA_PLAYLISTNAME,
+				new String[] { PLAYLIST_MEDIA_MEDIAPATH },
+				PLAYLIST_MEDIA_PLAYLISTNAME + "=?", new String[]{ playlistName },
 				null, null, "ASC");
-		
+
 		MediaLibrary mediaLibrary = MediaLibrary.getInstance(mContext);
 		cursor.moveToFirst();
 		if (!cursor.isAfterLast()) {
@@ -217,15 +219,15 @@ public class DatabaseManager {
 		return (Media[])media.toArray();
 	}
 
-	
+
 	/**
 	 * Add a new media to the database. The picture can only added by update.
 	 * @param meida which you like to add to the database
 	 */
 	public synchronized void addMedia(Media media) {
-	
+
 		ContentValues values = new ContentValues();
-		
+
 		values.put(MEDIA_PATH, media.getPath());
 		values.put(MEDIA_TIME, media.getTime());
 		values.put(MEDIA_LENGTH, media.getLength());
@@ -234,39 +236,39 @@ public class DatabaseManager {
 		values.put(MEDIA_ARTIST, media.getArtist());
 		values.put(MEDIA_GENRE, media.getGenre());
 		values.put(MEDIA_ALBUM, media.getAlbum());
-		
-		mDb.replace(MEDIA_TABLE_NAME, "NULL", values); 
+
+		mDb.replace(MEDIA_TABLE_NAME, "NULL", values);
 
 	}
-	
+
 //	/**
 //	 * Check if the item already in the database
 //	 * @param path of the item (primary key)
-//	 * @return 
+//	 * @return
 //	 */
 //	public synchronized boolean mediaItemExists(String path) {
-//		Cursor cursor = mDb.query(MEDIA_TABLE_NAME, 
-//				new String[] { DIR_ROW_PATH }, 
-//				MEDIA_PATH + "=?", 
+//		Cursor cursor = mDb.query(MEDIA_TABLE_NAME,
+//				new String[] { DIR_ROW_PATH },
+//				MEDIA_PATH + "=?",
 //				new String[] { path },
 //				null, null, null);
 //		boolean exists = cursor.moveToFirst();
 //		cursor.close();
 //		return exists;
 //	}
-	
+
 	/**
 	 * Get all paths from the items in the database
 	 * @return list of File
 	 */
 	public synchronized List<File> getMediaFiles() {
-		
+
 		List<File> files = new ArrayList<File>();
 		Cursor cursor;
-		
+
 		cursor = mDb.query(
-				MEDIA_TABLE_NAME, 
-				new String[] { MEDIA_PATH }, 
+				MEDIA_TABLE_NAME,
+				new String[] { MEDIA_PATH },
 				null, null, null, null, null);
 		cursor.moveToFirst();
 		if (!cursor.isAfterLast()) {
@@ -279,18 +281,18 @@ public class DatabaseManager {
 
 		return files;
 	}
-	
+
 
 	public synchronized Media getMedia(String path) {
-		
+
 		Cursor cursor;
 		Media media = null;
 		Bitmap picture = null;
 		byte[] blob;
-		
+
 		cursor = mDb.query(
-				MEDIA_TABLE_NAME, 
-				new String[] {  
+				MEDIA_TABLE_NAME,
+				new String[] {
 						MEDIA_TIME,    //0 long
 						MEDIA_LENGTH,  //1 long
 						MEDIA_TYPE,    //2 int
@@ -299,39 +301,38 @@ public class DatabaseManager {
 						MEDIA_ARTIST,  //5 string
 						MEDIA_GENRE,   //6 string
 						MEDIA_ALBUM    //7 string
-						}, 
-				MEDIA_PATH + "=?", 
+						},
+				MEDIA_PATH + "=?",
 				new String[] { path },
 				null, null, null);
+		try {
 		if (cursor.moveToFirst()) {
-				
 			blob = cursor.getBlob(3);
 			if (blob != null) {
 				picture = BitmapFactory.decodeByteArray(blob, 0, blob.length);
 			}
-			
-			media = new Media(mContext, new File(path), cursor.getLong(0), 
-					cursor.getLong(1), cursor.getInt(2), 
-					picture, cursor.getString(4), 
-					cursor.getString(5), cursor.getString(6), 
-					cursor.getString(7));
-		}
 
+			media = new Media(mContext, new File(path), cursor.getLong(0),
+					cursor.getLong(1), cursor.getInt(2),
+					picture, cursor.getString(4),
+					cursor.getString(5), cursor.getString(6),
+					cursor.getString(7));
+		}}catch(Exception e) {}
 		return media;
 	}
-	
+
 	public synchronized void removeMedia(String path) {
 		mDb.delete(MEDIA_TABLE_NAME, MEDIA_PATH + "=?", new String[] { path });
 	}
-	
-	public synchronized void updateMedia(String path, mediaColumn col, 
+
+	public synchronized void updateMedia(String path, mediaColumn col,
 			Object object ) {
 		ContentValues values = new ContentValues();
 		switch (col) {
-		case MEDIA_PICTURE:	
+		case MEDIA_PICTURE:
 			Bitmap picture = (Bitmap)object;
 			ByteArrayOutputStream out = new ByteArrayOutputStream();
-			picture.compress(Bitmap.CompressFormat.PNG, 100, out);		
+			picture.compress(Bitmap.CompressFormat.PNG, 100, out);
 			values.put(MEDIA_PICTURE, out.toByteArray());
 			break;
 		default:
@@ -339,24 +340,24 @@ public class DatabaseManager {
 		}
 		mDb.update(MEDIA_TABLE_NAME, values, MEDIA_PATH +"=?", new String[] { path });
 	}
-	
-	
-	/** 
+
+
+	/**
 	 * Add directory to the directories table
-	 * 
+	 *
 	 * @param path
 	 */
-	public synchronized void addDir(String path) {	
+	public synchronized void addDir(String path) {
 		if (!mediaDirExists(path)) {
 			ContentValues values = new ContentValues();
 			values.put(DIR_ROW_PATH, path);
-			mDb.insert(DIR_TABLE_NAME, null, values); 
+			mDb.insert(DIR_TABLE_NAME, null, values);
 		}
 	}
-	
+
 	/**
 	 * Delete directory from directories table
-	 * 
+	 *
 	 * @param path
 	 */
 	public synchronized void removeDir(String path) {
@@ -364,17 +365,17 @@ public class DatabaseManager {
 	}
 
 	/**
-	 * 
+	 *
 	 * @return
 	 */
 	public synchronized List<File> getMediaDirs() {
-		
+
 		List<File> paths = new ArrayList<File>();
 		Cursor cursor;
-		
+
 		cursor = mDb.query(
-				DIR_TABLE_NAME, 
-				new String[] { DIR_ROW_PATH }, 
+				DIR_TABLE_NAME,
+				new String[] { DIR_ROW_PATH },
 				null, null, null, null, null);
 		cursor.moveToFirst();
 		if (!cursor.isAfterLast()) {
@@ -387,54 +388,54 @@ public class DatabaseManager {
 
 		return paths;
 	}
-	
+
 	public synchronized boolean mediaDirExists(String path) {
-		Cursor cursor = mDb.query(DIR_TABLE_NAME, 
-				new String[] { DIR_ROW_PATH }, 
-				DIR_ROW_PATH + "=?", 
-				new String[] { path }, 
+		Cursor cursor = mDb.query(DIR_TABLE_NAME,
+				new String[] { DIR_ROW_PATH },
+				DIR_ROW_PATH + "=?",
+				new String[] { path },
 				null, null, null);
 		boolean exists = cursor.moveToFirst();
 		cursor.close();
 		return exists;
 	}
-	
+
 	/**
-	 * 
+	 *
 	 * @param key
 	 */
 	public synchronized void addSearchhistoryItem(String key) {
 		// set the format to sql date time
-		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 		Date date = new Date();
 		ContentValues values = new ContentValues();
 		values.put(SEARCHHISTORY_KEY, key);
 		values.put(SEARCHHISTORY_DATE, dateFormat.format(date));
-		
-		mDb.replace(SEARCHHISTORY_TABLE_NAME, null, values); 
+
+		mDb.replace(SEARCHHISTORY_TABLE_NAME, null, values);
 	}
-	
-	
+
+
 	public synchronized ArrayList<String> getSearchhistory(int size) {
 		ArrayList<String> history = new ArrayList<String>();
-		
-		Cursor cursor = mDb.query(SEARCHHISTORY_TABLE_NAME, 
-				new String[] { SEARCHHISTORY_KEY }, 
-				null, null, null, null, 
+
+		Cursor cursor = mDb.query(SEARCHHISTORY_TABLE_NAME,
+				new String[] { SEARCHHISTORY_KEY },
+				null, null, null, null,
 				SEARCHHISTORY_DATE + " DESC",
 				Integer.toString(size));
-		
+
 		while(cursor.moveToNext()) {
 			history.add(cursor.getString(0));
 		}
 		cursor.close();
-		
+
 		return history;
 	}
-	
+
 	public synchronized void clearSearchhistory() {
 		mDb.delete(SEARCHHISTORY_TABLE_NAME, null, null);
 	}
-	
+
 
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/IAudioService.aidl b/extras/package/android/vlc-android/src/org/videolan/vlc/android/IAudioService.aidl
index d31cd1c..b694057 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/IAudioService.aidl
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/IAudioService.aidl
@@ -6,11 +6,15 @@ interface IAudioService {
 	void pause();
 	void stop();
 	void next();
+	void shuffle();
+	void repeat();
 	void previous();
 	void setTime(long time);
 	String getCurrentMediaPath();
 	void load(in List<String> mediaPathList, int position);
 	boolean isPlaying();
+	boolean isShuffling();
+	boolean isRepeating();
 	boolean hasMedia();
 	boolean hasNext();
 	boolean hasPrevious();
@@ -19,6 +23,7 @@ interface IAudioService {
 	String getAlbum();
 	int getTime();
 	int getLength();
+	Bitmap getCover();
 	void addAudioCallback(IAudioServiceCallback cb);
 	void removeAudioCallback(IAudioServiceCallback cb);
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/MainActivity.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/MainActivity.java
index d0220ac..c08e37e 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/MainActivity.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/MainActivity.java
@@ -35,32 +35,32 @@ public class MainActivity extends TabActivity {
 	private static final int AUDIO_TAB = 1;
 	public static final String START_FROM_NOTIFICATION = "from_notification";
 	private static final String PREF_SHOW_INFO = "show_info";
-	
+
 	private VideoListActivity mVideoListActivity;
-	
-	private static MainActivity mInstance;	
+
+	private static MainActivity mInstance;
 	private ProgressBar mProgressBar;
 	private TabHost mTabHost;
 	private int mCurrentState = 0;
 	private ImageButton mChangeTab;
 	private AudioMiniPlayer mAudioPlayer;
 	private AudioServiceController mAudioController;
-	
+
 	private SharedPreferences mSettings;
 
 	private int mVersionNumber = -1;
-	
 
-	@Override   
-	protected void onCreate(Bundle savedInstanceState) {	
-		setContentView(R.layout.main);	
-		super.onCreate(savedInstanceState); 
-		
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		setContentView(R.layout.main);
+		super.onCreate(savedInstanceState);
+
 		/* Get settings */
 		mSettings = PreferenceManager.getDefaultSharedPreferences(this);
 
 		/* Initialize variables */
-		mInstance = this;	
+		mInstance = this;
 		mProgressBar = (ProgressBar)findViewById(R.id.ml_progress_bar);
 		mChangeTab = (ImageButton) findViewById(R.id.change_tab);
 
@@ -68,22 +68,22 @@ public class MainActivity extends TabActivity {
         mTabHost = getTabHost();
         mTabHost.addTab(mTabHost.newTabSpec("VIDEO TAB").setIndicator("VIDEO TAB")
         		.setContent(new Intent(this, VideoActivityGroup.class)));
-        
+
         mTabHost.addTab(mTabHost.newTabSpec("AUDIO TAB").setIndicator("AUDIO TAB")
         		.setContent(new Intent(this, AudioActivityGroup.class)));
-        
+
         // Get video list instance to sort the list.
         mVideoListActivity = VideoListActivity.getInstance();
-        
+
         // add mini audio player
         mAudioPlayer = (AudioMiniPlayer) findViewById(R.id.audio_mini_player);
 		mAudioController = AudioServiceController.getInstance();
 		mAudioController.addAudioPlayer(mAudioPlayer);
 		mAudioPlayer.setAudioPlayerControl(mAudioController);
 		mAudioPlayer.update();
-		
-		
-		
+
+
+
         // Start audio player when audio is playing
         if (getIntent().hasExtra(START_FROM_NOTIFICATION)) {
         	Log.d(TAG, "Started from notification.");
@@ -92,7 +92,7 @@ public class MainActivity extends TabActivity {
         	// TODO: load the last tab-state
         	showVideoTab();
         }
-        
+
         /* Show info/alpha/beta Warning */
         PackageInfo pinfo = null;
 		try {
@@ -102,16 +102,16 @@ public class MainActivity extends TabActivity {
 		}
 		if (pinfo != null) {
 			mVersionNumber = pinfo.versionCode;
-        
+
 	        if (mSettings.getInt(PREF_SHOW_INFO, -1) != mVersionNumber)
 	        	showInfoDialog();
 		}
-        
+
         /* Load media items from database and storage */
         MediaLibrary.getInstance(this).loadMediaItems();
 	}
 
-	/** Create menu from XML 
+	/** Create menu from XML
 	 */
 	@Override
 	public boolean onCreateOptionsMenu(Menu menu) {
@@ -132,10 +132,10 @@ public class MainActivity extends TabActivity {
 	 */
 	@Override
 	public boolean onOptionsItemSelected(MenuItem item) {
-		
+
 		// Intent to start new Activity
 		Intent intent;
-		
+
 		// Handle item selection
 		switch (item.getItemId()) {
 		// Sort by name
@@ -143,17 +143,18 @@ public class MainActivity extends TabActivity {
 			if (mCurrentState == VIDEO_TAB) {
 				mVideoListActivity.sortBy(
 						VideoListAdapter.SORT_BY_TITLE);
-			} 
+			}
 			break;
 			// Sort by length
 		case R.id.ml_menu_sortby_length:
 			if (mCurrentState == VIDEO_TAB) {
 				mVideoListActivity.sortBy(
 						VideoListAdapter.SORT_BY_LENGTH);
-			} 
+			}
 			break;
 		// About
 		case R.id.ml_menu_about:
+		    	assert false;
 			intent = new Intent(this, AboutActivity.class);
 			startActivity(intent);
 			break;
@@ -165,7 +166,7 @@ public class MainActivity extends TabActivity {
 		}
 		return super.onOptionsItemSelected(item);
 	}
-	
+
 	@Override
 	public boolean onContextItemSelected(MenuItem item) {
 		switch (item.getItemId()) {
@@ -176,7 +177,7 @@ public class MainActivity extends TabActivity {
 				mAudioController.play();
 			}
 		case R.id.show_player:
-			// TODO: start audio player activity 
+			// TODO: start audio player activity
 			break;
 		case R.id.hide_mini_player:
 			hideAudioPlayer();
@@ -189,19 +190,19 @@ public class MainActivity extends TabActivity {
 		mAudioPlayer.setVisibility(AudioMiniPlayer.GONE);
 		mAudioController.stop();
 	}
-	
+
 	public void showAudioPlayer() {
 		mAudioPlayer.setVisibility(AudioMiniPlayer.VISIBLE);
 	}
-	
+
 	private void showInfoDialog() {
         final Dialog infoDialog = new Dialog(this, R.style.info_dialog);
         infoDialog.setContentView(R.layout.info_dialog);
         Button okButton = (Button) infoDialog.findViewById(R.id.ok);
         okButton.setOnClickListener(new OnClickListener() {
-			@Override
+
 			public void onClick(View view) {
-				CheckBox notShowAgain = 
+				CheckBox notShowAgain =
 						(CheckBox) infoDialog.findViewById(R.id.not_show_again);
 				if (notShowAgain.isChecked() && mSettings != null) {
 					Editor editor = mSettings.edit();
@@ -213,8 +214,8 @@ public class MainActivity extends TabActivity {
 		});
         infoDialog.show();
 	}
-	
-	
+
+
 	/**
 	 * onClick event from xml
 	 * @param view
@@ -227,20 +228,20 @@ public class MainActivity extends TabActivity {
 			showVideoTab();
 		}
 	}
-	
+
 	private void showVideoTab() {
 		mChangeTab.setImageResource(R.drawable.header_icon_audio);
 		mTabHost.setCurrentTab(VIDEO_TAB);
 		mCurrentState = VIDEO_TAB;
 	}
-	
+
 	private void showAudioTab() {
 		mChangeTab.setImageResource(R.drawable.header_icon_video);
 		mTabHost.setCurrentTab(AUDIO_TAB);
 		mCurrentState = AUDIO_TAB;
 	}
-	
-	
+
+
 	/**
 	 * onClick event from xml
 	 * @param view
@@ -254,10 +255,10 @@ public class MainActivity extends TabActivity {
 	 * @return this ;)
 	 */
 	public static MainActivity getInstance() {
-		return mInstance;	
+		return mInstance;
 	}
-	
-	protected Handler mHandler = new Handler() {	
+
+	protected Handler mHandler = new Handler() {
 		@Override
 		public void handleMessage(Message msg) {
 			switch (msg.what) {
@@ -265,10 +266,10 @@ public class MainActivity extends TabActivity {
 				mProgressBar.setVisibility(View.VISIBLE);
 				break;
 			case HIDE_PROGRESSBAR:
-				mProgressBar.setVisibility(View.INVISIBLE);	
+				mProgressBar.setVisibility(View.INVISIBLE);
 				break;
 			}
 		};
 	};
-    
+
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/Media.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/Media.java
index 4e0b2a9..97b4087 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/Media.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/Media.java
@@ -21,12 +21,12 @@ public class Media implements Comparable<Media> {
 		 ".a52", ".aac", ".ac3", ".adt", ".adts", ".aif", ".aifc", ".aiff", ".amr", ".aob", ".ape",
 		 ".awb", ".cda", ".dts", ".flac", ".it", ".m4a", ".m4p", ".mid", ".mka", ".mlp", ".mod",
 		 ".mp1", ".mp2", ".mp3", ".mpc", ".oga", ".ogg", ".oma", ".rmi", ".s3m", ".spx", ".tta",
-		 ".voc", ".vqf", ".w64", ".wav", ".wma", ".wv", ".xa", ".xm"};	
-	
+		 ".voc", ".vqf", ".w64", ".wav", ".wma", ".wv", ".xa", ".xm"};
+
 	public final static int TYPE_ALL = -1;
 	public final static int TYPE_VIDEO = 0;
 	public final static int TYPE_AUDIO = 1;
-	
+
 	/** Meta data form libvlc_media */
 	private String mTitle;
 	private String mArtist;
@@ -50,13 +50,13 @@ public class Media implements Comparable<Media> {
 	private int mWidth = 0;
 	private int mHeight = 0;
 	private Bitmap mPicture;
-	
+
 	private Context mContext;
 
 
 	/**
 	 * Create an new Media
-	 * @param file: path on the local storage
+	 * @param file path on the local storage
 	 */
 	public Media(Context context, File file) {
 		this.mFile = file;
@@ -66,6 +66,7 @@ public class Media implements Comparable<Media> {
     	try {
 			mLibVlc = LibVLC.getInstance();
 			mType = (mLibVlc.hasVideoTrack(file.getPath())) ? TYPE_VIDEO : TYPE_AUDIO;
+			if(file.getPath().endsWith("mpg"))mType=TYPE_VIDEO;
 			mLength = mLibVlc.getLengthFromFile(file.getPath());
 
             String[] array = mLibVlc.readMediaMeta(file.getPath());
@@ -74,7 +75,6 @@ public class Media implements Comparable<Media> {
             for(i=0; i < array.length; i++) {
                 String s = array[i++];
                 String v = array[i];
-
                 if (s.equals("title")) {
                     mTitle = v;
                     Log.d(TAG, "Title " + mTitle);
@@ -98,23 +98,23 @@ public class Media implements Comparable<Media> {
 		db.addMedia(this);
 	}
 
-	
-	public Media(Context context, File file, long time, long length, int type, 
+
+	public Media(Context context, File file, long time, long length, int type,
 			Bitmap picture, String title, String artist, String genre, String album) {
 		mContext = context;
-		
+
 		mFile = file;
 		mTime = time;
 		mLength = length;
 		mType = type;
 		mPicture = picture;
-		
+
 		mTitle = title;
 		mArtist = artist;
 		mGenre = genre;
 		mAlbum = album;
 	}
-	
+
 	/**
 	 * Compare the filenames to sort items
 	 */
@@ -122,17 +122,17 @@ public class Media implements Comparable<Media> {
 		return mTitle.toUpperCase().compareTo(
 				another.getTitle().toUpperCase());
 	}
-	
+
 	public File getFile() {
 		return mFile;
 	}
-	
+
 	public String getPath() {
 		return mFile.getPath();
 	}
 
 	public void updateMeta() {
-		
+
 	}
 
 	public String getFileName() {
@@ -142,7 +142,7 @@ public class Media implements Comparable<Media> {
 	public long getTime() {
 		return mTime;
 	}
-	
+
 	public void setTime(long time) {
 		mTime = time;
 	}
@@ -182,7 +182,7 @@ public class Media implements Comparable<Media> {
 		else
 			return mTitle;
 	}
-	
+
 	public String getArtist() {
 		if (mArtist == null)
 			return mContext.getString(R.string.unknown_artist);
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/MediaInfoActivity.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/MediaInfoActivity.java
index b6460b5..ccf3324 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/MediaInfoActivity.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/MediaInfoActivity.java
@@ -17,7 +17,7 @@ public class MediaInfoActivity extends Activity {
 	private Media mItem;
 	private Bitmap mImage;
 	private final static int NEW_IMAGE = 0;
-	
+
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
@@ -26,26 +26,25 @@ public class MediaInfoActivity extends Activity {
 		if (path == null)
 			return;
 		mItem = MediaLibrary.getInstance(this).getMediaItem(path);
-				
+
 		// set title
 		TextView titleView = (TextView)findViewById(R.id.title);
 		titleView.setText(mItem.getTitle());
-		
+
 		// set length
 		TextView lengthView = (TextView)findViewById(R.id.length);
 		lengthView.setText(Util.millisToString(mItem.getLength()));
-		
+
 		new Thread(mLoadImage).start();
-		
+
 	}
-	
+
 	@Override
 	public void onBackPressed() {
 		Log.e(TAG, TAG + " onBackPressed()");
 	}
-	
-	Runnable mLoadImage = new Runnable() {	
-		@Override
+
+	Runnable mLoadImage = new Runnable() {
 		public void run() {
 			LibVLC mLibVlc = null;
 			try {
@@ -53,10 +52,10 @@ public class MediaInfoActivity extends Activity {
 			} catch (LibVlcException e) {
 				return;
 			}
-			
+
             int width = getWindowManager().getDefaultDisplay().getHeight();
             int height = width;
-            
+
             // Get the thumbnail.
             mImage = Bitmap.createBitmap(width, height, Config.ARGB_8888);
 
@@ -65,7 +64,7 @@ public class MediaInfoActivity extends Activity {
             if (b == null) // We were not able to create a thumbnail for this item.
             	return;
 
-            
+
             mImage.copyPixelsFromBuffer(ByteBuffer.wrap(b));
             int top = 0;
             for (int i = 0; i < height; i++) {
@@ -76,7 +75,7 @@ public class MediaInfoActivity extends Activity {
             		break;
             	}
             }
-            
+
             int left = 0;
             for (int i = 0; i < width; i++) {
             	int pixel = mImage.getPixel(i, height/2);
@@ -86,30 +85,30 @@ public class MediaInfoActivity extends Activity {
             		break;
             	}
             }
-            
+
             // Cut off the transparency on the borders
-            mImage = Bitmap.createBitmap(mImage, top, left, 
+            mImage = Bitmap.createBitmap(mImage, top, left,
 					(width - (2 * top)), (height - (2 * left)));
-            
+
             mHandler.sendEmptyMessage(NEW_IMAGE);
 		}
 	};
-	
-	
-	
+
+
+
 	Handler mHandler = new Handler() {
-		
+
 		public void handleMessage(Message msg) {
 			switch (msg.what) {
 			case NEW_IMAGE:
-				ImageView imageView = 
+				ImageView imageView =
 					(ImageView)MediaInfoActivity.this.findViewById(R.id.image);
 				imageView.setImageBitmap(mImage);
 				imageView.setVisibility(ImageView.VISIBLE);
 				break;
 			}
 		};
-		
+
 	};
 
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/MediaLibrary.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/MediaLibrary.java
index 4bbe259..bbe73b5 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/MediaLibrary.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/MediaLibrary.java
@@ -15,35 +15,35 @@ import android.os.Handler;
 
 public class MediaLibrary {
 	public final static String TAG = "VLC/MediaLibrary";
-	
+
 	protected static final int MEDIA_ITEMS_UPDATED = 100;
 
 	private static MediaLibrary mInstance;
-	private DatabaseManager mDBManager;	
+	private DatabaseManager mDBManager;
 	private ArrayList<Media> mItemList;
 	private final CyclicBarrier mBarrier = new CyclicBarrier(2);
 	private ArrayList<Handler> mUpdateHandler;
 	protected Context mContext;
-	
+
 	private MediaLibrary(Context context) {
 		mInstance = this;
 		mContext = context;
 		mItemList = new ArrayList<Media>();
 		mUpdateHandler = new ArrayList<Handler>();
-		mDBManager = DatabaseManager.getInstance();	
+		mDBManager = DatabaseManager.getInstance();
 	}
-	
+
 	public void loadMediaItems() {
 		new Thread(mGetMediaItems).start();
 	}
-	
+
 
 	public static MediaLibrary getInstance(Context context) {
 		if (mInstance == null)
 			mInstance = new MediaLibrary(context);
 		return mInstance;
 	}
-	
+
 	public void addUpdateHandler(Handler handler) {
 		mUpdateHandler.add(handler);
 	}
@@ -58,7 +58,7 @@ public class MediaLibrary {
 		}
 		return videoItems;
 	}
-	
+
 	public ArrayList<Media> getAudioItems() {
 		ArrayList<Media> videoItems = new ArrayList<Media>();
 		for (int i = 0; i < mItemList.size(); i++) {
@@ -69,11 +69,11 @@ public class MediaLibrary {
 		}
 		return videoItems;
 	}
-	
+
 	public ArrayList<Media> getMediaItems() {
 		return mItemList;
 	}
-	
+
 	public Media getMediaItem(String path) {
 		for (int i = 0; i < mItemList.size(); i++) {
 			Media item = mItemList.get(i);
@@ -83,10 +83,10 @@ public class MediaLibrary {
 		}
 		return null;
 	}
-	
-	
+
+
 	private final Runnable mGetMediaItems = new Runnable() {
-    	
+
     	private Stack<File> directorys = new Stack<File>();
     	private  MainActivity mMainActivity;
 
@@ -94,41 +94,41 @@ public class MediaLibrary {
 			// Initialize variables
 			mMainActivity = MainActivity.getInstance();
 			Handler mainHandler = mMainActivity.mHandler;
-			
-			
+
+
 			// show progressbar in header
-			mainHandler.sendEmptyMessage(MainActivity.SHOW_PROGRESSBAR);	
-			
+			mainHandler.sendEmptyMessage(MainActivity.SHOW_PROGRESSBAR);
+
 			// get directories from database
 			directorys.addAll(mDBManager.getMediaDirs());
-			
+
 			// get all paths of the existing media items
 			List<File> existingFiles = mDBManager.getMediaFiles();
-			
+
 			// list of all added files
 			List<File> addedFiles = new ArrayList<File>();
-			
+
 			// clear all old item
 			mItemList.clear();
-			
+
 	    	MediaItemFilter mediaFileFilter = new MediaItemFilter();
-	    	
-	    	
+
+
 	    	while (!directorys.isEmpty()) {
 	    		File dir = directorys.pop();
 	    		File[] f = null;
-	    		if ((f = dir.listFiles(mediaFileFilter)) != null) {		    	  	
+	    		if ((f = dir.listFiles(mediaFileFilter)) != null) {
 			    	for (int i = 0; i < f.length; i++) {
 			    		if (f[i].isFile()) {
 			    			if (existingFiles.contains(f[i])) {
-			    				
-			    				/** only add file if it is not already in the 
+
+			    				/** only add file if it is not already in the
 			    				 * list. eg. if user select an subfolder as well
 			    				 */
 			    				if (!addedFiles.contains(f[i])) {
 				    				// get existing media item from database
 				    				mItemList.add(mDBManager.getMedia(
-				    						f[i].getPath()));	
+				    						f[i].getPath()));
 				    				addedFiles.add( f[i] );
 			    				}
 			    			} else {
@@ -138,17 +138,17 @@ public class MediaLibrary {
 			    		} else if (f[i].isDirectory()) {
 			    			directorys.push(f[i]);
 			    		}
-			    	}   
+			    	}
 		    	}
 	    	}
-	    	
+
 	    	// update the video and audio activities
 	    	for (int i = 0; i < mUpdateHandler.size(); i++) {
 	    		Handler h = mUpdateHandler.get(i);
 	    		h.sendEmptyMessage(MEDIA_ITEMS_UPDATED);
 	    	}
-	    	
-	    	
+
+
 			try {
 				mBarrier.await();
 			} catch (InterruptedException e) {
@@ -156,8 +156,8 @@ public class MediaLibrary {
 			} catch (BrokenBarrierException e) {
 				e.printStackTrace();
 			}
-	    	
-	    	// remove file from database 
+
+	    	// remove file from database
 	    	for (int i = 0; i < existingFiles.size(); i++) {
 	    		if (!addedFiles.contains(existingFiles.get(i))) {
 		    		mDBManager.removeMedia(existingFiles.get(i).getPath());
@@ -165,18 +165,18 @@ public class MediaLibrary {
 	    	}
 	    	// hide progressbar in header
 	    	mainHandler.sendEmptyMessage(MainActivity.HIDE_PROGRESSBAR);
-			
+
 		}
     };
 
-	
-	/** 
-	 * Filters all irrelevant files 
+
+	/**
+	 * Filters all irrelevant files
 	 */
     private class MediaItemFilter implements FileFilter {
-    	
+
     	// FIXME: save extensions in external database
-    	private String[] extensions = Media.EXTENTIONS; 
+    	private String[] extensions = Media.EXTENTIONS;
 		public boolean accept(File f) {
 			boolean accepted = false;
 			if (!f.isHidden()) {
@@ -192,6 +192,6 @@ public class MediaLibrary {
 				}
 			}
 			return accepted;
-		}   	
+		}
     }
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/SearchActivity.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/SearchActivity.java
index 70f401f..e34cb5b 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/SearchActivity.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/SearchActivity.java
@@ -24,208 +24,215 @@ import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
 
 public class SearchActivity extends ListActivity {
-	public final static String TAG = "VLC/SearchActivit";
-	
-	private EditText mSearchText;
-	private ArrayAdapter<String> mHistoryAdapter;
-	private ArrayList<String> mHistory = new ArrayList<String>();
-	private SearchResultAdapter mResultAdapter;
-	private LinearLayout mListHeader;
-	
+    public final static String TAG = "VLC/SearchActivit";
+
+    private EditText mSearchText;
+    private ArrayAdapter<String> mHistoryAdapter;
+    private ArrayList<String> mHistory = new ArrayList<String>();
+    private SearchResultAdapter mResultAdapter;
+    private LinearLayout mListHeader;
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.search);
-        
-        // TODO: create layout
-        mResultAdapter = new SearchResultAdapter(this, android.R.layout.simple_list_item_1);
-        
-        mSearchText = (EditText)findViewById(R.id.search_text);
-        mSearchText.setOnEditorActionListener(searchTextListener);
-        mSearchText.addTextChangedListener(searchTextWatcher);		
-        
-        final Intent queryIntent = getIntent();
-		final String queryAction = queryIntent.getAction();
-		if (Intent.ACTION_SEARCH.equals(queryAction)) {
-			String query = queryIntent.getStringExtra(SearchManager.QUERY);
-			mSearchText.setText(query);
-			mSearchText.setSelection(query.length());
-		} else {
-			InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
-	    	imm.showSoftInput(mSearchText, InputMethodManager.RESULT_SHOWN);
-	    	showSearchHistory();
-		}
-		
-		
-		mSearchText.requestFocus();
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.search);
+
+	// TODO: create layout
+	mResultAdapter = new SearchResultAdapter(this,
+		android.R.layout.simple_list_item_1);
+
+	mSearchText = (EditText) findViewById(R.id.search_text);
+	mSearchText.setOnEditorActionListener(searchTextListener);
+	mSearchText.addTextChangedListener(searchTextWatcher);
+
+	final Intent queryIntent = getIntent();
+	final String queryAction = queryIntent.getAction();
+	if (Intent.ACTION_SEARCH.equals(queryAction)) {
+	    String query = queryIntent.getStringExtra(SearchManager.QUERY);
+	    mSearchText.setText(query);
+	    mSearchText.setSelection(query.length());
+	} else {
+	    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+	    imm.showSoftInput(mSearchText, InputMethodManager.RESULT_SHOWN);
+	    showSearchHistory();
+	}
+
+	mSearchText.requestFocus();
 
     }
-    
+
     private void search(CharSequence key, int type) {
-    	
-    	// set result adapter to the list 
-		mResultAdapter.clear();
-		String[] keys = key.toString().split("\\s+");
-		ArrayList<Media> allItems = MediaLibrary.getInstance(this).getMediaItems();
-		int results = 0;
-		for (int i = 0; i < allItems.size(); i++) {
-			Media item = allItems.get(i);
-			if (type != Media.TYPE_ALL && type != item.getType())
-				continue;
-			boolean add = true;
-			String name = item.getTitle().toLowerCase();
-			String path = item.getPath().toLowerCase();
-			for (int k = 0; k < keys.length; k++) {
-				if (!(name.contains(keys[k].toLowerCase()) ||
-						path.contains(keys[k].toLowerCase()))) {
-					add = false;
-					break;
-				}
-			}
-
-			if (add) {
-				mResultAdapter.add(item);
-				results++;
-			}
 
+	// set result adapter to the list
+	mResultAdapter.clear();
+	String[] keys = key.toString().split("\\s+");
+	ArrayList<Media> allItems = MediaLibrary.getInstance(this)
+		.getMediaItems();
+	int results = 0;
+	for (int i = 0; i < allItems.size(); i++) {
+	    Media item = allItems.get(i);
+	    if (type != Media.TYPE_ALL && type != item.getType())
+		continue;
+	    boolean add = true;
+	    String name = item.getTitle().toLowerCase();
+	    String path = item.getPath().toLowerCase();
+	    for (int k = 0; k < keys.length; k++) {
+		if (!(name.contains(keys[k].toLowerCase()) || path
+			.contains(keys[k].toLowerCase()))) {
+		    add = false;
+		    break;
 		}
-		mResultAdapter.sort();
-		
-		String headerText = getString(R.string.search_found_results, results);
-    	showListHeader(headerText);
-		
-    	setListAdapter(mResultAdapter);
+	    }
+
+	    if (add) {
+		mResultAdapter.add(item);
+		results++;
+	    }
+
+	}
+	mResultAdapter.sort();
+
+	String headerText = getString(R.string.search_found_results, results);
+	showListHeader(headerText);
+
+	setListAdapter(mResultAdapter);
     }
-    
-    
+
     private void showListHeader(String text) {
-    	ListView lv = getListView();
-    	
-    	// create a new header if not exists
-    	if (mListHeader == null) {
-    		LayoutInflater infalter = getLayoutInflater();
-        	mListHeader = (LinearLayout) infalter.inflate(R.layout.list_header, lv, false);
-        	lv.addHeaderView(mListHeader, null, false);
-    	} 
-    	
-    	// set header text
-    	TextView headerText = (TextView)mListHeader.findViewById(R.id.text);
-    	headerText.setText(text);
+	ListView lv = getListView();
+
+	// create a new header if not exists
+	if (mListHeader == null) {
+	    LayoutInflater infalter = getLayoutInflater();
+	    mListHeader = (LinearLayout) infalter.inflate(R.layout.list_header,
+		    lv, false);
+	    lv.addHeaderView(mListHeader, null, false);
+	}
+
+	// set header text
+	TextView headerText = (TextView) mListHeader.findViewById(R.id.text);
+	headerText.setText(text);
     }
 
-    
     private void showSearchHistory() {
 
-    	// Add header to the history
-    	String headerText = getString(R.string.search_history);
-    	showListHeader(headerText);
-    	
-    	DatabaseManager db = DatabaseManager.getInstance();
-    	mHistory.clear();
-    	mHistory.addAll(db.getSearchhistory(20)); 
-    	if (mHistoryAdapter == null) {
-    		mHistoryAdapter = new ArrayAdapter<String>(this, 
-    				android.R.layout.simple_list_item_1, mHistory);
-    	} else {
-    		mHistoryAdapter.notifyDataSetChanged();
-    	}
-    	setListAdapter(mHistoryAdapter);
+	// Add header to the history
+	String headerText = getString(R.string.search_history);
+	showListHeader(headerText);
+
+	DatabaseManager db = DatabaseManager.getInstance();
+	mHistory.clear();
+	mHistory.addAll(db.getSearchhistory(20));
+	if (mHistoryAdapter == null) {
+	    mHistoryAdapter = new ArrayAdapter<String>(this,
+		    android.R.layout.simple_list_item_1, mHistory);
+	} else {
+	    mHistoryAdapter.notifyDataSetChanged();
+	}
+	setListAdapter(mHistoryAdapter);
     }
-    
+
     private TextWatcher searchTextWatcher = new TextWatcher() {
-		
-		@Override
-		public void onTextChanged(CharSequence s, int start, int before, int count) {
-			if (s.length() > 0) {
-				search(s, Media.TYPE_ALL);
-			} else {
-				showSearchHistory();
-			}
-		}
-		
-		@Override
-		public void beforeTextChanged(CharSequence s, int start, int count,
-				int after) {
-			
-		}
-		
-		@Override
-		public void afterTextChanged(Editable s) {
-			
-		}
-	};
-	
-	/** Create menu from XML 
-	 */
-	@Override
-	public boolean onCreateOptionsMenu(Menu menu) {
-		MenuInflater inflater = getMenuInflater();
-		inflater.inflate(R.menu.search, menu);
-		return super.onCreateOptionsMenu(menu);
+
+	public void onTextChanged(CharSequence s, int start, int before,
+		int count) {
+	    if (s.length() > 0) {
+		search(s, Media.TYPE_ALL);
+	    } else {
+		showSearchHistory();
+	    }
 	}
-	
-	/**
-	 * Handle onClick form menu buttons
-	 */
-	@Override
-	public boolean onOptionsItemSelected(MenuItem item) {
-
-		// Handle item selection
-		switch (item.getItemId()) {
-		// Sort by name
-		case R.id.search_clear_history:
-			DatabaseManager db = DatabaseManager.getInstance();
-			db.clearSearchhistory();
-			if (mHistoryAdapter == getListAdapter())
-				showSearchHistory();
-		}
-		return super.onOptionsItemSelected(item);
+
+	public void beforeTextChanged(CharSequence s, int start, int count,
+		int after) {
+
 	}
-	
-    
-    private OnEditorActionListener searchTextListener = new OnEditorActionListener() {	
-		@Override
-		public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-			InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
-	    	imm.hideSoftInputFromWindow(mSearchText.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
-			return false;
-		}
-	};
-	
-	protected void onListItemClick(ListView l, View v, int position, long id) {
-		if (getListAdapter() == mHistoryAdapter) {
-			String selection = ((TextView)v.findViewById(android.R.id.text1)).getText().toString();
-			mSearchText.setText(selection);
-			mSearchText.setSelection(selection.length());
-			mSearchText.requestFocus();
-		} else if (getListAdapter() == mResultAdapter) {
-			// add search text to the database (history)
-			DatabaseManager db = DatabaseManager.getInstance();
-			db.addSearchhistoryItem(mSearchText.getText().toString());
-			
-			// open media in the player
-			Media item = (Media) getListAdapter().getItem(position - 1);
-			Intent intent = new Intent(this, VideoPlayerActivity.class);
-			intent.putExtra("filePath", item.getPath());
-			startActivity(intent);
-			super.onListItemClick(l, v, position, id);
-			
-		}
-	};
-	
-	@Override
-	public boolean onKeyDown(int keyCode, KeyEvent event) {
-		if (keyCode == KeyEvent.KEYCODE_SEARCH) {
-			mSearchText.requestFocus();
-			mSearchText.setSelection(mSearchText.getText().length());
-			InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
-	    	imm.showSoftInput(mSearchText, InputMethodManager.RESULT_SHOWN);
-	        return true;
+
+	public void afterTextChanged(Editable s) {
+
+	}
+    };
+
+    /**
+     * Create menu from XML
+     */
+
+    public boolean onCreateOptionsMenu(Menu menu) {
+	MenuInflater inflater = getMenuInflater();
+	inflater.inflate(R.menu.search, menu);
+	return super.onCreateOptionsMenu(menu);
+    }
+
+    /**
+     * Handle onClick form menu buttons
+     */
+
+    public boolean onOptionsItemSelected(MenuItem item) {
+
+	// Handle item selection
+	switch (item.getItemId()) {
+	// Sort by name
+	case R.id.search_clear_history:
+	    DatabaseManager db = DatabaseManager.getInstance();
+	    db.clearSearchhistory();
+	    if (mHistoryAdapter == getListAdapter())
+		showSearchHistory();
+	}
+	return super.onOptionsItemSelected(item);
+    }
+
+    private OnEditorActionListener searchTextListener = new OnEditorActionListener() {
+
+	public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+	    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+	    imm.hideSoftInputFromWindow(mSearchText.getWindowToken(),
+		    InputMethodManager.HIDE_NOT_ALWAYS);
+	    return false;
+	}
+    };
+
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+	if (getListAdapter() == mHistoryAdapter) {
+	    String selection = ((TextView) v.findViewById(android.R.id.text1))
+		    .getText().toString();
+	    mSearchText.setText(selection);
+	    mSearchText.setSelection(selection.length());
+	    mSearchText.requestFocus();
+	} else if (getListAdapter() == mResultAdapter) {
+	    // add search text to the database (history)
+	    DatabaseManager db = DatabaseManager.getInstance();
+	    db.addSearchhistoryItem(mSearchText.getText().toString());
+
+	    // open media in the player
+	    Media item = (Media) getListAdapter().getItem(position - 1);
+	    Intent intent;
+	    if (item.getType() == Media.TYPE_VIDEO) {
+		intent = new Intent(this, VideoPlayerActivity.class);
+		intent.putExtra("filePath", item.getPath());
+		startActivity(intent);
+	    } else {
+		ArrayList<String> arr = new ArrayList<String>();
+		for (int i=0;i<getListAdapter().getCount();i++)
+		    arr.add(((Media)getListAdapter().getItem(i)).getPath());
+		AudioServiceController.getInstance().load(arr, position-1);
+		intent = new Intent(this, AudioPlayerActivity.class);
+		startActivity(intent);
 	    }
+	    super.onListItemClick(l, v, position, id);
+
+	}
+    };
 
-		return super.onKeyDown(keyCode, event);
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+	if (keyCode == KeyEvent.KEYCODE_SEARCH) {
+	    mSearchText.requestFocus();
+	    mSearchText.setSelection(mSearchText.getText().length());
+	    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+	    imm.showSoftInput(mSearchText, InputMethodManager.RESULT_SHOWN);
+	    return true;
 	}
-    
-    
+
+	return super.onKeyDown(keyCode, event);
+    }
 
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/SearchResultAdapter.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/SearchResultAdapter.java
index c656d34..eb92b1d 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/SearchResultAdapter.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/SearchResultAdapter.java
@@ -9,31 +9,30 @@ import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.TextView;
 
-public class SearchResultAdapter extends ArrayAdapter<Media> 
+public class SearchResultAdapter extends ArrayAdapter<Media>
 									implements Comparator<Media>  {
 
 	public SearchResultAdapter(Context context, int textViewResourceId) {
 		super(context, textViewResourceId);
 	}
-			
+
 	@Override
 	public View getView(int position, View convertView, ViewGroup parent) {
 		View v = convertView;
 		if (v == null){
-			LayoutInflater inflater = (LayoutInflater) 
+			LayoutInflater inflater = (LayoutInflater)
 					getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-			v = inflater.inflate(android.R.layout.simple_list_item_1, 
+			v = inflater.inflate(android.R.layout.simple_list_item_1,
 					parent, false);
 		}
 
 		Media item = getItem(position);
 		TextView textView = (TextView)v.findViewById(android.R.id.text1);
 		textView.setText(item.getTitle());
-		
+
 		return v;
 	}
 
-	@Override
 	public int compare(Media object1, Media object2) {
 		return object1.getTitle().compareToIgnoreCase(object2.getTitle());
 	}
@@ -41,7 +40,7 @@ public class SearchResultAdapter extends ArrayAdapter<Media>
 	public void sort() {
 		super.sort(this);
 	}
-	
-	
+
+
 
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/VideoListAdapter.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/VideoListAdapter.java
index de44388..3119acf 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/VideoListAdapter.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/VideoListAdapter.java
@@ -15,22 +15,22 @@ import android.widget.ArrayAdapter;
 import android.widget.ImageView;
 import android.widget.TextView;
 
-public class VideoListAdapter extends ArrayAdapter<Media> 
+public class VideoListAdapter extends ArrayAdapter<Media>
 								 implements Comparator<Media> {
 
 	public final static int SORT_BY_TITLE = 0;
 	public final static int SORT_BY_LENGTH = 1;
 	private int mSortDirection = 1;
 	private int mSortBy = SORT_BY_TITLE;
-	
-	
-	
+
+
+
 	public VideoListAdapter(Context context, int textViewResourceId) {
 		super(context, textViewResourceId);
 	}
 
 	public final static String TAG = "VLC/MediaLibraryAdapter";
-	
+
 
 	public synchronized void update(Media item) {
 		int position = getPosition(item);
@@ -39,7 +39,7 @@ public class VideoListAdapter extends ArrayAdapter<Media>
 			insert(item, position);
 		}
 	}
-	
+
 	public void sortBy(int sortby) {
 		switch (sortby) {
 		case SORT_BY_TITLE:
@@ -65,9 +65,9 @@ public class VideoListAdapter extends ArrayAdapter<Media>
 		}
 		sort();
 	}
-	
+
 	public void sort() {
-		super.sort(this);		
+		super.sort(this);
 	}
 
 	public int compare(Media item1, Media item2) {
@@ -83,8 +83,8 @@ public class VideoListAdapter extends ArrayAdapter<Media>
 		}
 		return mSortDirection * compare;
 	}
-	
-	
+
+
 
 	/**
      * Display the view of a file browser item.
@@ -94,9 +94,9 @@ public class VideoListAdapter extends ArrayAdapter<Media>
 
 		View v = convertView;
 		if (v == null){
-			LayoutInflater inflater = (LayoutInflater) 
+			LayoutInflater inflater = (LayoutInflater)
 					getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-			v = inflater.inflate(R.layout.video_list_item, 
+			v = inflater.inflate(R.layout.video_list_item,
 					parent, false);
 		}
 
@@ -107,7 +107,7 @@ public class VideoListAdapter extends ArrayAdapter<Media>
 		titleView.setText(media.getTitle());
 		lengthView.setText(" " + Util.millisToString(media.getLength()) + " ");
 		ImageView moreView = (ImageView)v.findViewById(R.id.ml_item_more);
-		
+
 		Bitmap thumbnail;
 		if (media.getPicture() != null) {
 			thumbnail = media.getPicture();
@@ -115,20 +115,19 @@ public class VideoListAdapter extends ArrayAdapter<Media>
 		} else {
 			// set default thumbnail
 			thumbnail = BitmapFactory.decodeResource(
-					MainActivity.getInstance().getResources(), 
+					MainActivity.getInstance().getResources(),
 					R.drawable.thumbnail);
 			thumbnailView.setImageBitmap(thumbnail);
 		}
-		
+
 		moreView.setTag(media);
 		moreView.setOnClickListener(moreClickListener);
-		
+
 		return v;
 	}
 
 	private OnClickListener moreClickListener = new OnClickListener() {
-		
-		@Override
+
 		public void onClick(View v) {
 			Media item = (Media)v.getTag();
 			Intent intent = new Intent(getContext(), MediaInfoActivity.class);
@@ -137,6 +136,6 @@ public class VideoListAdapter extends ArrayAdapter<Media>
 			group.startChildAcitvity("MediaInfo", intent);
 		}
 	};
-	
+
 }
 
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/VideoPlayerActivity.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/VideoPlayerActivity.java
index 2cf16f4..956c920 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/VideoPlayerActivity.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/VideoPlayerActivity.java
@@ -33,561 +33,554 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
 
 public class VideoPlayerActivity extends Activity {
 
-	public final static String TAG = "VLC/VideoPlayerActivity";
-
-	private SurfaceView mSurface;
-	private SurfaceHolder mSurfaceHolder;
-	private LibVLC mLibVLC;
-	
-	private static final int SURFACE_FIT_HORIZONTAL = 0;
-	private static final int SURFACE_FIT_VERTICAL = 1;
-	private static final int SURFACE_FILL = 2;
-	private static final int SURFACE_16_9 = 3;
-	private static final int SURFACE_4_3 = 4;
-	private static final int SURFACE_ORIGINAL = 5;
-	private int mCurrentSize = SURFACE_FIT_HORIZONTAL;
-	
-	/** Overlay */
-	private LinearLayout mOverlay;
-	private LinearLayout mDecor;
-	private View mSpacer;
-	private static final int OVERLAY_TIMEOUT = 4000;
-	private static final int FADE_OUT = 1;
-	private static final int SHOW_PROGRESS = 2;
-	private static final int SURFACE_SIZE = 3;
-	private static final int FADE_OUT_INFO = 4;
-	private boolean mDragging;
-	private boolean mShowing;
-	private SeekBar mSeekbar;
-	private TextView mTime;
-	private TextView mLength;
-	private TextView mInfo;
-	private ImageButton mPause;
-	private ImageButton mLock;
-	private ImageButton mSize;
-	
-	// size of the video
-	private int mVideoHeight;
-	private int mVideoWidth;
+    public final static String TAG = "VLC/VideoPlayerActivity";
+
+    private SurfaceView mSurface;
+    private SurfaceHolder mSurfaceHolder;
+    private LibVLC mLibVLC;
+
+    private static final int SURFACE_FIT_HORIZONTAL = 0;
+    private static final int SURFACE_FIT_VERTICAL = 1;
+    private static final int SURFACE_FILL = 2;
+    private static final int SURFACE_16_9 = 3;
+    private static final int SURFACE_4_3 = 4;
+    private static final int SURFACE_ORIGINAL = 5;
+    private int mCurrentSize = SURFACE_FIT_HORIZONTAL;
+
+    /** Overlay */
+    private LinearLayout mOverlay;
+    private LinearLayout mDecor;
+    private View mSpacer;
+    private static final int OVERLAY_TIMEOUT = 4000;
+    private static final int FADE_OUT = 1;
+    private static final int SHOW_PROGRESS = 2;
+    private static final int SURFACE_SIZE = 3;
+    private static final int FADE_OUT_INFO = 4;
+    private boolean mDragging;
+    private boolean mShowing;
+    private SeekBar mSeekbar;
+    private TextView mTime;
+    private TextView mLength;
+    private TextView mInfo;
+    private ImageButton mPause;
+    private ImageButton mLock;
+    private ImageButton mSize;
+
+    // size of the video
+    private int mVideoHeight;
+    private int mVideoWidth;
+
+    // stop screen from dimming
+    private WakeLock mWakeLock;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.player);
 
 	// stop screen from dimming
-	private WakeLock mWakeLock;
-	
-	@Override
-	protected void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.player);
-		
-		// stop screen from dimming
-		PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
-		mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, TAG);
-		
-		/** initialize Views an their Events */
-		mDecor = (LinearLayout)findViewById(R.id.player_overlay_decor);
-		mSpacer = (View)findViewById(R.id.player_overlay_spacer);
-		mSpacer.setOnTouchListener(mTouchListener);
-		
-		LayoutInflater inflater = (LayoutInflater) getSystemService(
-				Context.LAYOUT_INFLATER_SERVICE);
-		mOverlay = (LinearLayout)inflater.inflate(R.layout.player_overlay, null);
-		
-		mTime = (TextView) mOverlay.findViewById(R.id.player_overlay_time);
-		mLength = (TextView) mOverlay.findViewById(R.id.player_overlay_length);
-		// the info textView is not on the overlay
-		mInfo = (TextView) findViewById(R.id.player_overlay_info);
-		
-		mPause = (ImageButton) mOverlay.findViewById(R.id.player_overlay_play);
-		mPause.setOnClickListener(mPauseListener);
-		
-		mLock = (ImageButton) mOverlay.findViewById(R.id.player_overlay_lock);
-		mLock.setOnClickListener(mLockListener);
-		
-		mSize = (ImageButton) mOverlay.findViewById(R.id.player_overlay_size);
-		mSize.setOnClickListener(mSizeListener);
-		
-		mSurface = (SurfaceView) findViewById(R.id.player_surface);
-		mSurfaceHolder = mSurface.getHolder();	
-		mSurfaceHolder.setKeepScreenOn(true);
-		mSurfaceHolder.setFormat(PixelFormat.RGBX_8888);
-		mSurfaceHolder.addCallback(mSurfaceCallback);
-
-		mSeekbar = (SeekBar)mOverlay.findViewById(R.id.player_overlay_seekbar);	
-		mSeekbar.setOnSeekBarChangeListener(mSeekListener);
-
-        try {
-			mLibVLC = LibVLC.getInstance();
-		} catch (LibVlcException e) {
-			e.printStackTrace();
-		}		
-
-		EventManager em = EventManager.getIntance();
-		em.addHandler(eventHandler);
-
-		load();
-		
+	PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+	mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, TAG);
+
+	/** initialize Views an their Events */
+	mDecor = (LinearLayout) findViewById(R.id.player_overlay_decor);
+	mSpacer = findViewById(R.id.player_overlay_spacer);
+	mSpacer.setOnTouchListener(mTouchListener);
+
+	LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+	mOverlay = (LinearLayout) inflater.inflate(R.layout.player_overlay,
+		null);
+
+	mTime = (TextView) mOverlay.findViewById(R.id.player_overlay_time);
+	mLength = (TextView) mOverlay.findViewById(R.id.player_overlay_length);
+	// the info textView is not on the overlay
+	mInfo = (TextView) findViewById(R.id.player_overlay_info);
+
+	mPause = (ImageButton) mOverlay.findViewById(R.id.player_overlay_play);
+	mPause.setOnClickListener(mPauseListener);
+
+	mLock = (ImageButton) mOverlay.findViewById(R.id.player_overlay_lock);
+	mLock.setOnClickListener(mLockListener);
+
+	mSize = (ImageButton) mOverlay.findViewById(R.id.player_overlay_size);
+	mSize.setOnClickListener(mSizeListener);
+
+	mSurface = (SurfaceView) findViewById(R.id.player_surface);
+	mSurfaceHolder = mSurface.getHolder();
+	mSurfaceHolder.setKeepScreenOn(true);
+	mSurfaceHolder.setFormat(PixelFormat.RGBX_8888);
+	mSurfaceHolder.addCallback(mSurfaceCallback);
+	mSeekbar = (SeekBar) mOverlay.findViewById(R.id.player_overlay_seekbar);
+	mSeekbar.setOnSeekBarChangeListener(mSeekListener);
+
+	try {
+	    mLibVLC = LibVLC.getInstance();
+	} catch (LibVlcException e) {
+	    e.printStackTrace();
 	}
-		
-		
-	@Override
-	protected void onPause() {
-		if (mLibVLC.isPlaying())
-			pause();
-		super.onPause();
+
+	EventManager em = EventManager.getIntance();
+	em.addHandler(eventHandler);
+
+	load();
+
+    }
+
+    @Override
+    protected void onPause() {
+	if (mLibVLC.isPlaying())
+	    pause();
+	super.onPause();
+    }
+
+    @Override
+    protected void onDestroy() {
+	if (mLibVLC != null) {
+	    mLibVLC.stop();
 	}
 
-	@Override
-	protected void onDestroy() {
-		if (mLibVLC != null) {
-			mLibVLC.stop();
-		}
-		
-		EventManager em = EventManager.getIntance();
-		em.removeHandler(eventHandler);
-		
-		super.onDestroy();
+	EventManager em = EventManager.getIntance();
+	em.removeHandler(eventHandler);
+
+	super.onDestroy();
+    }
+
+    @Override
+    public boolean onTrackballEvent(MotionEvent event) {
+	showOverlay();
+	return true;
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+	setSurfaceSize(mVideoWidth, mVideoHeight);
+	super.onConfigurationChanged(newConfig);
+    }
+
+    public void setSurfaceSize(int width, int height) {
+	// store video size
+	mVideoHeight = height;
+	mVideoWidth = width;
+	Message msg = mHandler.obtainMessage(SURFACE_SIZE);
+	mHandler.sendMessage(msg);
+    }
+
+    /**
+     * Lock screen rotation
+     */
+    private void lockScreen() {
+	WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
+	Display display = wm.getDefaultDisplay();
+
+	switch (display.getRotation()) {
+	case Surface.ROTATION_0:
+	    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+	    break;
+	case Surface.ROTATION_90:
+	    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+	    break;
+	case Surface.ROTATION_270:
+	    // FIXME: API Level 9+ (not tested on a device with API Level < 9)
+	    setRequestedOrientation(8); // SCREEN_ORIENTATION_REVERSE_LANDSCAPE
+	    break;
 	}
 
+	showInfo("locked", 500);
+    }
+
+    /**
+     * Remove screen lock
+     */
+    private void unlockScreen() {
+	setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
+	showInfo("unlocked", 500);
+    }
+
+    /**
+     * Show text in the info view for "duration" milliseconds
+     *
+     * @param text
+     * @param duration
+     */
+    private void showInfo(String text, int duration) {
+	mInfo.setVisibility(View.VISIBLE);
+	mInfo.setText(text);
+	mHandler.removeMessages(FADE_OUT_INFO);
+	mHandler.sendEmptyMessageDelayed(FADE_OUT_INFO, duration);
+    }
+
+    /**
+     * Show text in the info view
+     *
+     * @param text
+     */
+    private void showInfo(String text) {
+	mInfo.setVisibility(View.VISIBLE);
+	mInfo.setText(text);
+	mHandler.removeMessages(FADE_OUT_INFO);
+    }
+
+    /**
+     * hide the info view with "delay" milliseconds delay
+     *
+     * @param delay
+     */
+    private void hideInfo(int delay) {
+	mHandler.sendEmptyMessageDelayed(FADE_OUT_INFO, delay);
+    }
+
+    /**
+     * hide the info view
+     */
+    private void hideInfo() {
+	hideInfo(0);
+    }
+
+    /**
+     * Handle libvlc asynchronous events
+     */
+    private Handler eventHandler = new Handler() {
 	@Override
-	public boolean onTrackballEvent(MotionEvent event) {
-		showOverlay();
-		return true;
+	public void handleMessage(Message msg) {
+	    switch (msg.getData().getInt("event")) {
+	    case EventManager.MediaPlayerPlaying:
+		Log.e(TAG, "MediaPlayerPlaying");
+		break;
+	    case EventManager.MediaPlayerPaused:
+		Log.e(TAG, "MediaPlayerPaused");
+		break;
+	    case EventManager.MediaPlayerStopped:
+		Log.e(TAG, "MediaPlayerStopped");
+		break;
+	    case EventManager.MediaPlayerEndReached:
+		Log.e(TAG, "MediaPlayerEndReached");
+		/* Exit player when reach the end */
+		VideoPlayerActivity.this.finish();
+		break;
+	    default:
+		Log.e(TAG, "Event not handled");
+		break;
+	    }
+	    updateOverlayPausePlay();
 	}
-	
+    };
 
-    @Override
-	public void onConfigurationChanged(Configuration newConfig) {
-		setSurfaceSize(mVideoWidth, mVideoHeight);
-		super.onConfigurationChanged(newConfig);
+    /**
+     * Handle resize of the surface and the overlay
+     */
+    private Handler mHandler = new Handler() {
+
+	@Override
+	public void handleMessage(Message msg) {
+	    switch (msg.what) {
+	    case FADE_OUT:
+		hideOverlay(false);
+		break;
+	    case SHOW_PROGRESS:
+		int pos = setOverlayProgress();
+		if (!mDragging && mShowing && mLibVLC.isPlaying()) {
+		    msg = obtainMessage(SHOW_PROGRESS);
+		    sendMessageDelayed(msg, 1000 - (pos % 1000));
+		}
+		break;
+	    case SURFACE_SIZE:
+		changeSurfaceSize();
+		break;
+	    case FADE_OUT_INFO:
+		mInfo.startAnimation(AnimationUtils.loadAnimation(
+			VideoPlayerActivity.this, android.R.anim.fade_out));
+		mInfo.setVisibility(View.INVISIBLE);
+	    }
 	}
+    };
+
+    private void changeSurfaceSize() {
+	// get screen size
+	int dw = getWindowManager().getDefaultDisplay().getWidth();
+	int dh = getWindowManager().getDefaultDisplay().getHeight();
 
+	// calculate aspect ratio
+	double ar = (double) mVideoWidth / (double) mVideoHeight;
+	// calculate display aspect ratio
+	double dar = (double) dw / (double) dh;
 
-	public void setSurfaceSize(int width, int height) {
-		// store video size
-		mVideoHeight = height;
-		mVideoWidth = width;	
-		Message msg = mHandler.obtainMessage(SURFACE_SIZE);
-		mHandler.sendMessage(msg);
+	switch (mCurrentSize) {
+	case SURFACE_FIT_HORIZONTAL:
+	    dh = (int) (dw / ar);
+	    break;
+	case SURFACE_FIT_VERTICAL:
+	    dw = (int) (dh * ar);
+	    break;
+	case SURFACE_FILL:
+	    break;
+	case SURFACE_16_9:
+	    ar = 16.0 / 9.0;
+	    if (dar < ar)
+		dh = (int) (dw / ar);
+	    else
+		dw = (int) (dh * ar);
+	    break;
+	case SURFACE_4_3:
+	    ar = 4.0 / 3.0;
+	    if (dar < ar)
+		dh = (int) (dw / ar);
+	    else
+		dw = (int) (dh * ar);
+	    break;
+	case SURFACE_ORIGINAL:
+	    dh = mVideoHeight;
+	    dw = mVideoWidth;
+	    break;
+	}
+
+	mSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
+	LayoutParams lp = mSurface.getLayoutParams();
+	lp.width = dw;
+	lp.height = dh;
+	mSurface.setLayoutParams(lp);
+	mSurface.invalidate();
     }
-	
-	/**
-	 * Lock screen rotation
-	 */
-	private void lockScreen() {
-		WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
-		Display display = wm.getDefaultDisplay();
-		
-		switch (display.getRotation()) {
-		case Surface.ROTATION_0:
-			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-			break;
-		case Surface.ROTATION_90:
-			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-			break;
-		case Surface.ROTATION_270:
-			// FIXME: API Level 9+ (not tested on a device with API Level < 9)
-			setRequestedOrientation(8); // SCREEN_ORIENTATION_REVERSE_LANDSCAPE
-			break;
+
+    /**
+     * show/hide the overlay
+     */
+    private OnTouchListener mTouchListener = new OnTouchListener() {
+	public boolean onTouch(View v, MotionEvent event) {
+	    if (event.getAction() == MotionEvent.ACTION_DOWN) {
+		if (!mShowing) {
+		    showOverlay();
+		} else {
+		    hideOverlay(true);
 		}
-		
-		showInfo("locked", 500);
+	    }
+	    return false;
 	}
-	
-	/**
-	 * Remove screen lock
-	 */
-	private void unlockScreen() {
-		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
-		showInfo("unlocked", 500);
+    };
+
+    /**
+     * handle changes of the seekbar (slicer)
+     */
+    private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
+
+	public void onStartTrackingTouch(SeekBar seekBar) {
+	    mDragging = true;
+	    showOverlay(3600000);
 	}
-	
-	/**
-	 * Show text in the info view for "duration" milliseconds
-	 * @param text
-	 * @param duration
-	 */
-	private void showInfo(String text, int duration) {
-		mInfo.setVisibility(View.VISIBLE);
-		mInfo.setText(text);
-		mHandler.removeMessages(FADE_OUT_INFO);
-		mHandler.sendEmptyMessageDelayed(FADE_OUT_INFO, duration);
+
+	public void onStopTrackingTouch(SeekBar seekBar) {
+	    mDragging = false;
+	    showOverlay();
+	    hideInfo();
+	}
+
+	public void onProgressChanged(SeekBar seekBar, int progress,
+		boolean fromUser) {
+	    if (fromUser) {
+		mLibVLC.setTime(progress);
+		setOverlayProgress();
+		mTime.setText(Util.millisToString(progress));
+		showInfo(Util.millisToString(progress));
+	    }
+
 	}
-	
-	/**
-	 * Show text in the info view
-	 * @param text
+    };
+
+    /**
+	 *
 	 */
-	private void showInfo(String text) {
-		mInfo.setVisibility(View.VISIBLE);
-		mInfo.setText(text);
-		mHandler.removeMessages(FADE_OUT_INFO);
+    private OnClickListener mPauseListener = new OnClickListener() {
+	public void onClick(View v) {
+	    doPausePlay();
+	    showOverlay();
 	}
-	
-	/**
-	 * hide the info view with "delay" milliseconds delay
-	 * @param delay
+    };
+
+    /**
+	 *
 	 */
-	private void hideInfo(int delay) {
-		mHandler.sendEmptyMessageDelayed(FADE_OUT_INFO, delay);
+    private OnClickListener mLockListener = new OnClickListener() {
+	boolean isLocked = false;
+
+	public void onClick(View v) {
+	    if (isLocked) {
+		unlockScreen();
+		isLocked = false;
+	    } else {
+		lockScreen();
+		isLocked = true;
+	    }
+	    showOverlay();
 	}
-	
-	/**
-	 * hide the info view
+    };
+
+    /**
+	 *
 	 */
-	private void hideInfo() {
-		hideInfo(0);
+    private OnClickListener mSizeListener = new OnClickListener() {
+
+	public void onClick(View v) {
+	    if (mCurrentSize < SURFACE_ORIGINAL) {
+		mCurrentSize++;
+	    } else {
+		mCurrentSize = 0;
+	    }
+	    changeSurfaceSize();
+	    switch (mCurrentSize) {
+	    case SURFACE_FIT_HORIZONTAL:
+		showInfo("fit horizontal", 500);
+		break;
+	    case SURFACE_FIT_VERTICAL:
+		showInfo("fit vertival", 500);
+		break;
+	    case SURFACE_FILL:
+		showInfo("fill", 500);
+		break;
+	    case SURFACE_16_9:
+		showInfo("16:9", 500);
+		break;
+	    case SURFACE_4_3:
+		showInfo("4:3", 500);
+		break;
+	    case SURFACE_ORIGINAL:
+		showInfo("original", 500);
+		break;
+	    }
+	    showOverlay();
 	}
-	
+    };
+
     /**
-     *  Handle libvlc asynchronous events 
+     * attach and disattach surface to the lib
      */
-    private Handler eventHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.getData().getInt("event")) {
-                case EventManager.MediaPlayerPlaying:
-                    Log.e(TAG, "MediaPlayerPlaying");
-                    break;
-                case EventManager.MediaPlayerPaused:
-                    Log.e(TAG, "MediaPlayerPaused");
-                    break;
-                case EventManager.MediaPlayerStopped:
-                    Log.e(TAG, "MediaPlayerStopped");
-                    break;
-                case EventManager.MediaPlayerEndReached:
-                    Log.e(TAG, "MediaPlayerEndReached");
-                    /* Exit player when reach the end */
-                    VideoPlayerActivity.this.finish();
-                    break;
-                default:
-                    Log.e(TAG, "Event not handled");
-                    break;
-            }
-            updateOverlayPausePlay();
-        }
-    };
-	
-	/**
-	 * Handle resize of the surface and the overlay
-	 */
-	private Handler mHandler = new Handler() {
-
-		@Override
-		public void handleMessage(Message msg) {
-			switch (msg.what) {
-				case FADE_OUT:
-					hideOverlay(false);
-					break;
-				case SHOW_PROGRESS:
-					int pos = setOverlayProgress();
-					if (!mDragging && mShowing && mLibVLC.isPlaying()) {
-						msg = obtainMessage(SHOW_PROGRESS);
-						sendMessageDelayed(msg, 1000 - (pos % 1000));
-					}
-					break;
-				case SURFACE_SIZE:
-					changeSurfaceSize();
-					break;
-				case FADE_OUT_INFO:
-					mInfo.startAnimation(AnimationUtils.loadAnimation(
-							VideoPlayerActivity.this, android.R.anim.fade_out));
-					mInfo.setVisibility(View.INVISIBLE);
-			}
-		}
-	};
-	
-	private void changeSurfaceSize() {
-		// get screen size
-		int dw = getWindowManager().getDefaultDisplay().getWidth();
-		int dh = getWindowManager().getDefaultDisplay().getHeight();
-				
-		// calculate aspect ratio
-		double ar = (double)mVideoWidth / (double)mVideoHeight;
-		// calculate display aspect ratio
-		double dar = (double)dw / (double)dh;
-		
-		switch (mCurrentSize) {
-		case SURFACE_FIT_HORIZONTAL:
-			dh = (int) (dw / ar);
-			break;
-		case SURFACE_FIT_VERTICAL:
-			dw = (int) (dh * ar);
-			break;
-		case SURFACE_FILL:	
-			break;
-		case SURFACE_16_9:	
-			ar = 16.0/9.0;
-			if (dar < ar)
-				dh = (int) (dw / ar);
-			else
-				dw = (int) (dh * ar);
-			break;
-		case SURFACE_4_3:			
-			ar = 4.0/3.0;
-			if (dar < ar)
-				dh = (int) (dw / ar);
-			else
-				dw = (int) (dh * ar);
-			break;
-		case SURFACE_ORIGINAL:
-			dh = mVideoHeight;
-			dw = mVideoWidth;
-			break;
-		}
-		
-		mSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
-		LayoutParams lp = mSurface.getLayoutParams();
-		lp.width = dw;
-		lp.height = dh;
-		mSurface.setLayoutParams(lp);
-		mSurface.invalidate();
+    private SurfaceHolder.Callback mSurfaceCallback = new Callback() {
+	public void surfaceChanged(SurfaceHolder holder, int format, int width,
+		int height) {
+	    mLibVLC.attachSurface(holder.getSurface(),
+		    VideoPlayerActivity.this, width, height);
 	}
-	
 
-	/**
-	 * show/hide the overlay
-	 */
-    private OnTouchListener mTouchListener = new OnTouchListener() {
-        public boolean onTouch(View v, MotionEvent event) {
-            if (event.getAction() == MotionEvent.ACTION_DOWN) {
-                if (!mShowing) {
-                    showOverlay();
-                } else {
-                	hideOverlay(true);
-                }
-            }
-            return false;
-        }
+	public void surfaceCreated(SurfaceHolder holder) {
+	}
+
+	public void surfaceDestroyed(SurfaceHolder holder) {
+	    mLibVLC.detachSurface();
+	}
     };
-    
-    
+
     /**
-     * handle changes of the seekbar (slicer)
+     * show overlay the the default timeout
      */
-    private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
-    	
-		public void onStartTrackingTouch(SeekBar seekBar) {
-			mDragging = true;
-			showOverlay(3600000);
-		}
-		
-		public void onStopTrackingTouch(SeekBar seekBar) {
-			mDragging = false;
-			showOverlay();
-			hideInfo();
-		}
-		
-		public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-			if (fromUser) {
-				mLibVLC.setTime(progress);
-				setOverlayProgress();	
-				mTime.setText(Util.millisToString(progress));
-				showInfo(Util.millisToString(progress));
-			}
-			
-		}
-	};
-	
-	
-	/**
-	 * 
-	 */
-	private OnClickListener mPauseListener = new OnClickListener() {		
-		public void onClick(View v) {
-			doPausePlay();
-			showOverlay();
-		}
-	};
-	
-	/**
-	 * 
-	 */
-	private OnClickListener mLockListener = new OnClickListener() {		
-		boolean isLocked = false;
-		public void onClick(View v) {
-			if (isLocked) {
-				unlockScreen();
-				isLocked = false;
-			} else {
-				lockScreen();
-				isLocked = true;
-			}
-			showOverlay();
-		}
-	};
-	
-	/**
-	 * 
-	 */
-	private OnClickListener mSizeListener = new OnClickListener() {
-
-		@Override
-		public void onClick(View v) {
-			if (mCurrentSize < SURFACE_ORIGINAL) {
-				mCurrentSize++;
-			} else {
-				mCurrentSize = 0;
-			}
-			changeSurfaceSize();
-			switch (mCurrentSize) {
-			case SURFACE_FIT_HORIZONTAL:
-				showInfo("fit horizontal", 500);
-				break;
-			case SURFACE_FIT_VERTICAL:
-				showInfo("fit vertival", 500);
-				break;
-			case SURFACE_FILL:	
-				showInfo("fill", 500);
-				break;
-			case SURFACE_16_9:	
-				showInfo("16:9", 500);
-				break;
-			case SURFACE_4_3:			
-				showInfo("4:3", 500);
-				break;
-			case SURFACE_ORIGINAL:
-				showInfo("original", 500);
-				break;
-			}
-			showOverlay();
-		}		
-	};
-
-
-	
-	/**
-	 * attach and disattach surface to the lib
-	 */
-	private SurfaceHolder.Callback mSurfaceCallback = new Callback() {		
-		public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-			mLibVLC.attachSurface(holder.getSurface(), VideoPlayerActivity.this, width, height);
-		}
-
-		public void surfaceCreated(SurfaceHolder holder) { }
+    private void showOverlay() {
+	showOverlay(OVERLAY_TIMEOUT);
+    }
 
-		public void surfaceDestroyed(SurfaceHolder holder) {
-			mLibVLC.detachSurface();
-		}
-	};
+    /**
+     * show overlay
+     */
+    private void showOverlay(int timeout) {
+	mHandler.sendEmptyMessage(SHOW_PROGRESS);
+	if (!mShowing) {
+	    mShowing = true;
+	    mDecor.addView(mOverlay);
+	}
+	Message msg = mHandler.obtainMessage(FADE_OUT);
+	if (timeout != 0) {
+	    mHandler.removeMessages(FADE_OUT);
+	    mHandler.sendMessageDelayed(msg, timeout);
+	}
+	updateOverlayPausePlay();
+    }
 
-	
-	/**
-	 * show overlay the the default timeout
-	 */
-	private void showOverlay() {
-		showOverlay(OVERLAY_TIMEOUT);
+    /**
+     * hider overlay
+     */
+    private void hideOverlay(boolean fromUser) {
+	mSurface.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
+	if (mShowing) {
+	    mHandler.removeMessages(SHOW_PROGRESS);
+	    Log.i(TAG, "remove View!");
+	    if (!fromUser) {
+		mOverlay.startAnimation(AnimationUtils.loadAnimation(this,
+			android.R.anim.fade_out));
+	    }
+	    mDecor.removeView(mOverlay);
+	    mShowing = false;
 	}
-	
-	
-	/**
-	 * show overlay
-	 */
-	private void showOverlay(int timeout) {
-		mHandler.sendEmptyMessage(SHOW_PROGRESS);
-		if (!mShowing) {
-			mShowing = true;
-			mDecor.addView(mOverlay);
-		}
-		Message msg = mHandler.obtainMessage(FADE_OUT);
-        if (timeout != 0) {
-            mHandler.removeMessages(FADE_OUT);
-            mHandler.sendMessageDelayed(msg, timeout);
-        }
-        updateOverlayPausePlay();
+    }
+
+    private void updateOverlayPausePlay() {
+	if (mLibVLC == null) {
+	    return;
 	}
-	
-	
-	/**
-	 * hider overlay
-	 */
-	private void hideOverlay(boolean fromUser) {
-		if (mShowing) {
-			mHandler.removeMessages(SHOW_PROGRESS);
-        	Log.i(TAG, "remove View!");
-        	if (!fromUser) {
-	        	mOverlay.startAnimation(AnimationUtils.loadAnimation(
-	        			this, android.R.anim.fade_out));
-        	}
-			mDecor.removeView(mOverlay);
-			mShowing = false;
-		}
+
+	if (mLibVLC.isPlaying()) {
+	    mPause.setBackgroundResource(R.drawable.ic_pause);
+	} else {
+	    mPause.setBackgroundResource(R.drawable.ic_play);
 	}
+    }
 
-	
-	private void updateOverlayPausePlay() {
-		if (mLibVLC == null) {
-			return;
-		}
-		
-		if (mLibVLC.isPlaying()) {
-			mPause.setBackgroundResource(R.drawable.ic_pause);
-		} else {
-			mPause.setBackgroundResource(R.drawable.ic_play);
-		}
+    /**
+     * play or pause the media
+     */
+    private void doPausePlay() {
+	if (mLibVLC.isPlaying()) {
+	    pause();
+	} else {
+	    play();
 	}
-	
-	
-	/**
-	 * play or pause the media
-	 */
-	private void doPausePlay() {
-		if (mLibVLC.isPlaying()) {
-			pause();
-		} else {
-			play();
-		}
+    }
+
+    /**
+     * update the overlay
+     */
+    private int setOverlayProgress() {
+	if (mLibVLC == null) {
+	    return 0;
 	}
-	
-	
-	/**
-	 * update the overlay
+	int time = (int) mLibVLC.getTime();
+	int length = (int) mLibVLC.getLength();
+	// Update all view elements
+
+	mSeekbar.setMax(length);
+	mSeekbar.setProgress(time);
+	mTime.setText(Util.millisToString(time));
+	mLength.setText(Util.millisToString(length));
+	return time;
+    }
+
+    /**
+	 *
 	 */
-	private int setOverlayProgress() {
-		if (mLibVLC == null) {
-			return 0;
-		}
-		int time = (int)mLibVLC.getTime();
-		int length = (int)mLibVLC.getLength();
-		// Update all view elements
-
-		mSeekbar.setMax(length);
-		mSeekbar.setProgress(time);
-		mTime.setText(Util.millisToString(time));
-		mLength.setText(Util.millisToString(length));
-		return time;
-	}
+    private void play() {
+	mLibVLC.play();
+	mWakeLock.acquire();
+    }
 
-	/**
-	 * 
+    /**
+	 *
 	 */
-	private void play() {
-		mLibVLC.play();
-		mWakeLock.acquire();
-	}
-	
-	/**
-	 * 
+    private void pause() {
+	mLibVLC.pause();
+	mWakeLock.release();
+    }
+
+    /**
+	 *
 	 */
-	private void pause() {
-		mLibVLC.pause();
-		mWakeLock.release();
+    private void load() {
+	String path = null;
+	if (getIntent().getAction() != null
+		&& getIntent().getAction().equals(Intent.ACTION_VIEW)) {
+	    /* Started from external application */
+	    path = getIntent().getData().getPath();
+	} else {
+	    /* Started from VideoListActivity */
+	    path = getIntent().getExtras().getString("filePath");
 	}
-	
-	/**
-	 * 
-	 */
-	private void load() {
-        String path = null;
-        if (getIntent().getAction() != null
-        		&& getIntent().getAction().equals(Intent.ACTION_VIEW )) {
-            /* Started from external application */
-            path = getIntent().getData().getPath();
-        } else {
-            /* Started from VideoListActivity */
-            path = getIntent().getExtras().getString("filePath");
-        }
-        if (path != null && path.length() > 0) {
-    		mLibVLC.readMedia(path);
-		    mWakeLock.acquire();
-        }
+	if (path != null && path.length() > 0) {
+	    mLibVLC.readMedia(path);
+	    mWakeLock.acquire();
 	}
+    }
 }
diff --git a/extras/package/android/vlc-android/src/org/videolan/vlc/android/widget/AudioMiniPlayer.java b/extras/package/android/vlc-android/src/org/videolan/vlc/android/widget/AudioMiniPlayer.java
index 621a28b..63dc844 100644
--- a/extras/package/android/vlc-android/src/org/videolan/vlc/android/widget/AudioMiniPlayer.java
+++ b/extras/package/android/vlc-android/src/org/videolan/vlc/android/widget/AudioMiniPlayer.java
@@ -1,10 +1,5 @@
 package org.videolan.vlc.android.widget;
 
-import org.videolan.vlc.android.AudioPlayer;
-import org.videolan.vlc.android.AudioPlayerActivity;
-import org.videolan.vlc.android.MainActivity;
-import org.videolan.vlc.android.R;
-
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
@@ -19,138 +14,149 @@ import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.SeekBar;
 import android.widget.TextView;
+import org.videolan.vlc.android.AudioPlayer;
+import org.videolan.vlc.android.AudioPlayerActivity;
+import org.videolan.vlc.android.MainActivity;
+import org.videolan.vlc.android.R;
 
 public class AudioMiniPlayer extends LinearLayout implements AudioPlayer {
-	public static final String TAG = "VLC/AudioMiniPlayer";
-
-	
-	private AudioPlayerControl mAudioPlayerControl;
-	
-	private TextView mTitle;
-	private TextView mArtist;
-	private ImageButton mPlayPause;
-	private ImageView mCover;
-	private SeekBar mSeekbar;
-	
-	// Listener for the play and pause buttons
-	private OnClickListener onPlayPauseClickListener = new OnClickListener() {		
-		@Override
-		public void onClick(View v) {
-			if (mAudioPlayerControl != null) {
-				if (mAudioPlayerControl.isPlaying()) {
-					mAudioPlayerControl.pause();
-				} else {
-					mAudioPlayerControl.play();
-				}
-			}
-			update();
-		}
-	};
+    public static final String TAG = "VLC/AudioMiniPlayer";
 
-	
-	public AudioMiniPlayer(Context context, AttributeSet attrs) {
-		super(context, attrs);
-		init();
-	}
+    private AudioPlayerControl mAudioPlayerControl;
 
-	public AudioMiniPlayer(Context context) {
-		super(context);
-		init();
-	}
-	
-	private void init() {
-		// get inflater and create the new view
-		LayoutInflater layoutInflater = 
-			(LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-		View mMiniPlayerView = layoutInflater.inflate(R.layout.audio_player_mini, this, false);
-		
-		addView(mMiniPlayerView);
-		
-		// Initialize the children
-		mCover = (ImageView) findViewById(R.id.cover);
-		mTitle = (TextView) findViewById(R.id.title);
-		mArtist = (TextView) findViewById(R.id.artist);
-		mPlayPause = (ImageButton) findViewById(R.id.play_pause);
-		mPlayPause.setOnClickListener(onPlayPauseClickListener);
-		mSeekbar = (SeekBar) findViewById(R.id.timeline);
-		
-		this.setOnClickListener(new OnClickListener() {
-			
-			@Override
-			public void onClick(View view) {
-				// Start audio player
-				
-				Intent intent = new Intent(getContext(), 
-						AudioPlayerActivity.class);
-				getContext().startActivity(intent);
-			}
-			
-		});
-		
-		this.setOnLongClickListener(new OnLongClickListener() {
-			
-			@Override
-			public boolean onLongClick(View arg0) {
-				showContextMenu();
-				return true;
-			}
-		});
-	}
-	
-	@Override
-	protected void onCreateContextMenu(ContextMenu menu) {
-		MenuInflater inflater = MainActivity.getInstance().getMenuInflater();
-		inflater.inflate(R.menu.audio_player_mini, menu);
-		MenuItem hmi = menu.findItem(R.id.hide_mini_player);
-		MenuItem pp = menu.findItem(R.id.play_pause);
-		if (mAudioPlayerControl.isPlaying()) {
-			hmi.setVisible(false);
-			pp.setTitle(R.string.pause);
-		} else {
-			pp.setTitle(R.string.play);
+    private TextView mTitle;
+    private TextView mArtist;
+    private ImageButton mPlayPause;
+    private ImageButton mForward;
+    private ImageButton mBackward;
+    private ImageView mCover;
+    private SeekBar mSeekbar;
+
+    // Listener for the play and pause buttons
+    private OnClickListener onMediaControlClickListener = new OnClickListener() {
+	public void onClick(View v) {
+	    if (mAudioPlayerControl != null) {
+		if (v == mPlayPause) {
+		    if (mAudioPlayerControl.isPlaying()) {
+			mAudioPlayerControl.pause();
+		    } else {
+			mAudioPlayerControl.play();
+		    }
+		} else if (v==mForward) {
+		    mAudioPlayerControl.next();
+		} else if (v==mBackward) {
+		    mAudioPlayerControl.previous();
 		}
-		
-		super.onCreateContextMenu(menu);
+	    }
+	    update();
 	}
-	
-	public void setAudioPlayerControl(AudioPlayerControl control) {
-		mAudioPlayerControl = control;
+    };
+
+    public AudioMiniPlayer(Context context, AttributeSet attrs) {
+	super(context, attrs);
+	init();
+    }
+
+    public AudioMiniPlayer(Context context) {
+	super(context);
+	init();
+    }
+
+    private void init() {
+	// get inflater and create the new view
+	LayoutInflater layoutInflater = (LayoutInflater) getContext()
+		.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+	View mMiniPlayerView = layoutInflater.inflate(
+		R.layout.audio_player_mini, this, false);
+
+	addView(mMiniPlayerView);
+
+	// Initialize the children
+	mCover = (ImageView) findViewById(R.id.cover);
+	mTitle = (TextView) findViewById(R.id.title);
+	mArtist = (TextView) findViewById(R.id.artist);
+	mPlayPause = (ImageButton) findViewById(R.id.play_pause);
+	mForward = (ImageButton) findViewById(R.id.forward);
+	mBackward = (ImageButton) findViewById(R.id.backward);
+	mPlayPause.setOnClickListener(onMediaControlClickListener);
+	mForward.setOnClickListener(onMediaControlClickListener);
+	mBackward.setOnClickListener(onMediaControlClickListener);
+	mSeekbar = (SeekBar) findViewById(R.id.timeline);
+
+	this.setOnClickListener(new OnClickListener() {
+
+	    public void onClick(View view) {
+		// Start audio player
+
+		Intent intent = new Intent(getContext(),
+			AudioPlayerActivity.class);
+		getContext().startActivity(intent);
+	    }
+
+	});
+
+	this.setOnLongClickListener(new OnLongClickListener() {
+
+	    public boolean onLongClick(View arg0) {
+		showContextMenu();
+		return true;
+	    }
+	});
+    }
+
+    @Override
+    protected void onCreateContextMenu(ContextMenu menu) {
+	MenuInflater inflater = MainActivity.getInstance().getMenuInflater();
+	inflater.inflate(R.menu.audio_player_mini, menu);
+	MenuItem hmi = menu.findItem(R.id.hide_mini_player);
+	MenuItem pp = menu.findItem(R.id.play_pause);
+	if (mAudioPlayerControl.isPlaying()) {
+	    hmi.setVisible(false);
+	    pp.setTitle(R.string.pause);
+	} else {
+	    pp.setTitle(R.string.play);
 	}
-	
-	public void update() {
-		if (mAudioPlayerControl != null) {
-			
-			if (mAudioPlayerControl.hasMedia()) {
-				this.setVisibility(LinearLayout.VISIBLE);
-			} else {
-				this.setVisibility(LinearLayout.GONE);
-				return;
-			}
-			
-			Bitmap cover = mAudioPlayerControl.getCover();
-			if (cover != null) {
-				mCover.setVisibility(ImageView.VISIBLE);
-				mCover.setImageBitmap(cover);
-			} else {
-				mCover.setVisibility(ImageView.GONE);
-			}
-	
-			mTitle.setText(mAudioPlayerControl.getTitle());
-			mArtist.setText(mAudioPlayerControl.getArtist());
-			if (mAudioPlayerControl.isPlaying()) {
-				mPlayPause.setImageResource(R.drawable.ic_pause);
-			} else {
-				mPlayPause.setImageResource(R.drawable.ic_play);
-			}
-			int time = (int)mAudioPlayerControl.getTime();
-			int length = (int)mAudioPlayerControl.getLength();
-			// Update all view elements
-
-			mSeekbar.setMax(length);
-			mSeekbar.setProgress(time);
-		}
-		
-		
+
+	super.onCreateContextMenu(menu);
+    }
+
+    public void setAudioPlayerControl(AudioPlayerControl control) {
+	mAudioPlayerControl = control;
+    }
+
+    public void update() {
+	if (mAudioPlayerControl != null) {
+
+	    if (mAudioPlayerControl.hasMedia()) {
+		this.setVisibility(LinearLayout.VISIBLE);
+	    } else {
+		this.setVisibility(LinearLayout.GONE);
+		return;
+	    }
+	    // TODO
+	    Bitmap cover = mAudioPlayerControl.getCover();
+	    if (cover != null) {
+		mCover.setVisibility(ImageView.VISIBLE);
+		mCover.setImageBitmap(cover);
+	    } else {
+		mCover.setVisibility(ImageView.GONE);
+	    }
+
+	    mTitle.setText(mAudioPlayerControl.getTitle());
+	    mArtist.setText(mAudioPlayerControl.getArtist());
+	    if (mAudioPlayerControl.isPlaying()) {
+		mPlayPause.setImageResource(R.drawable.ic_pause);
+	    } else {
+		mPlayPause.setImageResource(R.drawable.ic_play);
+	    }
+	    int time = mAudioPlayerControl.getTime();
+	    int length = mAudioPlayerControl.getLength();
+	    // Update all view elements
+
+	    mSeekbar.setMax(length);
+	    mSeekbar.setProgress(time);
 	}
-	
+
+    }
+
 }
-- 
1.7.4.1




More information about the vlc-devel mailing list