diff options
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | device.cpp | 4 | ||||
-rw-r--r-- | device.h | 1 | ||||
-rw-r--r-- | install.cpp | 14 | ||||
-rw-r--r-- | minui/resources.cpp | 2 | ||||
-rw-r--r-- | minzip/SysUtil.c | 67 | ||||
-rw-r--r-- | otafault/Android.mk | 9 | ||||
-rw-r--r-- | otafault/ota_io.cpp | 3 | ||||
-rw-r--r-- | recovery.cpp | 64 | ||||
-rw-r--r-- | res-hdpi/images/icon_installing.png | bin | 129975 -> 0 bytes | |||
-rw-r--r-- | res-hdpi/images/loop00.png | bin | 0 -> 9780 bytes | |||
-rw-r--r-- | res-hdpi/images/loop01.png | bin | 0 -> 9852 bytes | |||
-rw-r--r-- | res-hdpi/images/loop02.png | bin | 0 -> 10149 bytes | |||
-rw-r--r-- | res-hdpi/images/loop03.png | bin | 0 -> 10091 bytes | |||
-rw-r--r-- | res-hdpi/images/loop04.png | bin | 0 -> 9893 bytes | |||
-rw-r--r-- | res-hdpi/images/loop05.png | bin | 0 -> 10022 bytes | |||
-rw-r--r-- | res-hdpi/images/loop06.png | bin | 0 -> 10004 bytes | |||
-rw-r--r-- | res-hdpi/images/loop07.png | bin | 0 -> 10043 bytes | |||
-rw-r--r-- | res-hdpi/images/loop08.png | bin | 0 -> 10057 bytes | |||
-rw-r--r-- | res-hdpi/images/loop09.png | bin | 0 -> 9972 bytes | |||
-rw-r--r-- | res-hdpi/images/loop10.png | bin | 0 -> 10127 bytes | |||
-rw-r--r-- | res-hdpi/images/loop11.png | bin | 0 -> 10098 bytes | |||
-rw-r--r-- | res-hdpi/images/loop12.png | bin | 0 -> 9862 bytes | |||
-rw-r--r-- | res-hdpi/images/loop13.png | bin | 0 -> 9830 bytes | |||
-rw-r--r-- | res-hdpi/images/loop14.png | bin | 0 -> 9801 bytes | |||
-rw-r--r-- | res-hdpi/images/loop15.png | bin | 0 -> 9621 bytes | |||
-rw-r--r-- | res-hdpi/images/loop16.png | bin | 0 -> 9808 bytes | |||
-rw-r--r-- | res-hdpi/images/loop17.png | bin | 0 -> 9816 bytes | |||
-rw-r--r-- | res-hdpi/images/loop18.png | bin | 0 -> 9787 bytes | |||
-rw-r--r-- | res-hdpi/images/loop19.png | bin | 0 -> 9745 bytes | |||
-rw-r--r-- | res-hdpi/images/loop20.png | bin | 0 -> 9680 bytes | |||
-rw-r--r-- | res-hdpi/images/loop21.png | bin | 0 -> 9598 bytes | |||
-rw-r--r-- | res-hdpi/images/loop22.png | bin | 0 -> 9456 bytes | |||
-rw-r--r-- | res-hdpi/images/loop23.png | bin | 0 -> 9391 bytes | |||
-rw-r--r-- | res-hdpi/images/loop24.png | bin | 0 -> 9443 bytes | |||
-rw-r--r-- | res-hdpi/images/loop25.png | bin | 0 -> 9390 bytes | |||
-rw-r--r-- | res-hdpi/images/loop26.png | bin | 0 -> 9294 bytes | |||
-rw-r--r-- | res-hdpi/images/loop27.png | bin | 0 -> 9268 bytes | |||
-rw-r--r-- | res-hdpi/images/loop28.png | bin | 0 -> 9287 bytes | |||
-rw-r--r-- | res-hdpi/images/loop29.png | bin | 0 -> 9241 bytes | |||
-rw-r--r-- | res-hdpi/images/loop30.png | bin | 0 -> 9157 bytes | |||
-rw-r--r-- | res-hdpi/images/loop31.png | bin | 0 -> 9075 bytes | |||
-rw-r--r-- | res-hdpi/images/loop32.png | bin | 0 -> 8867 bytes | |||
-rw-r--r-- | res-hdpi/images/loop33.png | bin | 0 -> 8757 bytes | |||
-rw-r--r-- | res-hdpi/images/loop34.png | bin | 0 -> 8771 bytes | |||
-rw-r--r-- | res-hdpi/images/loop35.png | bin | 0 -> 9044 bytes | |||
-rw-r--r-- | res-hdpi/images/loop36.png | bin | 0 -> 8850 bytes | |||
-rw-r--r-- | res-hdpi/images/loop37.png | bin | 0 -> 8944 bytes | |||
-rw-r--r-- | res-hdpi/images/loop38.png | bin | 0 -> 8996 bytes | |||
-rw-r--r-- | res-hdpi/images/loop39.png | bin | 0 -> 9066 bytes | |||
-rw-r--r-- | res-hdpi/images/loop40.png | bin | 0 -> 9113 bytes | |||
-rw-r--r-- | res-hdpi/images/loop41.png | bin | 0 -> 9043 bytes | |||
-rw-r--r-- | res-hdpi/images/loop42.png | bin | 0 -> 9296 bytes | |||
-rw-r--r-- | res-hdpi/images/loop43.png | bin | 0 -> 9423 bytes | |||
-rw-r--r-- | res-hdpi/images/loop44.png | bin | 0 -> 9407 bytes | |||
-rw-r--r-- | res-hdpi/images/loop45.png | bin | 0 -> 9630 bytes | |||
-rw-r--r-- | res-hdpi/images/loop46.png | bin | 0 -> 9484 bytes | |||
-rw-r--r-- | res-hdpi/images/loop47.png | bin | 0 -> 9689 bytes | |||
-rw-r--r-- | res-hdpi/images/loop48.png | bin | 0 -> 9763 bytes | |||
-rw-r--r-- | res-hdpi/images/loop49.png | bin | 0 -> 9921 bytes | |||
-rw-r--r-- | res-hdpi/images/loop50.png | bin | 0 -> 10085 bytes | |||
-rw-r--r-- | res-hdpi/images/loop51.png | bin | 0 -> 9819 bytes | |||
-rw-r--r-- | res-hdpi/images/loop52.png | bin | 0 -> 9935 bytes | |||
-rw-r--r-- | res-hdpi/images/loop53.png | bin | 0 -> 9924 bytes | |||
-rw-r--r-- | res-hdpi/images/loop54.png | bin | 0 -> 10072 bytes | |||
-rw-r--r-- | res-hdpi/images/loop55.png | bin | 0 -> 9779 bytes | |||
-rw-r--r-- | res-hdpi/images/loop56.png | bin | 0 -> 10020 bytes | |||
-rw-r--r-- | res-hdpi/images/loop57.png | bin | 0 -> 9875 bytes | |||
-rw-r--r-- | res-hdpi/images/loop58.png | bin | 0 -> 9965 bytes | |||
-rw-r--r-- | res-hdpi/images/loop59.png | bin | 0 -> 9624 bytes | |||
-rw-r--r-- | res-hdpi/images/loop60.png | bin | 0 -> 9677 bytes | |||
-rw-r--r-- | res-hdpi/images/loop61.png | bin | 0 -> 9777 bytes | |||
-rw-r--r-- | res-hdpi/images/loop62.png | bin | 0 -> 9625 bytes | |||
-rw-r--r-- | res-hdpi/images/loop63.png | bin | 0 -> 9611 bytes | |||
-rw-r--r-- | res-hdpi/images/loop64.png | bin | 0 -> 9619 bytes | |||
-rw-r--r-- | res-hdpi/images/loop65.png | bin | 0 -> 9673 bytes | |||
-rw-r--r-- | res-hdpi/images/loop66.png | bin | 0 -> 9655 bytes | |||
-rw-r--r-- | res-hdpi/images/loop67.png | bin | 0 -> 9738 bytes | |||
-rw-r--r-- | res-hdpi/images/loop68.png | bin | 0 -> 9676 bytes | |||
-rw-r--r-- | res-hdpi/images/loop69.png | bin | 0 -> 9476 bytes | |||
-rw-r--r-- | res-hdpi/images/loop70.png | bin | 0 -> 9368 bytes | |||
-rw-r--r-- | res-hdpi/images/loop71.png | bin | 0 -> 9364 bytes | |||
-rw-r--r-- | res-hdpi/images/loop72.png | bin | 0 -> 9239 bytes | |||
-rw-r--r-- | res-hdpi/images/loop73.png | bin | 0 -> 9137 bytes | |||
-rw-r--r-- | res-hdpi/images/loop74.png | bin | 0 -> 9004 bytes | |||
-rw-r--r-- | res-hdpi/images/loop75.png | bin | 0 -> 9002 bytes | |||
-rw-r--r-- | res-hdpi/images/loop76.png | bin | 0 -> 8999 bytes | |||
-rw-r--r-- | res-hdpi/images/loop77.png | bin | 0 -> 8924 bytes | |||
-rw-r--r-- | res-hdpi/images/loop78.png | bin | 0 -> 8811 bytes | |||
-rw-r--r-- | res-hdpi/images/loop79.png | bin | 0 -> 8601 bytes | |||
-rw-r--r-- | res-hdpi/images/loop80.png | bin | 0 -> 8896 bytes | |||
-rw-r--r-- | res-hdpi/images/loop81.png | bin | 0 -> 9152 bytes | |||
-rw-r--r-- | res-hdpi/images/loop82.png | bin | 0 -> 9154 bytes | |||
-rw-r--r-- | res-hdpi/images/loop83.png | bin | 0 -> 9346 bytes | |||
-rw-r--r-- | res-hdpi/images/loop84.png | bin | 0 -> 9347 bytes | |||
-rw-r--r-- | res-hdpi/images/loop85.png | bin | 0 -> 9483 bytes | |||
-rw-r--r-- | res-hdpi/images/loop86.png | bin | 0 -> 9468 bytes | |||
-rw-r--r-- | res-hdpi/images/loop87.png | bin | 0 -> 9473 bytes | |||
-rw-r--r-- | res-hdpi/images/loop88.png | bin | 0 -> 9545 bytes | |||
-rw-r--r-- | res-hdpi/images/loop89.png | bin | 0 -> 9748 bytes | |||
-rw-r--r-- | res-hdpi/images/loop90.png | bin | 0 -> 9780 bytes | |||
-rw-r--r-- | res-mdpi/images/icon_installing.png | bin | 129975 -> 0 bytes | |||
-rw-r--r-- | res-mdpi/images/loop00.png | bin | 0 -> 6121 bytes | |||
-rw-r--r-- | res-mdpi/images/loop01.png | bin | 0 -> 6247 bytes | |||
-rw-r--r-- | res-mdpi/images/loop02.png | bin | 0 -> 6308 bytes | |||
-rw-r--r-- | res-mdpi/images/loop03.png | bin | 0 -> 6311 bytes | |||
-rw-r--r-- | res-mdpi/images/loop04.png | bin | 0 -> 6315 bytes | |||
-rw-r--r-- | res-mdpi/images/loop05.png | bin | 0 -> 6362 bytes | |||
-rw-r--r-- | res-mdpi/images/loop06.png | bin | 0 -> 6289 bytes | |||
-rw-r--r-- | res-mdpi/images/loop07.png | bin | 0 -> 6296 bytes | |||
-rw-r--r-- | res-mdpi/images/loop08.png | bin | 0 -> 6342 bytes | |||
-rw-r--r-- | res-mdpi/images/loop09.png | bin | 0 -> 6266 bytes | |||
-rw-r--r-- | res-mdpi/images/loop10.png | bin | 0 -> 6287 bytes | |||
-rw-r--r-- | res-mdpi/images/loop11.png | bin | 0 -> 6278 bytes | |||
-rw-r--r-- | res-mdpi/images/loop12.png | bin | 0 -> 6174 bytes | |||
-rw-r--r-- | res-mdpi/images/loop13.png | bin | 0 -> 6158 bytes | |||
-rw-r--r-- | res-mdpi/images/loop14.png | bin | 0 -> 6155 bytes | |||
-rw-r--r-- | res-mdpi/images/loop15.png | bin | 0 -> 6105 bytes | |||
-rw-r--r-- | res-mdpi/images/loop16.png | bin | 0 -> 6101 bytes | |||
-rw-r--r-- | res-mdpi/images/loop17.png | bin | 0 -> 6141 bytes | |||
-rw-r--r-- | res-mdpi/images/loop18.png | bin | 0 -> 6145 bytes | |||
-rw-r--r-- | res-mdpi/images/loop19.png | bin | 0 -> 6152 bytes | |||
-rw-r--r-- | res-mdpi/images/loop20.png | bin | 0 -> 5972 bytes | |||
-rw-r--r-- | res-mdpi/images/loop21.png | bin | 0 -> 6036 bytes | |||
-rw-r--r-- | res-mdpi/images/loop22.png | bin | 0 -> 5988 bytes | |||
-rw-r--r-- | res-mdpi/images/loop23.png | bin | 0 -> 5973 bytes | |||
-rw-r--r-- | res-mdpi/images/loop24.png | bin | 0 -> 5907 bytes | |||
-rw-r--r-- | res-mdpi/images/loop25.png | bin | 0 -> 5895 bytes | |||
-rw-r--r-- | res-mdpi/images/loop26.png | bin | 0 -> 5892 bytes | |||
-rw-r--r-- | res-mdpi/images/loop27.png | bin | 0 -> 5737 bytes | |||
-rw-r--r-- | res-mdpi/images/loop28.png | bin | 0 -> 5788 bytes | |||
-rw-r--r-- | res-mdpi/images/loop29.png | bin | 0 -> 5754 bytes | |||
-rw-r--r-- | res-mdpi/images/loop30.png | bin | 0 -> 5709 bytes | |||
-rw-r--r-- | res-mdpi/images/loop31.png | bin | 0 -> 5622 bytes | |||
-rw-r--r-- | res-mdpi/images/loop32.png | bin | 0 -> 5473 bytes | |||
-rw-r--r-- | res-mdpi/images/loop33.png | bin | 0 -> 5459 bytes | |||
-rw-r--r-- | res-mdpi/images/loop34.png | bin | 0 -> 5496 bytes | |||
-rw-r--r-- | res-mdpi/images/loop35.png | bin | 0 -> 5575 bytes | |||
-rw-r--r-- | res-mdpi/images/loop36.png | bin | 0 -> 5542 bytes | |||
-rw-r--r-- | res-mdpi/images/loop37.png | bin | 0 -> 5596 bytes | |||
-rw-r--r-- | res-mdpi/images/loop38.png | bin | 0 -> 5654 bytes | |||
-rw-r--r-- | res-mdpi/images/loop39.png | bin | 0 -> 5667 bytes | |||
-rw-r--r-- | res-mdpi/images/loop40.png | bin | 0 -> 5629 bytes | |||
-rw-r--r-- | res-mdpi/images/loop41.png | bin | 0 -> 5639 bytes | |||
-rw-r--r-- | res-mdpi/images/loop42.png | bin | 0 -> 5686 bytes | |||
-rw-r--r-- | res-mdpi/images/loop43.png | bin | 0 -> 5847 bytes | |||
-rw-r--r-- | res-mdpi/images/loop44.png | bin | 0 -> 5840 bytes | |||
-rw-r--r-- | res-mdpi/images/loop45.png | bin | 0 -> 5967 bytes | |||
-rw-r--r-- | res-mdpi/images/loop46.png | bin | 0 -> 6039 bytes | |||
-rw-r--r-- | res-mdpi/images/loop47.png | bin | 0 -> 6163 bytes | |||
-rw-r--r-- | res-mdpi/images/loop48.png | bin | 0 -> 6135 bytes | |||
-rw-r--r-- | res-mdpi/images/loop49.png | bin | 0 -> 6133 bytes | |||
-rw-r--r-- | res-mdpi/images/loop50.png | bin | 0 -> 6193 bytes | |||
-rw-r--r-- | res-mdpi/images/loop51.png | bin | 0 -> 6225 bytes | |||
-rw-r--r-- | res-mdpi/images/loop52.png | bin | 0 -> 6320 bytes | |||
-rw-r--r-- | res-mdpi/images/loop53.png | bin | 0 -> 6183 bytes | |||
-rw-r--r-- | res-mdpi/images/loop54.png | bin | 0 -> 6366 bytes | |||
-rw-r--r-- | res-mdpi/images/loop55.png | bin | 0 -> 6301 bytes | |||
-rw-r--r-- | res-mdpi/images/loop56.png | bin | 0 -> 6280 bytes | |||
-rw-r--r-- | res-mdpi/images/loop57.png | bin | 0 -> 6274 bytes | |||
-rw-r--r-- | res-mdpi/images/loop58.png | bin | 0 -> 6253 bytes | |||
-rw-r--r-- | res-mdpi/images/loop59.png | bin | 0 -> 6245 bytes | |||
-rw-r--r-- | res-mdpi/images/loop60.png | bin | 0 -> 6105 bytes | |||
-rw-r--r-- | res-mdpi/images/loop61.png | bin | 0 -> 6033 bytes | |||
-rw-r--r-- | res-mdpi/images/loop62.png | bin | 0 -> 6091 bytes | |||
-rw-r--r-- | res-mdpi/images/loop63.png | bin | 0 -> 6072 bytes | |||
-rw-r--r-- | res-mdpi/images/loop64.png | bin | 0 -> 6094 bytes | |||
-rw-r--r-- | res-mdpi/images/loop65.png | bin | 0 -> 6050 bytes | |||
-rw-r--r-- | res-mdpi/images/loop66.png | bin | 0 -> 6071 bytes | |||
-rw-r--r-- | res-mdpi/images/loop67.png | bin | 0 -> 6144 bytes | |||
-rw-r--r-- | res-mdpi/images/loop68.png | bin | 0 -> 6078 bytes | |||
-rw-r--r-- | res-mdpi/images/loop69.png | bin | 0 -> 5974 bytes | |||
-rw-r--r-- | res-mdpi/images/loop70.png | bin | 0 -> 5924 bytes | |||
-rw-r--r-- | res-mdpi/images/loop71.png | bin | 0 -> 5871 bytes | |||
-rw-r--r-- | res-mdpi/images/loop72.png | bin | 0 -> 5786 bytes | |||
-rw-r--r-- | res-mdpi/images/loop73.png | bin | 0 -> 5790 bytes | |||
-rw-r--r-- | res-mdpi/images/loop74.png | bin | 0 -> 5664 bytes | |||
-rw-r--r-- | res-mdpi/images/loop75.png | bin | 0 -> 5668 bytes | |||
-rw-r--r-- | res-mdpi/images/loop76.png | bin | 0 -> 5685 bytes | |||
-rw-r--r-- | res-mdpi/images/loop77.png | bin | 0 -> 5555 bytes | |||
-rw-r--r-- | res-mdpi/images/loop78.png | bin | 0 -> 5404 bytes | |||
-rw-r--r-- | res-mdpi/images/loop79.png | bin | 0 -> 5466 bytes | |||
-rw-r--r-- | res-mdpi/images/loop80.png | bin | 0 -> 5522 bytes | |||
-rw-r--r-- | res-mdpi/images/loop81.png | bin | 0 -> 5644 bytes | |||
-rw-r--r-- | res-mdpi/images/loop82.png | bin | 0 -> 5696 bytes | |||
-rw-r--r-- | res-mdpi/images/loop83.png | bin | 0 -> 5802 bytes | |||
-rw-r--r-- | res-mdpi/images/loop84.png | bin | 0 -> 5898 bytes | |||
-rw-r--r-- | res-mdpi/images/loop85.png | bin | 0 -> 5954 bytes | |||
-rw-r--r-- | res-mdpi/images/loop86.png | bin | 0 -> 5989 bytes | |||
-rw-r--r-- | res-mdpi/images/loop87.png | bin | 0 -> 5995 bytes | |||
-rw-r--r-- | res-mdpi/images/loop88.png | bin | 0 -> 6014 bytes | |||
-rw-r--r-- | res-mdpi/images/loop89.png | bin | 0 -> 6141 bytes | |||
-rw-r--r-- | res-mdpi/images/loop90.png | bin | 0 -> 6121 bytes | |||
-rw-r--r-- | res-xhdpi/images/icon_installing.png | bin | 129975 -> 0 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop00.png | bin | 0 -> 13451 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop01.png | bin | 0 -> 13723 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop02.png | bin | 0 -> 13702 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop03.png | bin | 0 -> 13596 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop04.png | bin | 0 -> 13690 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop05.png | bin | 0 -> 13734 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop06.png | bin | 0 -> 13793 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop07.png | bin | 0 -> 13824 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop08.png | bin | 0 -> 13783 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop09.png | bin | 0 -> 13808 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop10.png | bin | 0 -> 13824 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop11.png | bin | 0 -> 13893 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop12.png | bin | 0 -> 13784 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop13.png | bin | 0 -> 13760 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop14.png | bin | 0 -> 13528 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop15.png | bin | 0 -> 13616 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop16.png | bin | 0 -> 13424 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop17.png | bin | 0 -> 13482 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop18.png | bin | 0 -> 13557 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop19.png | bin | 0 -> 13796 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop20.png | bin | 0 -> 13606 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop21.png | bin | 0 -> 13375 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop22.png | bin | 0 -> 13126 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop23.png | bin | 0 -> 12922 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop24.png | bin | 0 -> 13283 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop25.png | bin | 0 -> 13016 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop26.png | bin | 0 -> 12745 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop27.png | bin | 0 -> 12734 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop28.png | bin | 0 -> 12687 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop29.png | bin | 0 -> 12575 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop30.png | bin | 0 -> 12520 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop31.png | bin | 0 -> 12454 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop32.png | bin | 0 -> 12465 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop33.png | bin | 0 -> 12198 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop34.png | bin | 0 -> 12242 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop35.png | bin | 0 -> 12316 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop36.png | bin | 0 -> 12201 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop37.png | bin | 0 -> 12285 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop38.png | bin | 0 -> 12635 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop39.png | bin | 0 -> 12401 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop40.png | bin | 0 -> 12393 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop41.png | bin | 0 -> 12235 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop42.png | bin | 0 -> 12653 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop43.png | bin | 0 -> 12903 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop44.png | bin | 0 -> 13038 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop45.png | bin | 0 -> 13040 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop46.png | bin | 0 -> 13372 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop47.png | bin | 0 -> 13455 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop48.png | bin | 0 -> 13486 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop49.png | bin | 0 -> 13521 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop50.png | bin | 0 -> 13751 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop51.png | bin | 0 -> 13893 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop52.png | bin | 0 -> 13746 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop53.png | bin | 0 -> 13564 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop54.png | bin | 0 -> 13733 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop55.png | bin | 0 -> 13606 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop56.png | bin | 0 -> 13820 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop57.png | bin | 0 -> 13636 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop58.png | bin | 0 -> 13291 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop59.png | bin | 0 -> 13549 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop60.png | bin | 0 -> 13550 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop61.png | bin | 0 -> 13254 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop62.png | bin | 0 -> 12982 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop63.png | bin | 0 -> 13155 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop64.png | bin | 0 -> 13082 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop65.png | bin | 0 -> 13102 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop66.png | bin | 0 -> 13337 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop67.png | bin | 0 -> 13348 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop68.png | bin | 0 -> 13471 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop69.png | bin | 0 -> 13090 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop70.png | bin | 0 -> 12968 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop71.png | bin | 0 -> 12678 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop72.png | bin | 0 -> 12713 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop73.png | bin | 0 -> 12628 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop74.png | bin | 0 -> 12132 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop75.png | bin | 0 -> 12354 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop76.png | bin | 0 -> 12202 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop77.png | bin | 0 -> 12040 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop78.png | bin | 0 -> 11738 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop79.png | bin | 0 -> 11713 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop80.png | bin | 0 -> 12276 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop81.png | bin | 0 -> 12468 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop82.png | bin | 0 -> 12673 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop83.png | bin | 0 -> 12840 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop84.png | bin | 0 -> 13030 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop85.png | bin | 0 -> 13061 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop86.png | bin | 0 -> 13097 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop87.png | bin | 0 -> 12934 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop88.png | bin | 0 -> 13105 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop89.png | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | res-xhdpi/images/loop90.png | bin | 0 -> 13451 bytes | |||
-rw-r--r-- | res-xxhdpi/images/icon_installing.png | bin | 129975 -> 0 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop00.png | bin | 0 -> 23638 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop01.png | bin | 0 -> 23493 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop02.png | bin | 0 -> 23808 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop03.png | bin | 0 -> 23933 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop04.png | bin | 0 -> 23910 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop05.png | bin | 0 -> 23990 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop06.png | bin | 0 -> 24198 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop07.png | bin | 0 -> 23903 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop08.png | bin | 0 -> 24010 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop09.png | bin | 0 -> 24124 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop10.png | bin | 0 -> 23693 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop11.png | bin | 0 -> 23728 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop12.png | bin | 0 -> 23919 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop13.png | bin | 0 -> 24382 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop14.png | bin | 0 -> 24298 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop15.png | bin | 0 -> 23795 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop16.png | bin | 0 -> 24109 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop17.png | bin | 0 -> 23980 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop18.png | bin | 0 -> 24239 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop19.png | bin | 0 -> 23837 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop20.png | bin | 0 -> 23774 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop21.png | bin | 0 -> 23391 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop22.png | bin | 0 -> 23438 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop23.png | bin | 0 -> 23307 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop24.png | bin | 0 -> 23337 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop25.png | bin | 0 -> 23209 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop26.png | bin | 0 -> 23057 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop27.png | bin | 0 -> 22542 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop28.png | bin | 0 -> 22778 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop29.png | bin | 0 -> 22426 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop30.png | bin | 0 -> 22385 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop31.png | bin | 0 -> 22575 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop32.png | bin | 0 -> 21883 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop33.png | bin | 0 -> 21762 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop34.png | bin | 0 -> 21949 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop35.png | bin | 0 -> 22072 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop36.png | bin | 0 -> 22205 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop37.png | bin | 0 -> 21656 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop38.png | bin | 0 -> 21924 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop39.png | bin | 0 -> 21510 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop40.png | bin | 0 -> 21638 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop41.png | bin | 0 -> 21665 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop42.png | bin | 0 -> 22389 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop43.png | bin | 0 -> 22746 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop44.png | bin | 0 -> 23327 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop45.png | bin | 0 -> 23478 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop46.png | bin | 0 -> 23039 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop47.png | bin | 0 -> 23458 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop48.png | bin | 0 -> 23679 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop49.png | bin | 0 -> 23746 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop50.png | bin | 0 -> 23600 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop51.png | bin | 0 -> 24194 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop52.png | bin | 0 -> 24047 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop53.png | bin | 0 -> 24299 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop54.png | bin | 0 -> 23680 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop55.png | bin | 0 -> 23938 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop56.png | bin | 0 -> 24061 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop57.png | bin | 0 -> 23765 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop58.png | bin | 0 -> 23720 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop59.png | bin | 0 -> 23824 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop60.png | bin | 0 -> 23332 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop61.png | bin | 0 -> 23394 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop62.png | bin | 0 -> 23276 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop63.png | bin | 0 -> 23305 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop64.png | bin | 0 -> 23261 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop65.png | bin | 0 -> 23787 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop66.png | bin | 0 -> 23494 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop67.png | bin | 0 -> 23586 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop68.png | bin | 0 -> 23205 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop69.png | bin | 0 -> 23026 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop70.png | bin | 0 -> 23181 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop71.png | bin | 0 -> 22764 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop72.png | bin | 0 -> 22630 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop73.png | bin | 0 -> 22413 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop74.png | bin | 0 -> 21579 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop75.png | bin | 0 -> 21859 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop76.png | bin | 0 -> 21516 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop77.png | bin | 0 -> 21765 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop78.png | bin | 0 -> 21037 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop79.png | bin | 0 -> 20907 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop80.png | bin | 0 -> 21394 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop81.png | bin | 0 -> 21953 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop82.png | bin | 0 -> 22107 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop83.png | bin | 0 -> 22241 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop84.png | bin | 0 -> 22578 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop85.png | bin | 0 -> 22786 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop86.png | bin | 0 -> 22603 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop87.png | bin | 0 -> 22606 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop88.png | bin | 0 -> 22556 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop89.png | bin | 0 -> 23292 bytes | |||
-rw-r--r-- | res-xxhdpi/images/loop90.png | bin | 0 -> 23638 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/icon_installing.png | bin | 129975 -> 0 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop00.png | bin | 0 -> 31501 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop01.png | bin | 0 -> 32188 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop02.png | bin | 0 -> 32546 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop03.png | bin | 0 -> 32508 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop04.png | bin | 0 -> 32629 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop05.png | bin | 0 -> 32264 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop06.png | bin | 0 -> 32535 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop07.png | bin | 0 -> 32800 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop08.png | bin | 0 -> 32205 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop09.png | bin | 0 -> 32647 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop10.png | bin | 0 -> 32712 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop11.png | bin | 0 -> 32394 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop12.png | bin | 0 -> 32467 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop13.png | bin | 0 -> 32875 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop14.png | bin | 0 -> 32388 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop15.png | bin | 0 -> 32665 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop16.png | bin | 0 -> 31916 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop17.png | bin | 0 -> 32438 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop18.png | bin | 0 -> 32436 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop19.png | bin | 0 -> 32530 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop20.png | bin | 0 -> 32717 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop21.png | bin | 0 -> 31470 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop22.png | bin | 0 -> 31370 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop23.png | bin | 0 -> 31347 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop24.png | bin | 0 -> 31059 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop25.png | bin | 0 -> 31303 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop26.png | bin | 0 -> 30569 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop27.png | bin | 0 -> 30581 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop28.png | bin | 0 -> 30474 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop29.png | bin | 0 -> 30263 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop30.png | bin | 0 -> 30476 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop31.png | bin | 0 -> 30112 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop32.png | bin | 0 -> 29672 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop33.png | bin | 0 -> 29043 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop34.png | bin | 0 -> 29819 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop35.png | bin | 0 -> 30118 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop36.png | bin | 0 -> 29775 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop37.png | bin | 0 -> 29117 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop38.png | bin | 0 -> 29334 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop39.png | bin | 0 -> 29777 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop40.png | bin | 0 -> 30031 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop41.png | bin | 0 -> 29390 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop42.png | bin | 0 -> 29848 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop43.png | bin | 0 -> 30311 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop44.png | bin | 0 -> 30212 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop45.png | bin | 0 -> 31215 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop46.png | bin | 0 -> 31212 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop47.png | bin | 0 -> 31200 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop48.png | bin | 0 -> 31954 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop49.png | bin | 0 -> 31710 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop50.png | bin | 0 -> 32119 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop51.png | bin | 0 -> 32437 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop52.png | bin | 0 -> 31901 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop53.png | bin | 0 -> 32594 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop54.png | bin | 0 -> 32546 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop55.png | bin | 0 -> 32493 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop56.png | bin | 0 -> 32019 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop57.png | bin | 0 -> 32139 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop58.png | bin | 0 -> 32606 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop59.png | bin | 0 -> 32161 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop60.png | bin | 0 -> 32226 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop61.png | bin | 0 -> 31872 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop62.png | bin | 0 -> 31446 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop63.png | bin | 0 -> 31538 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop64.png | bin | 0 -> 31413 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop65.png | bin | 0 -> 31759 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop66.png | bin | 0 -> 31672 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop67.png | bin | 0 -> 31589 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop68.png | bin | 0 -> 31484 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop69.png | bin | 0 -> 31048 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop70.png | bin | 0 -> 29785 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop71.png | bin | 0 -> 30076 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop72.png | bin | 0 -> 29377 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop73.png | bin | 0 -> 29483 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop74.png | bin | 0 -> 28846 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop75.png | bin | 0 -> 28959 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop76.png | bin | 0 -> 29277 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop77.png | bin | 0 -> 28840 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop78.png | bin | 0 -> 27884 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop79.png | bin | 0 -> 28244 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop80.png | bin | 0 -> 28933 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop81.png | bin | 0 -> 29532 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop82.png | bin | 0 -> 29657 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop83.png | bin | 0 -> 29877 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop84.png | bin | 0 -> 30467 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop85.png | bin | 0 -> 30356 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop86.png | bin | 0 -> 30585 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop87.png | bin | 0 -> 29962 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop88.png | bin | 0 -> 30590 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop89.png | bin | 0 -> 31570 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/loop90.png | bin | 0 -> 31501 bytes | |||
-rw-r--r-- | roots.cpp | 8 | ||||
-rw-r--r-- | roots.h | 6 | ||||
-rw-r--r-- | screen_ui.cpp | 179 | ||||
-rw-r--r-- | screen_ui.h | 49 | ||||
-rw-r--r-- | tests/Android.mk | 10 | ||||
-rw-r--r-- | tests/common/test_constants.h | 25 | ||||
-rw-r--r-- | tests/component/applypatch_test.cpp | 392 | ||||
-rw-r--r-- | tests/component/verifier_test.cpp | 7 | ||||
-rw-r--r-- | tests/testdata/new.file | bin | 0 -> 1388877 bytes | |||
-rw-r--r-- | tests/testdata/old.file | bin | 0 -> 1348051 bytes | |||
-rw-r--r-- | tests/testdata/patch.bsdiff | bin | 0 -> 57476 bytes | |||
-rw-r--r-- | tools/recovery_l10n/res/layout/main.xml | 4 | ||||
-rw-r--r-- | tools/recovery_l10n/src/com/android/recovery_l10n/Main.java | 9 | ||||
-rw-r--r-- | uncrypt/Android.mk | 12 | ||||
-rw-r--r-- | uncrypt/bootloader_message_writer.cpp | 107 | ||||
-rw-r--r-- | uncrypt/include/bootloader_message_writer.h | 35 | ||||
-rw-r--r-- | uncrypt/uncrypt.cpp | 316 | ||||
-rw-r--r-- | uncrypt/uncrypt.rc | 10 | ||||
-rw-r--r-- | verifier.cpp | 10 | ||||
-rw-r--r-- | wear_touch.cpp | 177 | ||||
-rw-r--r-- | wear_touch.h | 58 | ||||
-rw-r--r-- | wear_ui.cpp | 125 | ||||
-rw-r--r-- | wear_ui.h | 21 |
492 files changed, 1347 insertions, 378 deletions
diff --git a/Android.mk b/Android.mk index 95e806ff9..355f4d841 100644 --- a/Android.mk +++ b/Android.mk @@ -43,6 +43,7 @@ LOCAL_SRC_FILES := \ ui.cpp \ verifier.cpp \ wear_ui.cpp \ + wear_touch.cpp \ LOCAL_MODULE := recovery diff --git a/device.cpp b/device.cpp index fd1a9875b..2465b0778 100644 --- a/device.cpp +++ b/device.cpp @@ -25,6 +25,7 @@ static const char* MENU_ITEMS[] = { "Wipe cache partition", "Mount /system", "View recovery logs", + "Run graphics test", "Power off", NULL }; @@ -43,7 +44,8 @@ Device::BuiltinAction Device::InvokeMenuItem(int menu_position) { case 5: return WIPE_CACHE; case 6: return MOUNT_SYSTEM; case 7: return VIEW_RECOVERY_LOGS; - case 8: return SHUTDOWN; + case 8: return RUN_GRAPHICS_TEST; + case 9: return SHUTDOWN; default: return NO_ACTION; } } @@ -68,6 +68,7 @@ class Device { SHUTDOWN = 8, VIEW_RECOVERY_LOGS = 9, MOUNT_SYSTEM = 10, + RUN_GRAPHICS_TEST = 11, }; // Return the list of menu items (an array of strings, diff --git a/install.cpp b/install.cpp index a7b59c3e7..7113fa286 100644 --- a/install.cpp +++ b/install.cpp @@ -23,6 +23,7 @@ #include <sys/wait.h> #include <unistd.h> +#include <chrono> #include <vector> #include "common.h" @@ -228,6 +229,7 @@ really_install_package(const char *path, bool* wipe_cache, bool needs_mount) return INSTALL_CORRUPT; } + // Load keys. std::vector<Certificate> loadedKeys; if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) { LOGE("Failed to load keys\n"); @@ -235,18 +237,19 @@ really_install_package(const char *path, bool* wipe_cache, bool needs_mount) } LOGI("%zu key(s) loaded from %s\n", loadedKeys.size(), PUBLIC_KEYS_FILE); + // Verify package. ui->Print("Verifying update package...\n"); - + auto t0 = std::chrono::system_clock::now(); int err = verify_file(map.addr, map.length, loadedKeys); - LOGI("verify_file returned %d\n", err); + std::chrono::duration<double> duration = std::chrono::system_clock::now() - t0; + ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err); if (err != VERIFY_SUCCESS) { LOGE("signature verification failed\n"); sysReleaseMap(&map); return INSTALL_CORRUPT; } - /* Try to open the package. - */ + // Try to open the package. ZipArchive zip; err = mzOpenZipArchive(map.addr, map.length, &zip); if (err != 0) { @@ -255,8 +258,7 @@ really_install_package(const char *path, bool* wipe_cache, bool needs_mount) return INSTALL_CORRUPT; } - /* Verify and install the contents of the package. - */ + // Verify and install the contents of the package. ui->Print("Installing update...\n"); ui->SetEnableReboot(false); int result = try_update_binary(path, &zip, wipe_cache); diff --git a/minui/resources.cpp b/minui/resources.cpp index 8489d60ef..cf738a7fb 100644 --- a/minui/resources.cpp +++ b/minui/resources.cpp @@ -33,8 +33,6 @@ #include "minui.h" -extern char* locale; - #define SURFACE_DATA_ALIGNMENT 8 static GRSurface* malloc_surface(size_t data_size) { diff --git a/minzip/SysUtil.c b/minzip/SysUtil.c index 09ec8768f..e7dd17b51 100644 --- a/minzip/SysUtil.c +++ b/minzip/SysUtil.c @@ -39,6 +39,11 @@ static bool sysMapFD(int fd, MemMapping* pMap) { pMap->length = sb.st_size; pMap->range_count = 1; pMap->ranges = malloc(sizeof(MappedRange)); + if (pMap->ranges == NULL) { + LOGE("malloc failed: %s\n", strerror(errno)); + munmap(memPtr, sb.st_size); + return false; + } pMap->ranges[0].addr = memPtr; pMap->ranges[0].length = sb.st_size; @@ -50,7 +55,7 @@ static int sysMapBlockFile(FILE* mapf, MemMapping* pMap) char block_dev[PATH_MAX+1]; size_t size; unsigned int blksize; - unsigned int blocks; + size_t blocks; unsigned int range_count; unsigned int i; @@ -69,49 +74,80 @@ static int sysMapBlockFile(FILE* mapf, MemMapping* pMap) LOGE("failed to parse block map header\n"); return -1; } - - blocks = ((size-1) / blksize) + 1; + if (blksize != 0) { + blocks = ((size-1) / blksize) + 1; + } + if (size == 0 || blksize == 0 || blocks > SIZE_MAX / blksize || range_count == 0) { + LOGE("invalid data in block map file: size %zu, blksize %u, range_count %u\n", + size, blksize, range_count); + return -1; + } pMap->range_count = range_count; - pMap->ranges = malloc(range_count * sizeof(MappedRange)); - memset(pMap->ranges, 0, range_count * sizeof(MappedRange)); + pMap->ranges = calloc(range_count, sizeof(MappedRange)); + if (pMap->ranges == NULL) { + LOGE("calloc(%u, %zu) failed: %s\n", range_count, sizeof(MappedRange), strerror(errno)); + return -1; + } // Reserve enough contiguous address space for the whole file. unsigned char* reserve; reserve = mmap64(NULL, blocks * blksize, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); if (reserve == MAP_FAILED) { LOGE("failed to reserve address space: %s\n", strerror(errno)); + free(pMap->ranges); return -1; } - pMap->ranges[range_count-1].addr = reserve; - pMap->ranges[range_count-1].length = blocks * blksize; - int fd = open(block_dev, O_RDONLY); if (fd < 0) { LOGE("failed to open block device %s: %s\n", block_dev, strerror(errno)); + munmap(reserve, blocks * blksize); + free(pMap->ranges); return -1; } unsigned char* next = reserve; + size_t remaining_size = blocks * blksize; + bool success = true; for (i = 0; i < range_count; ++i) { - int start, end; - if (fscanf(mapf, "%d %d\n", &start, &end) != 2) { + size_t start, end; + if (fscanf(mapf, "%zu %zu\n", &start, &end) != 2) { LOGE("failed to parse range %d in block map\n", i); - return -1; + success = false; + break; + } + size_t length = (end - start) * blksize; + if (end <= start || (end - start) > SIZE_MAX / blksize || length > remaining_size) { + LOGE("unexpected range in block map: %zu %zu\n", start, end); + success = false; + break; } - void* addr = mmap64(next, (end-start)*blksize, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ((off64_t)start)*blksize); + void* addr = mmap64(next, length, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ((off64_t)start)*blksize); if (addr == MAP_FAILED) { LOGE("failed to map block %d: %s\n", i, strerror(errno)); - return -1; + success = false; + break; } pMap->ranges[i].addr = addr; - pMap->ranges[i].length = (end-start)*blksize; + pMap->ranges[i].length = length; - next += pMap->ranges[i].length; + next += length; + remaining_size -= length; + } + if (success && remaining_size != 0) { + LOGE("ranges in block map are invalid: remaining_size = %zu\n", remaining_size); + success = false; + } + if (!success) { + close(fd); + munmap(reserve, blocks * blksize); + free(pMap->ranges); + return -1; } + close(fd); pMap->addr = reserve; pMap->length = size; @@ -134,6 +170,7 @@ int sysMapFile(const char* fn, MemMapping* pMap) if (sysMapBlockFile(mapf, pMap) != 0) { LOGE("Map of '%s' failed\n", fn); + fclose(mapf); return -1; } diff --git a/otafault/Android.mk b/otafault/Android.mk index 50e385efb..d0b1174a4 100644 --- a/otafault/Android.mk +++ b/otafault/Android.mk @@ -14,8 +14,6 @@ LOCAL_PATH := $(call my-dir) -# otafault (static library) -# =============================== include $(CLEAR_VARS) otafault_static_libs := \ @@ -25,11 +23,12 @@ otafault_static_libs := \ libselinux LOCAL_SRC_FILES := config.cpp ota_io.cpp +LOCAL_MODULE_TAGS := eng LOCAL_MODULE := libotafault LOCAL_CLANG := true LOCAL_C_INCLUDES := bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) -LOCAL_STATIC_LIBRARIES := $(otafault_static_libs) +LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs) include $(BUILD_STATIC_LIBRARY) @@ -40,9 +39,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp LOCAL_MODULE_TAGS := tests LOCAL_MODULE := otafault_test -LOCAL_STATIC_LIBRARIES := \ - libotafault \ - $(otafault_static_libs) +LOCAL_STATIC_LIBRARIES := $(otafault_static_libs) LOCAL_C_INCLUDES := bootable/recovery LOCAL_FORCE_STATIC_EXECUTABLE := true diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp index dd805e56e..94be8155a 100644 --- a/otafault/ota_io.cpp +++ b/otafault/ota_io.cpp @@ -29,7 +29,6 @@ static std::map<intptr_t, const char*> filename_cache; static std::string read_fault_file_name = ""; static std::string write_fault_file_name = ""; static std::string fsync_fault_file_name = ""; -bool have_eio_error = false; static bool get_hit_file(const char* cached_path, std::string ffn) { return should_hit_cache() @@ -49,6 +48,8 @@ void ota_set_fault_files() { } } +bool have_eio_error = false; + int ota_open(const char* path, int oflags) { // Let the caller handle errors; we do not care if open succeeds or fails int fd = open(path, oflags); diff --git a/recovery.cpp b/recovery.cpp index 169413ad5..756e1c544 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -83,7 +83,10 @@ static const char *COMMAND_FILE = "/cache/recovery/command"; static const char *LOG_FILE = "/cache/recovery/log"; static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install"; static const char *LOCALE_FILE = "/cache/recovery/last_locale"; +static const char *CONVERT_FBE_DIR = "/tmp/convert_fbe"; +static const char *CONVERT_FBE_FILE = "/tmp/convert_fbe/convert_fbe"; static const char *CACHE_ROOT = "/cache"; +static const char *DATA_ROOT = "/data"; static const char *SDCARD_ROOT = "/sdcard"; static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log"; static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install"; @@ -99,7 +102,7 @@ static const int BATTERY_OK_PERCENTAGE = 20; static const int BATTERY_WITH_CHARGER_OK_PERCENTAGE = 15; RecoveryUI* ui = NULL; -char* locale = NULL; +static const char* locale = "en_US"; char* stage = NULL; char* reason = NULL; bool modified_flash = false; @@ -530,6 +533,7 @@ typedef struct _saved_log_file { static bool erase_volume(const char* volume) { bool is_cache = (strcmp(volume, CACHE_ROOT) == 0); + bool is_data = (strcmp(volume, DATA_ROOT) == 0); ui->SetBackground(RecoveryUI::ERASING); ui->SetProgressType(RecoveryUI::INDETERMINATE); @@ -584,7 +588,28 @@ static bool erase_volume(const char* volume) { ui->Print("Formatting %s...\n", volume); ensure_path_unmounted(volume); - int result = format_volume(volume); + + int result; + + if (is_data && reason && strcmp(reason, "convert_fbe") == 0) { + // Create convert_fbe breadcrumb file to signal to init + // to convert to file based encryption, not full disk encryption + if (mkdir(CONVERT_FBE_DIR, 0700) != 0) { + ui->Print("Failed to make convert_fbe dir %s\n", strerror(errno)); + return true; + } + FILE* f = fopen(CONVERT_FBE_FILE, "wb"); + if (!f) { + ui->Print("Failed to convert to file encryption %s\n", strerror(errno)); + return true; + } + fclose(f); + result = format_volume(volume, CONVERT_FBE_DIR); + remove(CONVERT_FBE_FILE); + rmdir(CONVERT_FBE_DIR); + } else { + result = format_volume(volume); + } if (is_cache) { while (head) { @@ -870,6 +895,37 @@ static void choose_recovery_file(Device* device) { } } +static void run_graphics_test(Device* device) { + // Switch to graphics screen. + ui->ShowText(false); + + ui->SetProgressType(RecoveryUI::INDETERMINATE); + ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); + sleep(1); + + ui->SetBackground(RecoveryUI::ERROR); + sleep(1); + + ui->SetBackground(RecoveryUI::NO_COMMAND); + sleep(1); + + ui->SetBackground(RecoveryUI::ERASING); + sleep(1); + + ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); + + ui->SetProgressType(RecoveryUI::DETERMINATE); + ui->ShowProgress(1.0, 10.0); + float fraction = 0.0; + for (size_t i = 0; i < 100; ++i) { + fraction += .01; + ui->SetProgress(fraction); + usleep(100000); + } + + ui->ShowText(true); +} + // How long (in seconds) we wait for the fuse-provided package file to // appear, before timing out. #define SDCARD_INSTALL_TIMEOUT 10 @@ -1028,6 +1084,10 @@ prompt_and_wait(Device* device, int status) { choose_recovery_file(device); break; + case Device::RUN_GRAPHICS_TEST: + run_graphics_test(device); + break; + case Device::MOUNT_SYSTEM: char system_root_image[PROPERTY_VALUE_MAX]; property_get("ro.build.system_root_image", system_root_image, ""); diff --git a/res-hdpi/images/icon_installing.png b/res-hdpi/images/icon_installing.png Binary files differdeleted file mode 100644 index 0fcfbc231..000000000 --- a/res-hdpi/images/icon_installing.png +++ /dev/null diff --git a/res-hdpi/images/loop00.png b/res-hdpi/images/loop00.png Binary files differnew file mode 100644 index 000000000..c7f8084b8 --- /dev/null +++ b/res-hdpi/images/loop00.png diff --git a/res-hdpi/images/loop01.png b/res-hdpi/images/loop01.png Binary files differnew file mode 100644 index 000000000..31ed66703 --- /dev/null +++ b/res-hdpi/images/loop01.png diff --git a/res-hdpi/images/loop02.png b/res-hdpi/images/loop02.png Binary files differnew file mode 100644 index 000000000..114340722 --- /dev/null +++ b/res-hdpi/images/loop02.png diff --git a/res-hdpi/images/loop03.png b/res-hdpi/images/loop03.png Binary files differnew file mode 100644 index 000000000..040eeb293 --- /dev/null +++ b/res-hdpi/images/loop03.png diff --git a/res-hdpi/images/loop04.png b/res-hdpi/images/loop04.png Binary files differnew file mode 100644 index 000000000..58e139de3 --- /dev/null +++ b/res-hdpi/images/loop04.png diff --git a/res-hdpi/images/loop05.png b/res-hdpi/images/loop05.png Binary files differnew file mode 100644 index 000000000..f0c250098 --- /dev/null +++ b/res-hdpi/images/loop05.png diff --git a/res-hdpi/images/loop06.png b/res-hdpi/images/loop06.png Binary files differnew file mode 100644 index 000000000..e8c5b218c --- /dev/null +++ b/res-hdpi/images/loop06.png diff --git a/res-hdpi/images/loop07.png b/res-hdpi/images/loop07.png Binary files differnew file mode 100644 index 000000000..ee0523fbc --- /dev/null +++ b/res-hdpi/images/loop07.png diff --git a/res-hdpi/images/loop08.png b/res-hdpi/images/loop08.png Binary files differnew file mode 100644 index 000000000..f568a1c7d --- /dev/null +++ b/res-hdpi/images/loop08.png diff --git a/res-hdpi/images/loop09.png b/res-hdpi/images/loop09.png Binary files differnew file mode 100644 index 000000000..9fed668f8 --- /dev/null +++ b/res-hdpi/images/loop09.png diff --git a/res-hdpi/images/loop10.png b/res-hdpi/images/loop10.png Binary files differnew file mode 100644 index 000000000..93edfcc30 --- /dev/null +++ b/res-hdpi/images/loop10.png diff --git a/res-hdpi/images/loop11.png b/res-hdpi/images/loop11.png Binary files differnew file mode 100644 index 000000000..827fce887 --- /dev/null +++ b/res-hdpi/images/loop11.png diff --git a/res-hdpi/images/loop12.png b/res-hdpi/images/loop12.png Binary files differnew file mode 100644 index 000000000..927f04e49 --- /dev/null +++ b/res-hdpi/images/loop12.png diff --git a/res-hdpi/images/loop13.png b/res-hdpi/images/loop13.png Binary files differnew file mode 100644 index 000000000..2856f316e --- /dev/null +++ b/res-hdpi/images/loop13.png diff --git a/res-hdpi/images/loop14.png b/res-hdpi/images/loop14.png Binary files differnew file mode 100644 index 000000000..3a2c14dc9 --- /dev/null +++ b/res-hdpi/images/loop14.png diff --git a/res-hdpi/images/loop15.png b/res-hdpi/images/loop15.png Binary files differnew file mode 100644 index 000000000..dcde38335 --- /dev/null +++ b/res-hdpi/images/loop15.png diff --git a/res-hdpi/images/loop16.png b/res-hdpi/images/loop16.png Binary files differnew file mode 100644 index 000000000..7ba01f3b4 --- /dev/null +++ b/res-hdpi/images/loop16.png diff --git a/res-hdpi/images/loop17.png b/res-hdpi/images/loop17.png Binary files differnew file mode 100644 index 000000000..82a875f58 --- /dev/null +++ b/res-hdpi/images/loop17.png diff --git a/res-hdpi/images/loop18.png b/res-hdpi/images/loop18.png Binary files differnew file mode 100644 index 000000000..00537e7fd --- /dev/null +++ b/res-hdpi/images/loop18.png diff --git a/res-hdpi/images/loop19.png b/res-hdpi/images/loop19.png Binary files differnew file mode 100644 index 000000000..add89422a --- /dev/null +++ b/res-hdpi/images/loop19.png diff --git a/res-hdpi/images/loop20.png b/res-hdpi/images/loop20.png Binary files differnew file mode 100644 index 000000000..3c6f74483 --- /dev/null +++ b/res-hdpi/images/loop20.png diff --git a/res-hdpi/images/loop21.png b/res-hdpi/images/loop21.png Binary files differnew file mode 100644 index 000000000..e1d1adb8f --- /dev/null +++ b/res-hdpi/images/loop21.png diff --git a/res-hdpi/images/loop22.png b/res-hdpi/images/loop22.png Binary files differnew file mode 100644 index 000000000..bdee1acc1 --- /dev/null +++ b/res-hdpi/images/loop22.png diff --git a/res-hdpi/images/loop23.png b/res-hdpi/images/loop23.png Binary files differnew file mode 100644 index 000000000..631c62d00 --- /dev/null +++ b/res-hdpi/images/loop23.png diff --git a/res-hdpi/images/loop24.png b/res-hdpi/images/loop24.png Binary files differnew file mode 100644 index 000000000..081ba89b6 --- /dev/null +++ b/res-hdpi/images/loop24.png diff --git a/res-hdpi/images/loop25.png b/res-hdpi/images/loop25.png Binary files differnew file mode 100644 index 000000000..7511fc0be --- /dev/null +++ b/res-hdpi/images/loop25.png diff --git a/res-hdpi/images/loop26.png b/res-hdpi/images/loop26.png Binary files differnew file mode 100644 index 000000000..d9ae7d303 --- /dev/null +++ b/res-hdpi/images/loop26.png diff --git a/res-hdpi/images/loop27.png b/res-hdpi/images/loop27.png Binary files differnew file mode 100644 index 000000000..ca1d45e21 --- /dev/null +++ b/res-hdpi/images/loop27.png diff --git a/res-hdpi/images/loop28.png b/res-hdpi/images/loop28.png Binary files differnew file mode 100644 index 000000000..404297482 --- /dev/null +++ b/res-hdpi/images/loop28.png diff --git a/res-hdpi/images/loop29.png b/res-hdpi/images/loop29.png Binary files differnew file mode 100644 index 000000000..506e9e486 --- /dev/null +++ b/res-hdpi/images/loop29.png diff --git a/res-hdpi/images/loop30.png b/res-hdpi/images/loop30.png Binary files differnew file mode 100644 index 000000000..4f985058f --- /dev/null +++ b/res-hdpi/images/loop30.png diff --git a/res-hdpi/images/loop31.png b/res-hdpi/images/loop31.png Binary files differnew file mode 100644 index 000000000..b259b47f9 --- /dev/null +++ b/res-hdpi/images/loop31.png diff --git a/res-hdpi/images/loop32.png b/res-hdpi/images/loop32.png Binary files differnew file mode 100644 index 000000000..3ddfab8ad --- /dev/null +++ b/res-hdpi/images/loop32.png diff --git a/res-hdpi/images/loop33.png b/res-hdpi/images/loop33.png Binary files differnew file mode 100644 index 000000000..b61b64b16 --- /dev/null +++ b/res-hdpi/images/loop33.png diff --git a/res-hdpi/images/loop34.png b/res-hdpi/images/loop34.png Binary files differnew file mode 100644 index 000000000..96e839216 --- /dev/null +++ b/res-hdpi/images/loop34.png diff --git a/res-hdpi/images/loop35.png b/res-hdpi/images/loop35.png Binary files differnew file mode 100644 index 000000000..a8bb7fc27 --- /dev/null +++ b/res-hdpi/images/loop35.png diff --git a/res-hdpi/images/loop36.png b/res-hdpi/images/loop36.png Binary files differnew file mode 100644 index 000000000..5171a3b0f --- /dev/null +++ b/res-hdpi/images/loop36.png diff --git a/res-hdpi/images/loop37.png b/res-hdpi/images/loop37.png Binary files differnew file mode 100644 index 000000000..b4ba0a6dc --- /dev/null +++ b/res-hdpi/images/loop37.png diff --git a/res-hdpi/images/loop38.png b/res-hdpi/images/loop38.png Binary files differnew file mode 100644 index 000000000..bd248d816 --- /dev/null +++ b/res-hdpi/images/loop38.png diff --git a/res-hdpi/images/loop39.png b/res-hdpi/images/loop39.png Binary files differnew file mode 100644 index 000000000..40e2eee0f --- /dev/null +++ b/res-hdpi/images/loop39.png diff --git a/res-hdpi/images/loop40.png b/res-hdpi/images/loop40.png Binary files differnew file mode 100644 index 000000000..4ffadc69f --- /dev/null +++ b/res-hdpi/images/loop40.png diff --git a/res-hdpi/images/loop41.png b/res-hdpi/images/loop41.png Binary files differnew file mode 100644 index 000000000..e0f107bfb --- /dev/null +++ b/res-hdpi/images/loop41.png diff --git a/res-hdpi/images/loop42.png b/res-hdpi/images/loop42.png Binary files differnew file mode 100644 index 000000000..04b618aee --- /dev/null +++ b/res-hdpi/images/loop42.png diff --git a/res-hdpi/images/loop43.png b/res-hdpi/images/loop43.png Binary files differnew file mode 100644 index 000000000..e344cb90e --- /dev/null +++ b/res-hdpi/images/loop43.png diff --git a/res-hdpi/images/loop44.png b/res-hdpi/images/loop44.png Binary files differnew file mode 100644 index 000000000..85acfa053 --- /dev/null +++ b/res-hdpi/images/loop44.png diff --git a/res-hdpi/images/loop45.png b/res-hdpi/images/loop45.png Binary files differnew file mode 100644 index 000000000..d1f90b313 --- /dev/null +++ b/res-hdpi/images/loop45.png diff --git a/res-hdpi/images/loop46.png b/res-hdpi/images/loop46.png Binary files differnew file mode 100644 index 000000000..386a682d9 --- /dev/null +++ b/res-hdpi/images/loop46.png diff --git a/res-hdpi/images/loop47.png b/res-hdpi/images/loop47.png Binary files differnew file mode 100644 index 000000000..fa87591ce --- /dev/null +++ b/res-hdpi/images/loop47.png diff --git a/res-hdpi/images/loop48.png b/res-hdpi/images/loop48.png Binary files differnew file mode 100644 index 000000000..fec1c9d6e --- /dev/null +++ b/res-hdpi/images/loop48.png diff --git a/res-hdpi/images/loop49.png b/res-hdpi/images/loop49.png Binary files differnew file mode 100644 index 000000000..fbe504d6b --- /dev/null +++ b/res-hdpi/images/loop49.png diff --git a/res-hdpi/images/loop50.png b/res-hdpi/images/loop50.png Binary files differnew file mode 100644 index 000000000..62ea7205f --- /dev/null +++ b/res-hdpi/images/loop50.png diff --git a/res-hdpi/images/loop51.png b/res-hdpi/images/loop51.png Binary files differnew file mode 100644 index 000000000..6b1b5c193 --- /dev/null +++ b/res-hdpi/images/loop51.png diff --git a/res-hdpi/images/loop52.png b/res-hdpi/images/loop52.png Binary files differnew file mode 100644 index 000000000..48c2137c9 --- /dev/null +++ b/res-hdpi/images/loop52.png diff --git a/res-hdpi/images/loop53.png b/res-hdpi/images/loop53.png Binary files differnew file mode 100644 index 000000000..680945803 --- /dev/null +++ b/res-hdpi/images/loop53.png diff --git a/res-hdpi/images/loop54.png b/res-hdpi/images/loop54.png Binary files differnew file mode 100644 index 000000000..fb94ad815 --- /dev/null +++ b/res-hdpi/images/loop54.png diff --git a/res-hdpi/images/loop55.png b/res-hdpi/images/loop55.png Binary files differnew file mode 100644 index 000000000..c7f209245 --- /dev/null +++ b/res-hdpi/images/loop55.png diff --git a/res-hdpi/images/loop56.png b/res-hdpi/images/loop56.png Binary files differnew file mode 100644 index 000000000..aa376ccd0 --- /dev/null +++ b/res-hdpi/images/loop56.png diff --git a/res-hdpi/images/loop57.png b/res-hdpi/images/loop57.png Binary files differnew file mode 100644 index 000000000..b2bf5d8ff --- /dev/null +++ b/res-hdpi/images/loop57.png diff --git a/res-hdpi/images/loop58.png b/res-hdpi/images/loop58.png Binary files differnew file mode 100644 index 000000000..acef9338d --- /dev/null +++ b/res-hdpi/images/loop58.png diff --git a/res-hdpi/images/loop59.png b/res-hdpi/images/loop59.png Binary files differnew file mode 100644 index 000000000..f0d191e68 --- /dev/null +++ b/res-hdpi/images/loop59.png diff --git a/res-hdpi/images/loop60.png b/res-hdpi/images/loop60.png Binary files differnew file mode 100644 index 000000000..d58edc606 --- /dev/null +++ b/res-hdpi/images/loop60.png diff --git a/res-hdpi/images/loop61.png b/res-hdpi/images/loop61.png Binary files differnew file mode 100644 index 000000000..d355a188d --- /dev/null +++ b/res-hdpi/images/loop61.png diff --git a/res-hdpi/images/loop62.png b/res-hdpi/images/loop62.png Binary files differnew file mode 100644 index 000000000..95fd66f1b --- /dev/null +++ b/res-hdpi/images/loop62.png diff --git a/res-hdpi/images/loop63.png b/res-hdpi/images/loop63.png Binary files differnew file mode 100644 index 000000000..619bbf4e4 --- /dev/null +++ b/res-hdpi/images/loop63.png diff --git a/res-hdpi/images/loop64.png b/res-hdpi/images/loop64.png Binary files differnew file mode 100644 index 000000000..1867c8e7d --- /dev/null +++ b/res-hdpi/images/loop64.png diff --git a/res-hdpi/images/loop65.png b/res-hdpi/images/loop65.png Binary files differnew file mode 100644 index 000000000..a0eee31b2 --- /dev/null +++ b/res-hdpi/images/loop65.png diff --git a/res-hdpi/images/loop66.png b/res-hdpi/images/loop66.png Binary files differnew file mode 100644 index 000000000..b6befd6bf --- /dev/null +++ b/res-hdpi/images/loop66.png diff --git a/res-hdpi/images/loop67.png b/res-hdpi/images/loop67.png Binary files differnew file mode 100644 index 000000000..25762944f --- /dev/null +++ b/res-hdpi/images/loop67.png diff --git a/res-hdpi/images/loop68.png b/res-hdpi/images/loop68.png Binary files differnew file mode 100644 index 000000000..0bc718f75 --- /dev/null +++ b/res-hdpi/images/loop68.png diff --git a/res-hdpi/images/loop69.png b/res-hdpi/images/loop69.png Binary files differnew file mode 100644 index 000000000..3678cea38 --- /dev/null +++ b/res-hdpi/images/loop69.png diff --git a/res-hdpi/images/loop70.png b/res-hdpi/images/loop70.png Binary files differnew file mode 100644 index 000000000..03e69c466 --- /dev/null +++ b/res-hdpi/images/loop70.png diff --git a/res-hdpi/images/loop71.png b/res-hdpi/images/loop71.png Binary files differnew file mode 100644 index 000000000..62ba17e17 --- /dev/null +++ b/res-hdpi/images/loop71.png diff --git a/res-hdpi/images/loop72.png b/res-hdpi/images/loop72.png Binary files differnew file mode 100644 index 000000000..c6e8feede --- /dev/null +++ b/res-hdpi/images/loop72.png diff --git a/res-hdpi/images/loop73.png b/res-hdpi/images/loop73.png Binary files differnew file mode 100644 index 000000000..c12fb7d34 --- /dev/null +++ b/res-hdpi/images/loop73.png diff --git a/res-hdpi/images/loop74.png b/res-hdpi/images/loop74.png Binary files differnew file mode 100644 index 000000000..30b8ff951 --- /dev/null +++ b/res-hdpi/images/loop74.png diff --git a/res-hdpi/images/loop75.png b/res-hdpi/images/loop75.png Binary files differnew file mode 100644 index 000000000..c9b494029 --- /dev/null +++ b/res-hdpi/images/loop75.png diff --git a/res-hdpi/images/loop76.png b/res-hdpi/images/loop76.png Binary files differnew file mode 100644 index 000000000..9e789a587 --- /dev/null +++ b/res-hdpi/images/loop76.png diff --git a/res-hdpi/images/loop77.png b/res-hdpi/images/loop77.png Binary files differnew file mode 100644 index 000000000..c235f53aa --- /dev/null +++ b/res-hdpi/images/loop77.png diff --git a/res-hdpi/images/loop78.png b/res-hdpi/images/loop78.png Binary files differnew file mode 100644 index 000000000..11aaf36e4 --- /dev/null +++ b/res-hdpi/images/loop78.png diff --git a/res-hdpi/images/loop79.png b/res-hdpi/images/loop79.png Binary files differnew file mode 100644 index 000000000..cce9d8ae2 --- /dev/null +++ b/res-hdpi/images/loop79.png diff --git a/res-hdpi/images/loop80.png b/res-hdpi/images/loop80.png Binary files differnew file mode 100644 index 000000000..e92ba6214 --- /dev/null +++ b/res-hdpi/images/loop80.png diff --git a/res-hdpi/images/loop81.png b/res-hdpi/images/loop81.png Binary files differnew file mode 100644 index 000000000..ae44a1cb5 --- /dev/null +++ b/res-hdpi/images/loop81.png diff --git a/res-hdpi/images/loop82.png b/res-hdpi/images/loop82.png Binary files differnew file mode 100644 index 000000000..646b5e7f2 --- /dev/null +++ b/res-hdpi/images/loop82.png diff --git a/res-hdpi/images/loop83.png b/res-hdpi/images/loop83.png Binary files differnew file mode 100644 index 000000000..37357b532 --- /dev/null +++ b/res-hdpi/images/loop83.png diff --git a/res-hdpi/images/loop84.png b/res-hdpi/images/loop84.png Binary files differnew file mode 100644 index 000000000..e52d037dc --- /dev/null +++ b/res-hdpi/images/loop84.png diff --git a/res-hdpi/images/loop85.png b/res-hdpi/images/loop85.png Binary files differnew file mode 100644 index 000000000..73ecb61cb --- /dev/null +++ b/res-hdpi/images/loop85.png diff --git a/res-hdpi/images/loop86.png b/res-hdpi/images/loop86.png Binary files differnew file mode 100644 index 000000000..9474ed5ae --- /dev/null +++ b/res-hdpi/images/loop86.png diff --git a/res-hdpi/images/loop87.png b/res-hdpi/images/loop87.png Binary files differnew file mode 100644 index 000000000..af86252b1 --- /dev/null +++ b/res-hdpi/images/loop87.png diff --git a/res-hdpi/images/loop88.png b/res-hdpi/images/loop88.png Binary files differnew file mode 100644 index 000000000..0b6955bd9 --- /dev/null +++ b/res-hdpi/images/loop88.png diff --git a/res-hdpi/images/loop89.png b/res-hdpi/images/loop89.png Binary files differnew file mode 100644 index 000000000..e52e38d85 --- /dev/null +++ b/res-hdpi/images/loop89.png diff --git a/res-hdpi/images/loop90.png b/res-hdpi/images/loop90.png Binary files differnew file mode 100644 index 000000000..c7f8084b8 --- /dev/null +++ b/res-hdpi/images/loop90.png diff --git a/res-mdpi/images/icon_installing.png b/res-mdpi/images/icon_installing.png Binary files differdeleted file mode 100644 index 0fcfbc231..000000000 --- a/res-mdpi/images/icon_installing.png +++ /dev/null diff --git a/res-mdpi/images/loop00.png b/res-mdpi/images/loop00.png Binary files differnew file mode 100644 index 000000000..20bebb0e0 --- /dev/null +++ b/res-mdpi/images/loop00.png diff --git a/res-mdpi/images/loop01.png b/res-mdpi/images/loop01.png Binary files differnew file mode 100644 index 000000000..f5eabddca --- /dev/null +++ b/res-mdpi/images/loop01.png diff --git a/res-mdpi/images/loop02.png b/res-mdpi/images/loop02.png Binary files differnew file mode 100644 index 000000000..ae93a51d3 --- /dev/null +++ b/res-mdpi/images/loop02.png diff --git a/res-mdpi/images/loop03.png b/res-mdpi/images/loop03.png Binary files differnew file mode 100644 index 000000000..bda711b08 --- /dev/null +++ b/res-mdpi/images/loop03.png diff --git a/res-mdpi/images/loop04.png b/res-mdpi/images/loop04.png Binary files differnew file mode 100644 index 000000000..8e55e969d --- /dev/null +++ b/res-mdpi/images/loop04.png diff --git a/res-mdpi/images/loop05.png b/res-mdpi/images/loop05.png Binary files differnew file mode 100644 index 000000000..69d2172d5 --- /dev/null +++ b/res-mdpi/images/loop05.png diff --git a/res-mdpi/images/loop06.png b/res-mdpi/images/loop06.png Binary files differnew file mode 100644 index 000000000..f876787bc --- /dev/null +++ b/res-mdpi/images/loop06.png diff --git a/res-mdpi/images/loop07.png b/res-mdpi/images/loop07.png Binary files differnew file mode 100644 index 000000000..ee34a8180 --- /dev/null +++ b/res-mdpi/images/loop07.png diff --git a/res-mdpi/images/loop08.png b/res-mdpi/images/loop08.png Binary files differnew file mode 100644 index 000000000..2d5c3eb3b --- /dev/null +++ b/res-mdpi/images/loop08.png diff --git a/res-mdpi/images/loop09.png b/res-mdpi/images/loop09.png Binary files differnew file mode 100644 index 000000000..c83a736bf --- /dev/null +++ b/res-mdpi/images/loop09.png diff --git a/res-mdpi/images/loop10.png b/res-mdpi/images/loop10.png Binary files differnew file mode 100644 index 000000000..6cd8d8c84 --- /dev/null +++ b/res-mdpi/images/loop10.png diff --git a/res-mdpi/images/loop11.png b/res-mdpi/images/loop11.png Binary files differnew file mode 100644 index 000000000..c33dcb2b3 --- /dev/null +++ b/res-mdpi/images/loop11.png diff --git a/res-mdpi/images/loop12.png b/res-mdpi/images/loop12.png Binary files differnew file mode 100644 index 000000000..1f2b2f4e1 --- /dev/null +++ b/res-mdpi/images/loop12.png diff --git a/res-mdpi/images/loop13.png b/res-mdpi/images/loop13.png Binary files differnew file mode 100644 index 000000000..8a15029fd --- /dev/null +++ b/res-mdpi/images/loop13.png diff --git a/res-mdpi/images/loop14.png b/res-mdpi/images/loop14.png Binary files differnew file mode 100644 index 000000000..3ab2fee9d --- /dev/null +++ b/res-mdpi/images/loop14.png diff --git a/res-mdpi/images/loop15.png b/res-mdpi/images/loop15.png Binary files differnew file mode 100644 index 000000000..6af606f80 --- /dev/null +++ b/res-mdpi/images/loop15.png diff --git a/res-mdpi/images/loop16.png b/res-mdpi/images/loop16.png Binary files differnew file mode 100644 index 000000000..5cb302e6c --- /dev/null +++ b/res-mdpi/images/loop16.png diff --git a/res-mdpi/images/loop17.png b/res-mdpi/images/loop17.png Binary files differnew file mode 100644 index 000000000..cdceb06ce --- /dev/null +++ b/res-mdpi/images/loop17.png diff --git a/res-mdpi/images/loop18.png b/res-mdpi/images/loop18.png Binary files differnew file mode 100644 index 000000000..27c37a8d5 --- /dev/null +++ b/res-mdpi/images/loop18.png diff --git a/res-mdpi/images/loop19.png b/res-mdpi/images/loop19.png Binary files differnew file mode 100644 index 000000000..92e669637 --- /dev/null +++ b/res-mdpi/images/loop19.png diff --git a/res-mdpi/images/loop20.png b/res-mdpi/images/loop20.png Binary files differnew file mode 100644 index 000000000..634a011a0 --- /dev/null +++ b/res-mdpi/images/loop20.png diff --git a/res-mdpi/images/loop21.png b/res-mdpi/images/loop21.png Binary files differnew file mode 100644 index 000000000..6dc6dcc23 --- /dev/null +++ b/res-mdpi/images/loop21.png diff --git a/res-mdpi/images/loop22.png b/res-mdpi/images/loop22.png Binary files differnew file mode 100644 index 000000000..19b10a575 --- /dev/null +++ b/res-mdpi/images/loop22.png diff --git a/res-mdpi/images/loop23.png b/res-mdpi/images/loop23.png Binary files differnew file mode 100644 index 000000000..ab68fcde6 --- /dev/null +++ b/res-mdpi/images/loop23.png diff --git a/res-mdpi/images/loop24.png b/res-mdpi/images/loop24.png Binary files differnew file mode 100644 index 000000000..74541f4d1 --- /dev/null +++ b/res-mdpi/images/loop24.png diff --git a/res-mdpi/images/loop25.png b/res-mdpi/images/loop25.png Binary files differnew file mode 100644 index 000000000..af54a7b0e --- /dev/null +++ b/res-mdpi/images/loop25.png diff --git a/res-mdpi/images/loop26.png b/res-mdpi/images/loop26.png Binary files differnew file mode 100644 index 000000000..eaa826ec5 --- /dev/null +++ b/res-mdpi/images/loop26.png diff --git a/res-mdpi/images/loop27.png b/res-mdpi/images/loop27.png Binary files differnew file mode 100644 index 000000000..d5fd4710a --- /dev/null +++ b/res-mdpi/images/loop27.png diff --git a/res-mdpi/images/loop28.png b/res-mdpi/images/loop28.png Binary files differnew file mode 100644 index 000000000..aeb932418 --- /dev/null +++ b/res-mdpi/images/loop28.png diff --git a/res-mdpi/images/loop29.png b/res-mdpi/images/loop29.png Binary files differnew file mode 100644 index 000000000..06886bce3 --- /dev/null +++ b/res-mdpi/images/loop29.png diff --git a/res-mdpi/images/loop30.png b/res-mdpi/images/loop30.png Binary files differnew file mode 100644 index 000000000..c0f15ef11 --- /dev/null +++ b/res-mdpi/images/loop30.png diff --git a/res-mdpi/images/loop31.png b/res-mdpi/images/loop31.png Binary files differnew file mode 100644 index 000000000..b166a27cb --- /dev/null +++ b/res-mdpi/images/loop31.png diff --git a/res-mdpi/images/loop32.png b/res-mdpi/images/loop32.png Binary files differnew file mode 100644 index 000000000..ab5d1165b --- /dev/null +++ b/res-mdpi/images/loop32.png diff --git a/res-mdpi/images/loop33.png b/res-mdpi/images/loop33.png Binary files differnew file mode 100644 index 000000000..df4f77fb1 --- /dev/null +++ b/res-mdpi/images/loop33.png diff --git a/res-mdpi/images/loop34.png b/res-mdpi/images/loop34.png Binary files differnew file mode 100644 index 000000000..c5663d043 --- /dev/null +++ b/res-mdpi/images/loop34.png diff --git a/res-mdpi/images/loop35.png b/res-mdpi/images/loop35.png Binary files differnew file mode 100644 index 000000000..7aed6c5b2 --- /dev/null +++ b/res-mdpi/images/loop35.png diff --git a/res-mdpi/images/loop36.png b/res-mdpi/images/loop36.png Binary files differnew file mode 100644 index 000000000..e42a59f38 --- /dev/null +++ b/res-mdpi/images/loop36.png diff --git a/res-mdpi/images/loop37.png b/res-mdpi/images/loop37.png Binary files differnew file mode 100644 index 000000000..fb21da419 --- /dev/null +++ b/res-mdpi/images/loop37.png diff --git a/res-mdpi/images/loop38.png b/res-mdpi/images/loop38.png Binary files differnew file mode 100644 index 000000000..314e3f76d --- /dev/null +++ b/res-mdpi/images/loop38.png diff --git a/res-mdpi/images/loop39.png b/res-mdpi/images/loop39.png Binary files differnew file mode 100644 index 000000000..77f4362ea --- /dev/null +++ b/res-mdpi/images/loop39.png diff --git a/res-mdpi/images/loop40.png b/res-mdpi/images/loop40.png Binary files differnew file mode 100644 index 000000000..c3bc8b1fa --- /dev/null +++ b/res-mdpi/images/loop40.png diff --git a/res-mdpi/images/loop41.png b/res-mdpi/images/loop41.png Binary files differnew file mode 100644 index 000000000..33dcfe1d9 --- /dev/null +++ b/res-mdpi/images/loop41.png diff --git a/res-mdpi/images/loop42.png b/res-mdpi/images/loop42.png Binary files differnew file mode 100644 index 000000000..7cd3c10d9 --- /dev/null +++ b/res-mdpi/images/loop42.png diff --git a/res-mdpi/images/loop43.png b/res-mdpi/images/loop43.png Binary files differnew file mode 100644 index 000000000..15b152641 --- /dev/null +++ b/res-mdpi/images/loop43.png diff --git a/res-mdpi/images/loop44.png b/res-mdpi/images/loop44.png Binary files differnew file mode 100644 index 000000000..3c3825d87 --- /dev/null +++ b/res-mdpi/images/loop44.png diff --git a/res-mdpi/images/loop45.png b/res-mdpi/images/loop45.png Binary files differnew file mode 100644 index 000000000..6d52f3c98 --- /dev/null +++ b/res-mdpi/images/loop45.png diff --git a/res-mdpi/images/loop46.png b/res-mdpi/images/loop46.png Binary files differnew file mode 100644 index 000000000..8c7fe50c9 --- /dev/null +++ b/res-mdpi/images/loop46.png diff --git a/res-mdpi/images/loop47.png b/res-mdpi/images/loop47.png Binary files differnew file mode 100644 index 000000000..8ca16a465 --- /dev/null +++ b/res-mdpi/images/loop47.png diff --git a/res-mdpi/images/loop48.png b/res-mdpi/images/loop48.png Binary files differnew file mode 100644 index 000000000..62acae0bd --- /dev/null +++ b/res-mdpi/images/loop48.png diff --git a/res-mdpi/images/loop49.png b/res-mdpi/images/loop49.png Binary files differnew file mode 100644 index 000000000..3c7a35515 --- /dev/null +++ b/res-mdpi/images/loop49.png diff --git a/res-mdpi/images/loop50.png b/res-mdpi/images/loop50.png Binary files differnew file mode 100644 index 000000000..72add044f --- /dev/null +++ b/res-mdpi/images/loop50.png diff --git a/res-mdpi/images/loop51.png b/res-mdpi/images/loop51.png Binary files differnew file mode 100644 index 000000000..74108f1c5 --- /dev/null +++ b/res-mdpi/images/loop51.png diff --git a/res-mdpi/images/loop52.png b/res-mdpi/images/loop52.png Binary files differnew file mode 100644 index 000000000..bd129688f --- /dev/null +++ b/res-mdpi/images/loop52.png diff --git a/res-mdpi/images/loop53.png b/res-mdpi/images/loop53.png Binary files differnew file mode 100644 index 000000000..6af0c178c --- /dev/null +++ b/res-mdpi/images/loop53.png diff --git a/res-mdpi/images/loop54.png b/res-mdpi/images/loop54.png Binary files differnew file mode 100644 index 000000000..23f776c8c --- /dev/null +++ b/res-mdpi/images/loop54.png diff --git a/res-mdpi/images/loop55.png b/res-mdpi/images/loop55.png Binary files differnew file mode 100644 index 000000000..d2d03c810 --- /dev/null +++ b/res-mdpi/images/loop55.png diff --git a/res-mdpi/images/loop56.png b/res-mdpi/images/loop56.png Binary files differnew file mode 100644 index 000000000..13e73ed11 --- /dev/null +++ b/res-mdpi/images/loop56.png diff --git a/res-mdpi/images/loop57.png b/res-mdpi/images/loop57.png Binary files differnew file mode 100644 index 000000000..c2b81b6a5 --- /dev/null +++ b/res-mdpi/images/loop57.png diff --git a/res-mdpi/images/loop58.png b/res-mdpi/images/loop58.png Binary files differnew file mode 100644 index 000000000..d99cd74e5 --- /dev/null +++ b/res-mdpi/images/loop58.png diff --git a/res-mdpi/images/loop59.png b/res-mdpi/images/loop59.png Binary files differnew file mode 100644 index 000000000..8a36210dc --- /dev/null +++ b/res-mdpi/images/loop59.png diff --git a/res-mdpi/images/loop60.png b/res-mdpi/images/loop60.png Binary files differnew file mode 100644 index 000000000..dc957fba9 --- /dev/null +++ b/res-mdpi/images/loop60.png diff --git a/res-mdpi/images/loop61.png b/res-mdpi/images/loop61.png Binary files differnew file mode 100644 index 000000000..ea29c2977 --- /dev/null +++ b/res-mdpi/images/loop61.png diff --git a/res-mdpi/images/loop62.png b/res-mdpi/images/loop62.png Binary files differnew file mode 100644 index 000000000..608a868b2 --- /dev/null +++ b/res-mdpi/images/loop62.png diff --git a/res-mdpi/images/loop63.png b/res-mdpi/images/loop63.png Binary files differnew file mode 100644 index 000000000..f65a3b707 --- /dev/null +++ b/res-mdpi/images/loop63.png diff --git a/res-mdpi/images/loop64.png b/res-mdpi/images/loop64.png Binary files differnew file mode 100644 index 000000000..5b27105fd --- /dev/null +++ b/res-mdpi/images/loop64.png diff --git a/res-mdpi/images/loop65.png b/res-mdpi/images/loop65.png Binary files differnew file mode 100644 index 000000000..4ec41bf90 --- /dev/null +++ b/res-mdpi/images/loop65.png diff --git a/res-mdpi/images/loop66.png b/res-mdpi/images/loop66.png Binary files differnew file mode 100644 index 000000000..b0845b589 --- /dev/null +++ b/res-mdpi/images/loop66.png diff --git a/res-mdpi/images/loop67.png b/res-mdpi/images/loop67.png Binary files differnew file mode 100644 index 000000000..30fae6e1a --- /dev/null +++ b/res-mdpi/images/loop67.png diff --git a/res-mdpi/images/loop68.png b/res-mdpi/images/loop68.png Binary files differnew file mode 100644 index 000000000..fc90fca5c --- /dev/null +++ b/res-mdpi/images/loop68.png diff --git a/res-mdpi/images/loop69.png b/res-mdpi/images/loop69.png Binary files differnew file mode 100644 index 000000000..da3564310 --- /dev/null +++ b/res-mdpi/images/loop69.png diff --git a/res-mdpi/images/loop70.png b/res-mdpi/images/loop70.png Binary files differnew file mode 100644 index 000000000..baf515390 --- /dev/null +++ b/res-mdpi/images/loop70.png diff --git a/res-mdpi/images/loop71.png b/res-mdpi/images/loop71.png Binary files differnew file mode 100644 index 000000000..3b013c7d4 --- /dev/null +++ b/res-mdpi/images/loop71.png diff --git a/res-mdpi/images/loop72.png b/res-mdpi/images/loop72.png Binary files differnew file mode 100644 index 000000000..7f5599291 --- /dev/null +++ b/res-mdpi/images/loop72.png diff --git a/res-mdpi/images/loop73.png b/res-mdpi/images/loop73.png Binary files differnew file mode 100644 index 000000000..85a419483 --- /dev/null +++ b/res-mdpi/images/loop73.png diff --git a/res-mdpi/images/loop74.png b/res-mdpi/images/loop74.png Binary files differnew file mode 100644 index 000000000..740f37e22 --- /dev/null +++ b/res-mdpi/images/loop74.png diff --git a/res-mdpi/images/loop75.png b/res-mdpi/images/loop75.png Binary files differnew file mode 100644 index 000000000..cfb3d6f1f --- /dev/null +++ b/res-mdpi/images/loop75.png diff --git a/res-mdpi/images/loop76.png b/res-mdpi/images/loop76.png Binary files differnew file mode 100644 index 000000000..15c841dc7 --- /dev/null +++ b/res-mdpi/images/loop76.png diff --git a/res-mdpi/images/loop77.png b/res-mdpi/images/loop77.png Binary files differnew file mode 100644 index 000000000..b27772551 --- /dev/null +++ b/res-mdpi/images/loop77.png diff --git a/res-mdpi/images/loop78.png b/res-mdpi/images/loop78.png Binary files differnew file mode 100644 index 000000000..2744a9ac7 --- /dev/null +++ b/res-mdpi/images/loop78.png diff --git a/res-mdpi/images/loop79.png b/res-mdpi/images/loop79.png Binary files differnew file mode 100644 index 000000000..40f4908d3 --- /dev/null +++ b/res-mdpi/images/loop79.png diff --git a/res-mdpi/images/loop80.png b/res-mdpi/images/loop80.png Binary files differnew file mode 100644 index 000000000..cd969ec3a --- /dev/null +++ b/res-mdpi/images/loop80.png diff --git a/res-mdpi/images/loop81.png b/res-mdpi/images/loop81.png Binary files differnew file mode 100644 index 000000000..e388ac017 --- /dev/null +++ b/res-mdpi/images/loop81.png diff --git a/res-mdpi/images/loop82.png b/res-mdpi/images/loop82.png Binary files differnew file mode 100644 index 000000000..134bebba2 --- /dev/null +++ b/res-mdpi/images/loop82.png diff --git a/res-mdpi/images/loop83.png b/res-mdpi/images/loop83.png Binary files differnew file mode 100644 index 000000000..bdc71dd24 --- /dev/null +++ b/res-mdpi/images/loop83.png diff --git a/res-mdpi/images/loop84.png b/res-mdpi/images/loop84.png Binary files differnew file mode 100644 index 000000000..e630af397 --- /dev/null +++ b/res-mdpi/images/loop84.png diff --git a/res-mdpi/images/loop85.png b/res-mdpi/images/loop85.png Binary files differnew file mode 100644 index 000000000..a936c986c --- /dev/null +++ b/res-mdpi/images/loop85.png diff --git a/res-mdpi/images/loop86.png b/res-mdpi/images/loop86.png Binary files differnew file mode 100644 index 000000000..53b3e5168 --- /dev/null +++ b/res-mdpi/images/loop86.png diff --git a/res-mdpi/images/loop87.png b/res-mdpi/images/loop87.png Binary files differnew file mode 100644 index 000000000..982619394 --- /dev/null +++ b/res-mdpi/images/loop87.png diff --git a/res-mdpi/images/loop88.png b/res-mdpi/images/loop88.png Binary files differnew file mode 100644 index 000000000..00f682bd1 --- /dev/null +++ b/res-mdpi/images/loop88.png diff --git a/res-mdpi/images/loop89.png b/res-mdpi/images/loop89.png Binary files differnew file mode 100644 index 000000000..293b507c2 --- /dev/null +++ b/res-mdpi/images/loop89.png diff --git a/res-mdpi/images/loop90.png b/res-mdpi/images/loop90.png Binary files differnew file mode 100644 index 000000000..20bebb0e0 --- /dev/null +++ b/res-mdpi/images/loop90.png diff --git a/res-xhdpi/images/icon_installing.png b/res-xhdpi/images/icon_installing.png Binary files differdeleted file mode 100644 index 0fcfbc231..000000000 --- a/res-xhdpi/images/icon_installing.png +++ /dev/null diff --git a/res-xhdpi/images/loop00.png b/res-xhdpi/images/loop00.png Binary files differnew file mode 100644 index 000000000..45393eac2 --- /dev/null +++ b/res-xhdpi/images/loop00.png diff --git a/res-xhdpi/images/loop01.png b/res-xhdpi/images/loop01.png Binary files differnew file mode 100644 index 000000000..d410fc0ed --- /dev/null +++ b/res-xhdpi/images/loop01.png diff --git a/res-xhdpi/images/loop02.png b/res-xhdpi/images/loop02.png Binary files differnew file mode 100644 index 000000000..49c98a34e --- /dev/null +++ b/res-xhdpi/images/loop02.png diff --git a/res-xhdpi/images/loop03.png b/res-xhdpi/images/loop03.png Binary files differnew file mode 100644 index 000000000..b9ce0f584 --- /dev/null +++ b/res-xhdpi/images/loop03.png diff --git a/res-xhdpi/images/loop04.png b/res-xhdpi/images/loop04.png Binary files differnew file mode 100644 index 000000000..8391f60c1 --- /dev/null +++ b/res-xhdpi/images/loop04.png diff --git a/res-xhdpi/images/loop05.png b/res-xhdpi/images/loop05.png Binary files differnew file mode 100644 index 000000000..f76ad1b08 --- /dev/null +++ b/res-xhdpi/images/loop05.png diff --git a/res-xhdpi/images/loop06.png b/res-xhdpi/images/loop06.png Binary files differnew file mode 100644 index 000000000..a53c56749 --- /dev/null +++ b/res-xhdpi/images/loop06.png diff --git a/res-xhdpi/images/loop07.png b/res-xhdpi/images/loop07.png Binary files differnew file mode 100644 index 000000000..40b48dbdd --- /dev/null +++ b/res-xhdpi/images/loop07.png diff --git a/res-xhdpi/images/loop08.png b/res-xhdpi/images/loop08.png Binary files differnew file mode 100644 index 000000000..ea33f0c77 --- /dev/null +++ b/res-xhdpi/images/loop08.png diff --git a/res-xhdpi/images/loop09.png b/res-xhdpi/images/loop09.png Binary files differnew file mode 100644 index 000000000..1c93a9c73 --- /dev/null +++ b/res-xhdpi/images/loop09.png diff --git a/res-xhdpi/images/loop10.png b/res-xhdpi/images/loop10.png Binary files differnew file mode 100644 index 000000000..88309a498 --- /dev/null +++ b/res-xhdpi/images/loop10.png diff --git a/res-xhdpi/images/loop11.png b/res-xhdpi/images/loop11.png Binary files differnew file mode 100644 index 000000000..ae34ccfe7 --- /dev/null +++ b/res-xhdpi/images/loop11.png diff --git a/res-xhdpi/images/loop12.png b/res-xhdpi/images/loop12.png Binary files differnew file mode 100644 index 000000000..ee07cbc6b --- /dev/null +++ b/res-xhdpi/images/loop12.png diff --git a/res-xhdpi/images/loop13.png b/res-xhdpi/images/loop13.png Binary files differnew file mode 100644 index 000000000..c1b7a7829 --- /dev/null +++ b/res-xhdpi/images/loop13.png diff --git a/res-xhdpi/images/loop14.png b/res-xhdpi/images/loop14.png Binary files differnew file mode 100644 index 000000000..26ced74af --- /dev/null +++ b/res-xhdpi/images/loop14.png diff --git a/res-xhdpi/images/loop15.png b/res-xhdpi/images/loop15.png Binary files differnew file mode 100644 index 000000000..3cd3f3c7f --- /dev/null +++ b/res-xhdpi/images/loop15.png diff --git a/res-xhdpi/images/loop16.png b/res-xhdpi/images/loop16.png Binary files differnew file mode 100644 index 000000000..67f6dd3d8 --- /dev/null +++ b/res-xhdpi/images/loop16.png diff --git a/res-xhdpi/images/loop17.png b/res-xhdpi/images/loop17.png Binary files differnew file mode 100644 index 000000000..c2ddbd0b7 --- /dev/null +++ b/res-xhdpi/images/loop17.png diff --git a/res-xhdpi/images/loop18.png b/res-xhdpi/images/loop18.png Binary files differnew file mode 100644 index 000000000..14590aaf9 --- /dev/null +++ b/res-xhdpi/images/loop18.png diff --git a/res-xhdpi/images/loop19.png b/res-xhdpi/images/loop19.png Binary files differnew file mode 100644 index 000000000..0c6c828c7 --- /dev/null +++ b/res-xhdpi/images/loop19.png diff --git a/res-xhdpi/images/loop20.png b/res-xhdpi/images/loop20.png Binary files differnew file mode 100644 index 000000000..ab0572c6d --- /dev/null +++ b/res-xhdpi/images/loop20.png diff --git a/res-xhdpi/images/loop21.png b/res-xhdpi/images/loop21.png Binary files differnew file mode 100644 index 000000000..1ed54e5df --- /dev/null +++ b/res-xhdpi/images/loop21.png diff --git a/res-xhdpi/images/loop22.png b/res-xhdpi/images/loop22.png Binary files differnew file mode 100644 index 000000000..9e894c753 --- /dev/null +++ b/res-xhdpi/images/loop22.png diff --git a/res-xhdpi/images/loop23.png b/res-xhdpi/images/loop23.png Binary files differnew file mode 100644 index 000000000..87c44c559 --- /dev/null +++ b/res-xhdpi/images/loop23.png diff --git a/res-xhdpi/images/loop24.png b/res-xhdpi/images/loop24.png Binary files differnew file mode 100644 index 000000000..9dcebd94e --- /dev/null +++ b/res-xhdpi/images/loop24.png diff --git a/res-xhdpi/images/loop25.png b/res-xhdpi/images/loop25.png Binary files differnew file mode 100644 index 000000000..600c1e90a --- /dev/null +++ b/res-xhdpi/images/loop25.png diff --git a/res-xhdpi/images/loop26.png b/res-xhdpi/images/loop26.png Binary files differnew file mode 100644 index 000000000..575e808cd --- /dev/null +++ b/res-xhdpi/images/loop26.png diff --git a/res-xhdpi/images/loop27.png b/res-xhdpi/images/loop27.png Binary files differnew file mode 100644 index 000000000..3c7908dc1 --- /dev/null +++ b/res-xhdpi/images/loop27.png diff --git a/res-xhdpi/images/loop28.png b/res-xhdpi/images/loop28.png Binary files differnew file mode 100644 index 000000000..31bc00823 --- /dev/null +++ b/res-xhdpi/images/loop28.png diff --git a/res-xhdpi/images/loop29.png b/res-xhdpi/images/loop29.png Binary files differnew file mode 100644 index 000000000..7797b39a4 --- /dev/null +++ b/res-xhdpi/images/loop29.png diff --git a/res-xhdpi/images/loop30.png b/res-xhdpi/images/loop30.png Binary files differnew file mode 100644 index 000000000..234970cb4 --- /dev/null +++ b/res-xhdpi/images/loop30.png diff --git a/res-xhdpi/images/loop31.png b/res-xhdpi/images/loop31.png Binary files differnew file mode 100644 index 000000000..cd87e1b3c --- /dev/null +++ b/res-xhdpi/images/loop31.png diff --git a/res-xhdpi/images/loop32.png b/res-xhdpi/images/loop32.png Binary files differnew file mode 100644 index 000000000..263dd0d98 --- /dev/null +++ b/res-xhdpi/images/loop32.png diff --git a/res-xhdpi/images/loop33.png b/res-xhdpi/images/loop33.png Binary files differnew file mode 100644 index 000000000..62cbd5ceb --- /dev/null +++ b/res-xhdpi/images/loop33.png diff --git a/res-xhdpi/images/loop34.png b/res-xhdpi/images/loop34.png Binary files differnew file mode 100644 index 000000000..7ab585623 --- /dev/null +++ b/res-xhdpi/images/loop34.png diff --git a/res-xhdpi/images/loop35.png b/res-xhdpi/images/loop35.png Binary files differnew file mode 100644 index 000000000..2b124e936 --- /dev/null +++ b/res-xhdpi/images/loop35.png diff --git a/res-xhdpi/images/loop36.png b/res-xhdpi/images/loop36.png Binary files differnew file mode 100644 index 000000000..b5b74be51 --- /dev/null +++ b/res-xhdpi/images/loop36.png diff --git a/res-xhdpi/images/loop37.png b/res-xhdpi/images/loop37.png Binary files differnew file mode 100644 index 000000000..cad4c4278 --- /dev/null +++ b/res-xhdpi/images/loop37.png diff --git a/res-xhdpi/images/loop38.png b/res-xhdpi/images/loop38.png Binary files differnew file mode 100644 index 000000000..4a83e1806 --- /dev/null +++ b/res-xhdpi/images/loop38.png diff --git a/res-xhdpi/images/loop39.png b/res-xhdpi/images/loop39.png Binary files differnew file mode 100644 index 000000000..454a03eb7 --- /dev/null +++ b/res-xhdpi/images/loop39.png diff --git a/res-xhdpi/images/loop40.png b/res-xhdpi/images/loop40.png Binary files differnew file mode 100644 index 000000000..093f44bff --- /dev/null +++ b/res-xhdpi/images/loop40.png diff --git a/res-xhdpi/images/loop41.png b/res-xhdpi/images/loop41.png Binary files differnew file mode 100644 index 000000000..c1730327e --- /dev/null +++ b/res-xhdpi/images/loop41.png diff --git a/res-xhdpi/images/loop42.png b/res-xhdpi/images/loop42.png Binary files differnew file mode 100644 index 000000000..4b4072aa2 --- /dev/null +++ b/res-xhdpi/images/loop42.png diff --git a/res-xhdpi/images/loop43.png b/res-xhdpi/images/loop43.png Binary files differnew file mode 100644 index 000000000..33a03d28d --- /dev/null +++ b/res-xhdpi/images/loop43.png diff --git a/res-xhdpi/images/loop44.png b/res-xhdpi/images/loop44.png Binary files differnew file mode 100644 index 000000000..1965294b3 --- /dev/null +++ b/res-xhdpi/images/loop44.png diff --git a/res-xhdpi/images/loop45.png b/res-xhdpi/images/loop45.png Binary files differnew file mode 100644 index 000000000..0bf16daa5 --- /dev/null +++ b/res-xhdpi/images/loop45.png diff --git a/res-xhdpi/images/loop46.png b/res-xhdpi/images/loop46.png Binary files differnew file mode 100644 index 000000000..81255bc90 --- /dev/null +++ b/res-xhdpi/images/loop46.png diff --git a/res-xhdpi/images/loop47.png b/res-xhdpi/images/loop47.png Binary files differnew file mode 100644 index 000000000..e1e171053 --- /dev/null +++ b/res-xhdpi/images/loop47.png diff --git a/res-xhdpi/images/loop48.png b/res-xhdpi/images/loop48.png Binary files differnew file mode 100644 index 000000000..9d515ca7d --- /dev/null +++ b/res-xhdpi/images/loop48.png diff --git a/res-xhdpi/images/loop49.png b/res-xhdpi/images/loop49.png Binary files differnew file mode 100644 index 000000000..6cb515c72 --- /dev/null +++ b/res-xhdpi/images/loop49.png diff --git a/res-xhdpi/images/loop50.png b/res-xhdpi/images/loop50.png Binary files differnew file mode 100644 index 000000000..310ba7200 --- /dev/null +++ b/res-xhdpi/images/loop50.png diff --git a/res-xhdpi/images/loop51.png b/res-xhdpi/images/loop51.png Binary files differnew file mode 100644 index 000000000..283f7eb37 --- /dev/null +++ b/res-xhdpi/images/loop51.png diff --git a/res-xhdpi/images/loop52.png b/res-xhdpi/images/loop52.png Binary files differnew file mode 100644 index 000000000..141004fa1 --- /dev/null +++ b/res-xhdpi/images/loop52.png diff --git a/res-xhdpi/images/loop53.png b/res-xhdpi/images/loop53.png Binary files differnew file mode 100644 index 000000000..1b4649cd3 --- /dev/null +++ b/res-xhdpi/images/loop53.png diff --git a/res-xhdpi/images/loop54.png b/res-xhdpi/images/loop54.png Binary files differnew file mode 100644 index 000000000..3210b4a79 --- /dev/null +++ b/res-xhdpi/images/loop54.png diff --git a/res-xhdpi/images/loop55.png b/res-xhdpi/images/loop55.png Binary files differnew file mode 100644 index 000000000..b1d9ea0b9 --- /dev/null +++ b/res-xhdpi/images/loop55.png diff --git a/res-xhdpi/images/loop56.png b/res-xhdpi/images/loop56.png Binary files differnew file mode 100644 index 000000000..1ae612667 --- /dev/null +++ b/res-xhdpi/images/loop56.png diff --git a/res-xhdpi/images/loop57.png b/res-xhdpi/images/loop57.png Binary files differnew file mode 100644 index 000000000..6317e8812 --- /dev/null +++ b/res-xhdpi/images/loop57.png diff --git a/res-xhdpi/images/loop58.png b/res-xhdpi/images/loop58.png Binary files differnew file mode 100644 index 000000000..b275a31d5 --- /dev/null +++ b/res-xhdpi/images/loop58.png diff --git a/res-xhdpi/images/loop59.png b/res-xhdpi/images/loop59.png Binary files differnew file mode 100644 index 000000000..9bc3ba05e --- /dev/null +++ b/res-xhdpi/images/loop59.png diff --git a/res-xhdpi/images/loop60.png b/res-xhdpi/images/loop60.png Binary files differnew file mode 100644 index 000000000..b6a9e64ec --- /dev/null +++ b/res-xhdpi/images/loop60.png diff --git a/res-xhdpi/images/loop61.png b/res-xhdpi/images/loop61.png Binary files differnew file mode 100644 index 000000000..fee9beeba --- /dev/null +++ b/res-xhdpi/images/loop61.png diff --git a/res-xhdpi/images/loop62.png b/res-xhdpi/images/loop62.png Binary files differnew file mode 100644 index 000000000..e153319ae --- /dev/null +++ b/res-xhdpi/images/loop62.png diff --git a/res-xhdpi/images/loop63.png b/res-xhdpi/images/loop63.png Binary files differnew file mode 100644 index 000000000..a2d9efd44 --- /dev/null +++ b/res-xhdpi/images/loop63.png diff --git a/res-xhdpi/images/loop64.png b/res-xhdpi/images/loop64.png Binary files differnew file mode 100644 index 000000000..6cfdc5a8e --- /dev/null +++ b/res-xhdpi/images/loop64.png diff --git a/res-xhdpi/images/loop65.png b/res-xhdpi/images/loop65.png Binary files differnew file mode 100644 index 000000000..2806b1cfe --- /dev/null +++ b/res-xhdpi/images/loop65.png diff --git a/res-xhdpi/images/loop66.png b/res-xhdpi/images/loop66.png Binary files differnew file mode 100644 index 000000000..fc51ee94f --- /dev/null +++ b/res-xhdpi/images/loop66.png diff --git a/res-xhdpi/images/loop67.png b/res-xhdpi/images/loop67.png Binary files differnew file mode 100644 index 000000000..d85ebf3fc --- /dev/null +++ b/res-xhdpi/images/loop67.png diff --git a/res-xhdpi/images/loop68.png b/res-xhdpi/images/loop68.png Binary files differnew file mode 100644 index 000000000..8f5437abf --- /dev/null +++ b/res-xhdpi/images/loop68.png diff --git a/res-xhdpi/images/loop69.png b/res-xhdpi/images/loop69.png Binary files differnew file mode 100644 index 000000000..b426c539f --- /dev/null +++ b/res-xhdpi/images/loop69.png diff --git a/res-xhdpi/images/loop70.png b/res-xhdpi/images/loop70.png Binary files differnew file mode 100644 index 000000000..854189004 --- /dev/null +++ b/res-xhdpi/images/loop70.png diff --git a/res-xhdpi/images/loop71.png b/res-xhdpi/images/loop71.png Binary files differnew file mode 100644 index 000000000..2aa0fbf29 --- /dev/null +++ b/res-xhdpi/images/loop71.png diff --git a/res-xhdpi/images/loop72.png b/res-xhdpi/images/loop72.png Binary files differnew file mode 100644 index 000000000..dfe61c971 --- /dev/null +++ b/res-xhdpi/images/loop72.png diff --git a/res-xhdpi/images/loop73.png b/res-xhdpi/images/loop73.png Binary files differnew file mode 100644 index 000000000..4b235b541 --- /dev/null +++ b/res-xhdpi/images/loop73.png diff --git a/res-xhdpi/images/loop74.png b/res-xhdpi/images/loop74.png Binary files differnew file mode 100644 index 000000000..31e4c0e98 --- /dev/null +++ b/res-xhdpi/images/loop74.png diff --git a/res-xhdpi/images/loop75.png b/res-xhdpi/images/loop75.png Binary files differnew file mode 100644 index 000000000..68197f564 --- /dev/null +++ b/res-xhdpi/images/loop75.png diff --git a/res-xhdpi/images/loop76.png b/res-xhdpi/images/loop76.png Binary files differnew file mode 100644 index 000000000..cff8f4ab0 --- /dev/null +++ b/res-xhdpi/images/loop76.png diff --git a/res-xhdpi/images/loop77.png b/res-xhdpi/images/loop77.png Binary files differnew file mode 100644 index 000000000..3b38a39d6 --- /dev/null +++ b/res-xhdpi/images/loop77.png diff --git a/res-xhdpi/images/loop78.png b/res-xhdpi/images/loop78.png Binary files differnew file mode 100644 index 000000000..8d3562496 --- /dev/null +++ b/res-xhdpi/images/loop78.png diff --git a/res-xhdpi/images/loop79.png b/res-xhdpi/images/loop79.png Binary files differnew file mode 100644 index 000000000..e8cdbe021 --- /dev/null +++ b/res-xhdpi/images/loop79.png diff --git a/res-xhdpi/images/loop80.png b/res-xhdpi/images/loop80.png Binary files differnew file mode 100644 index 000000000..5b26b4892 --- /dev/null +++ b/res-xhdpi/images/loop80.png diff --git a/res-xhdpi/images/loop81.png b/res-xhdpi/images/loop81.png Binary files differnew file mode 100644 index 000000000..135b61ef8 --- /dev/null +++ b/res-xhdpi/images/loop81.png diff --git a/res-xhdpi/images/loop82.png b/res-xhdpi/images/loop82.png Binary files differnew file mode 100644 index 000000000..51da110f0 --- /dev/null +++ b/res-xhdpi/images/loop82.png diff --git a/res-xhdpi/images/loop83.png b/res-xhdpi/images/loop83.png Binary files differnew file mode 100644 index 000000000..84888a9fd --- /dev/null +++ b/res-xhdpi/images/loop83.png diff --git a/res-xhdpi/images/loop84.png b/res-xhdpi/images/loop84.png Binary files differnew file mode 100644 index 000000000..014334400 --- /dev/null +++ b/res-xhdpi/images/loop84.png diff --git a/res-xhdpi/images/loop85.png b/res-xhdpi/images/loop85.png Binary files differnew file mode 100644 index 000000000..58367781b --- /dev/null +++ b/res-xhdpi/images/loop85.png diff --git a/res-xhdpi/images/loop86.png b/res-xhdpi/images/loop86.png Binary files differnew file mode 100644 index 000000000..00166a9d4 --- /dev/null +++ b/res-xhdpi/images/loop86.png diff --git a/res-xhdpi/images/loop87.png b/res-xhdpi/images/loop87.png Binary files differnew file mode 100644 index 000000000..b6f008982 --- /dev/null +++ b/res-xhdpi/images/loop87.png diff --git a/res-xhdpi/images/loop88.png b/res-xhdpi/images/loop88.png Binary files differnew file mode 100644 index 000000000..77b5b4262 --- /dev/null +++ b/res-xhdpi/images/loop88.png diff --git a/res-xhdpi/images/loop89.png b/res-xhdpi/images/loop89.png Binary files differnew file mode 100644 index 000000000..4beb1f04f --- /dev/null +++ b/res-xhdpi/images/loop89.png diff --git a/res-xhdpi/images/loop90.png b/res-xhdpi/images/loop90.png Binary files differnew file mode 100644 index 000000000..45393eac2 --- /dev/null +++ b/res-xhdpi/images/loop90.png diff --git a/res-xxhdpi/images/icon_installing.png b/res-xxhdpi/images/icon_installing.png Binary files differdeleted file mode 100644 index 0fcfbc231..000000000 --- a/res-xxhdpi/images/icon_installing.png +++ /dev/null diff --git a/res-xxhdpi/images/loop00.png b/res-xxhdpi/images/loop00.png Binary files differnew file mode 100644 index 000000000..9d6154452 --- /dev/null +++ b/res-xxhdpi/images/loop00.png diff --git a/res-xxhdpi/images/loop01.png b/res-xxhdpi/images/loop01.png Binary files differnew file mode 100644 index 000000000..024bf6cea --- /dev/null +++ b/res-xxhdpi/images/loop01.png diff --git a/res-xxhdpi/images/loop02.png b/res-xxhdpi/images/loop02.png Binary files differnew file mode 100644 index 000000000..4f6cbf208 --- /dev/null +++ b/res-xxhdpi/images/loop02.png diff --git a/res-xxhdpi/images/loop03.png b/res-xxhdpi/images/loop03.png Binary files differnew file mode 100644 index 000000000..2f3287dfb --- /dev/null +++ b/res-xxhdpi/images/loop03.png diff --git a/res-xxhdpi/images/loop04.png b/res-xxhdpi/images/loop04.png Binary files differnew file mode 100644 index 000000000..bc979ccb7 --- /dev/null +++ b/res-xxhdpi/images/loop04.png diff --git a/res-xxhdpi/images/loop05.png b/res-xxhdpi/images/loop05.png Binary files differnew file mode 100644 index 000000000..b1733db35 --- /dev/null +++ b/res-xxhdpi/images/loop05.png diff --git a/res-xxhdpi/images/loop06.png b/res-xxhdpi/images/loop06.png Binary files differnew file mode 100644 index 000000000..46f629124 --- /dev/null +++ b/res-xxhdpi/images/loop06.png diff --git a/res-xxhdpi/images/loop07.png b/res-xxhdpi/images/loop07.png Binary files differnew file mode 100644 index 000000000..ead912a2b --- /dev/null +++ b/res-xxhdpi/images/loop07.png diff --git a/res-xxhdpi/images/loop08.png b/res-xxhdpi/images/loop08.png Binary files differnew file mode 100644 index 000000000..d693b5b32 --- /dev/null +++ b/res-xxhdpi/images/loop08.png diff --git a/res-xxhdpi/images/loop09.png b/res-xxhdpi/images/loop09.png Binary files differnew file mode 100644 index 000000000..06c703426 --- /dev/null +++ b/res-xxhdpi/images/loop09.png diff --git a/res-xxhdpi/images/loop10.png b/res-xxhdpi/images/loop10.png Binary files differnew file mode 100644 index 000000000..0875b917a --- /dev/null +++ b/res-xxhdpi/images/loop10.png diff --git a/res-xxhdpi/images/loop11.png b/res-xxhdpi/images/loop11.png Binary files differnew file mode 100644 index 000000000..1b0f18eee --- /dev/null +++ b/res-xxhdpi/images/loop11.png diff --git a/res-xxhdpi/images/loop12.png b/res-xxhdpi/images/loop12.png Binary files differnew file mode 100644 index 000000000..540d2927e --- /dev/null +++ b/res-xxhdpi/images/loop12.png diff --git a/res-xxhdpi/images/loop13.png b/res-xxhdpi/images/loop13.png Binary files differnew file mode 100644 index 000000000..5a85eff89 --- /dev/null +++ b/res-xxhdpi/images/loop13.png diff --git a/res-xxhdpi/images/loop14.png b/res-xxhdpi/images/loop14.png Binary files differnew file mode 100644 index 000000000..e94ea24ad --- /dev/null +++ b/res-xxhdpi/images/loop14.png diff --git a/res-xxhdpi/images/loop15.png b/res-xxhdpi/images/loop15.png Binary files differnew file mode 100644 index 000000000..c1a78f50a --- /dev/null +++ b/res-xxhdpi/images/loop15.png diff --git a/res-xxhdpi/images/loop16.png b/res-xxhdpi/images/loop16.png Binary files differnew file mode 100644 index 000000000..7cb3e9aa5 --- /dev/null +++ b/res-xxhdpi/images/loop16.png diff --git a/res-xxhdpi/images/loop17.png b/res-xxhdpi/images/loop17.png Binary files differnew file mode 100644 index 000000000..1ad8497a2 --- /dev/null +++ b/res-xxhdpi/images/loop17.png diff --git a/res-xxhdpi/images/loop18.png b/res-xxhdpi/images/loop18.png Binary files differnew file mode 100644 index 000000000..fb82ebe00 --- /dev/null +++ b/res-xxhdpi/images/loop18.png diff --git a/res-xxhdpi/images/loop19.png b/res-xxhdpi/images/loop19.png Binary files differnew file mode 100644 index 000000000..217d34bf9 --- /dev/null +++ b/res-xxhdpi/images/loop19.png diff --git a/res-xxhdpi/images/loop20.png b/res-xxhdpi/images/loop20.png Binary files differnew file mode 100644 index 000000000..f1cfe78ae --- /dev/null +++ b/res-xxhdpi/images/loop20.png diff --git a/res-xxhdpi/images/loop21.png b/res-xxhdpi/images/loop21.png Binary files differnew file mode 100644 index 000000000..184c86b41 --- /dev/null +++ b/res-xxhdpi/images/loop21.png diff --git a/res-xxhdpi/images/loop22.png b/res-xxhdpi/images/loop22.png Binary files differnew file mode 100644 index 000000000..68e3b2a31 --- /dev/null +++ b/res-xxhdpi/images/loop22.png diff --git a/res-xxhdpi/images/loop23.png b/res-xxhdpi/images/loop23.png Binary files differnew file mode 100644 index 000000000..af188318d --- /dev/null +++ b/res-xxhdpi/images/loop23.png diff --git a/res-xxhdpi/images/loop24.png b/res-xxhdpi/images/loop24.png Binary files differnew file mode 100644 index 000000000..dd7c4a518 --- /dev/null +++ b/res-xxhdpi/images/loop24.png diff --git a/res-xxhdpi/images/loop25.png b/res-xxhdpi/images/loop25.png Binary files differnew file mode 100644 index 000000000..c58c08d24 --- /dev/null +++ b/res-xxhdpi/images/loop25.png diff --git a/res-xxhdpi/images/loop26.png b/res-xxhdpi/images/loop26.png Binary files differnew file mode 100644 index 000000000..4409e551e --- /dev/null +++ b/res-xxhdpi/images/loop26.png diff --git a/res-xxhdpi/images/loop27.png b/res-xxhdpi/images/loop27.png Binary files differnew file mode 100644 index 000000000..e96e1fdb7 --- /dev/null +++ b/res-xxhdpi/images/loop27.png diff --git a/res-xxhdpi/images/loop28.png b/res-xxhdpi/images/loop28.png Binary files differnew file mode 100644 index 000000000..d36ffa91e --- /dev/null +++ b/res-xxhdpi/images/loop28.png diff --git a/res-xxhdpi/images/loop29.png b/res-xxhdpi/images/loop29.png Binary files differnew file mode 100644 index 000000000..936a57052 --- /dev/null +++ b/res-xxhdpi/images/loop29.png diff --git a/res-xxhdpi/images/loop30.png b/res-xxhdpi/images/loop30.png Binary files differnew file mode 100644 index 000000000..b5c5e0490 --- /dev/null +++ b/res-xxhdpi/images/loop30.png diff --git a/res-xxhdpi/images/loop31.png b/res-xxhdpi/images/loop31.png Binary files differnew file mode 100644 index 000000000..1e2aa8b3f --- /dev/null +++ b/res-xxhdpi/images/loop31.png diff --git a/res-xxhdpi/images/loop32.png b/res-xxhdpi/images/loop32.png Binary files differnew file mode 100644 index 000000000..638ec8bc1 --- /dev/null +++ b/res-xxhdpi/images/loop32.png diff --git a/res-xxhdpi/images/loop33.png b/res-xxhdpi/images/loop33.png Binary files differnew file mode 100644 index 000000000..cb62a36a0 --- /dev/null +++ b/res-xxhdpi/images/loop33.png diff --git a/res-xxhdpi/images/loop34.png b/res-xxhdpi/images/loop34.png Binary files differnew file mode 100644 index 000000000..ac877b83d --- /dev/null +++ b/res-xxhdpi/images/loop34.png diff --git a/res-xxhdpi/images/loop35.png b/res-xxhdpi/images/loop35.png Binary files differnew file mode 100644 index 000000000..567cbf1ca --- /dev/null +++ b/res-xxhdpi/images/loop35.png diff --git a/res-xxhdpi/images/loop36.png b/res-xxhdpi/images/loop36.png Binary files differnew file mode 100644 index 000000000..b1c6220e3 --- /dev/null +++ b/res-xxhdpi/images/loop36.png diff --git a/res-xxhdpi/images/loop37.png b/res-xxhdpi/images/loop37.png Binary files differnew file mode 100644 index 000000000..ad40b757d --- /dev/null +++ b/res-xxhdpi/images/loop37.png diff --git a/res-xxhdpi/images/loop38.png b/res-xxhdpi/images/loop38.png Binary files differnew file mode 100644 index 000000000..87be4ef39 --- /dev/null +++ b/res-xxhdpi/images/loop38.png diff --git a/res-xxhdpi/images/loop39.png b/res-xxhdpi/images/loop39.png Binary files differnew file mode 100644 index 000000000..fecaa1ff2 --- /dev/null +++ b/res-xxhdpi/images/loop39.png diff --git a/res-xxhdpi/images/loop40.png b/res-xxhdpi/images/loop40.png Binary files differnew file mode 100644 index 000000000..849caaa2d --- /dev/null +++ b/res-xxhdpi/images/loop40.png diff --git a/res-xxhdpi/images/loop41.png b/res-xxhdpi/images/loop41.png Binary files differnew file mode 100644 index 000000000..9c0b81f48 --- /dev/null +++ b/res-xxhdpi/images/loop41.png diff --git a/res-xxhdpi/images/loop42.png b/res-xxhdpi/images/loop42.png Binary files differnew file mode 100644 index 000000000..9c8657326 --- /dev/null +++ b/res-xxhdpi/images/loop42.png diff --git a/res-xxhdpi/images/loop43.png b/res-xxhdpi/images/loop43.png Binary files differnew file mode 100644 index 000000000..1a5f88822 --- /dev/null +++ b/res-xxhdpi/images/loop43.png diff --git a/res-xxhdpi/images/loop44.png b/res-xxhdpi/images/loop44.png Binary files differnew file mode 100644 index 000000000..2b4a449a7 --- /dev/null +++ b/res-xxhdpi/images/loop44.png diff --git a/res-xxhdpi/images/loop45.png b/res-xxhdpi/images/loop45.png Binary files differnew file mode 100644 index 000000000..11cc31c37 --- /dev/null +++ b/res-xxhdpi/images/loop45.png diff --git a/res-xxhdpi/images/loop46.png b/res-xxhdpi/images/loop46.png Binary files differnew file mode 100644 index 000000000..95f3f993c --- /dev/null +++ b/res-xxhdpi/images/loop46.png diff --git a/res-xxhdpi/images/loop47.png b/res-xxhdpi/images/loop47.png Binary files differnew file mode 100644 index 000000000..ed991154e --- /dev/null +++ b/res-xxhdpi/images/loop47.png diff --git a/res-xxhdpi/images/loop48.png b/res-xxhdpi/images/loop48.png Binary files differnew file mode 100644 index 000000000..e39761c5c --- /dev/null +++ b/res-xxhdpi/images/loop48.png diff --git a/res-xxhdpi/images/loop49.png b/res-xxhdpi/images/loop49.png Binary files differnew file mode 100644 index 000000000..65ec56034 --- /dev/null +++ b/res-xxhdpi/images/loop49.png diff --git a/res-xxhdpi/images/loop50.png b/res-xxhdpi/images/loop50.png Binary files differnew file mode 100644 index 000000000..82631d9db --- /dev/null +++ b/res-xxhdpi/images/loop50.png diff --git a/res-xxhdpi/images/loop51.png b/res-xxhdpi/images/loop51.png Binary files differnew file mode 100644 index 000000000..eb3910c31 --- /dev/null +++ b/res-xxhdpi/images/loop51.png diff --git a/res-xxhdpi/images/loop52.png b/res-xxhdpi/images/loop52.png Binary files differnew file mode 100644 index 000000000..64ec1ad96 --- /dev/null +++ b/res-xxhdpi/images/loop52.png diff --git a/res-xxhdpi/images/loop53.png b/res-xxhdpi/images/loop53.png Binary files differnew file mode 100644 index 000000000..e71c97145 --- /dev/null +++ b/res-xxhdpi/images/loop53.png diff --git a/res-xxhdpi/images/loop54.png b/res-xxhdpi/images/loop54.png Binary files differnew file mode 100644 index 000000000..877e15218 --- /dev/null +++ b/res-xxhdpi/images/loop54.png diff --git a/res-xxhdpi/images/loop55.png b/res-xxhdpi/images/loop55.png Binary files differnew file mode 100644 index 000000000..0a8f8f091 --- /dev/null +++ b/res-xxhdpi/images/loop55.png diff --git a/res-xxhdpi/images/loop56.png b/res-xxhdpi/images/loop56.png Binary files differnew file mode 100644 index 000000000..ed9eff998 --- /dev/null +++ b/res-xxhdpi/images/loop56.png diff --git a/res-xxhdpi/images/loop57.png b/res-xxhdpi/images/loop57.png Binary files differnew file mode 100644 index 000000000..9afb74557 --- /dev/null +++ b/res-xxhdpi/images/loop57.png diff --git a/res-xxhdpi/images/loop58.png b/res-xxhdpi/images/loop58.png Binary files differnew file mode 100644 index 000000000..775514eb8 --- /dev/null +++ b/res-xxhdpi/images/loop58.png diff --git a/res-xxhdpi/images/loop59.png b/res-xxhdpi/images/loop59.png Binary files differnew file mode 100644 index 000000000..b22a3a7fa --- /dev/null +++ b/res-xxhdpi/images/loop59.png diff --git a/res-xxhdpi/images/loop60.png b/res-xxhdpi/images/loop60.png Binary files differnew file mode 100644 index 000000000..94905cab2 --- /dev/null +++ b/res-xxhdpi/images/loop60.png diff --git a/res-xxhdpi/images/loop61.png b/res-xxhdpi/images/loop61.png Binary files differnew file mode 100644 index 000000000..bb9670ccd --- /dev/null +++ b/res-xxhdpi/images/loop61.png diff --git a/res-xxhdpi/images/loop62.png b/res-xxhdpi/images/loop62.png Binary files differnew file mode 100644 index 000000000..1acf5ac57 --- /dev/null +++ b/res-xxhdpi/images/loop62.png diff --git a/res-xxhdpi/images/loop63.png b/res-xxhdpi/images/loop63.png Binary files differnew file mode 100644 index 000000000..03f562086 --- /dev/null +++ b/res-xxhdpi/images/loop63.png diff --git a/res-xxhdpi/images/loop64.png b/res-xxhdpi/images/loop64.png Binary files differnew file mode 100644 index 000000000..7a5ce1824 --- /dev/null +++ b/res-xxhdpi/images/loop64.png diff --git a/res-xxhdpi/images/loop65.png b/res-xxhdpi/images/loop65.png Binary files differnew file mode 100644 index 000000000..022b64601 --- /dev/null +++ b/res-xxhdpi/images/loop65.png diff --git a/res-xxhdpi/images/loop66.png b/res-xxhdpi/images/loop66.png Binary files differnew file mode 100644 index 000000000..9fd326404 --- /dev/null +++ b/res-xxhdpi/images/loop66.png diff --git a/res-xxhdpi/images/loop67.png b/res-xxhdpi/images/loop67.png Binary files differnew file mode 100644 index 000000000..b05e20e11 --- /dev/null +++ b/res-xxhdpi/images/loop67.png diff --git a/res-xxhdpi/images/loop68.png b/res-xxhdpi/images/loop68.png Binary files differnew file mode 100644 index 000000000..66556f94d --- /dev/null +++ b/res-xxhdpi/images/loop68.png diff --git a/res-xxhdpi/images/loop69.png b/res-xxhdpi/images/loop69.png Binary files differnew file mode 100644 index 000000000..34150c3a7 --- /dev/null +++ b/res-xxhdpi/images/loop69.png diff --git a/res-xxhdpi/images/loop70.png b/res-xxhdpi/images/loop70.png Binary files differnew file mode 100644 index 000000000..007f5953d --- /dev/null +++ b/res-xxhdpi/images/loop70.png diff --git a/res-xxhdpi/images/loop71.png b/res-xxhdpi/images/loop71.png Binary files differnew file mode 100644 index 000000000..6db5c64f6 --- /dev/null +++ b/res-xxhdpi/images/loop71.png diff --git a/res-xxhdpi/images/loop72.png b/res-xxhdpi/images/loop72.png Binary files differnew file mode 100644 index 000000000..6e9d8e825 --- /dev/null +++ b/res-xxhdpi/images/loop72.png diff --git a/res-xxhdpi/images/loop73.png b/res-xxhdpi/images/loop73.png Binary files differnew file mode 100644 index 000000000..90c87d358 --- /dev/null +++ b/res-xxhdpi/images/loop73.png diff --git a/res-xxhdpi/images/loop74.png b/res-xxhdpi/images/loop74.png Binary files differnew file mode 100644 index 000000000..c0fe8dd07 --- /dev/null +++ b/res-xxhdpi/images/loop74.png diff --git a/res-xxhdpi/images/loop75.png b/res-xxhdpi/images/loop75.png Binary files differnew file mode 100644 index 000000000..185355820 --- /dev/null +++ b/res-xxhdpi/images/loop75.png diff --git a/res-xxhdpi/images/loop76.png b/res-xxhdpi/images/loop76.png Binary files differnew file mode 100644 index 000000000..911ffeaf5 --- /dev/null +++ b/res-xxhdpi/images/loop76.png diff --git a/res-xxhdpi/images/loop77.png b/res-xxhdpi/images/loop77.png Binary files differnew file mode 100644 index 000000000..87861a20b --- /dev/null +++ b/res-xxhdpi/images/loop77.png diff --git a/res-xxhdpi/images/loop78.png b/res-xxhdpi/images/loop78.png Binary files differnew file mode 100644 index 000000000..4b61b5208 --- /dev/null +++ b/res-xxhdpi/images/loop78.png diff --git a/res-xxhdpi/images/loop79.png b/res-xxhdpi/images/loop79.png Binary files differnew file mode 100644 index 000000000..dea4bcf14 --- /dev/null +++ b/res-xxhdpi/images/loop79.png diff --git a/res-xxhdpi/images/loop80.png b/res-xxhdpi/images/loop80.png Binary files differnew file mode 100644 index 000000000..dab06f389 --- /dev/null +++ b/res-xxhdpi/images/loop80.png diff --git a/res-xxhdpi/images/loop81.png b/res-xxhdpi/images/loop81.png Binary files differnew file mode 100644 index 000000000..4d74671af --- /dev/null +++ b/res-xxhdpi/images/loop81.png diff --git a/res-xxhdpi/images/loop82.png b/res-xxhdpi/images/loop82.png Binary files differnew file mode 100644 index 000000000..7124c88a1 --- /dev/null +++ b/res-xxhdpi/images/loop82.png diff --git a/res-xxhdpi/images/loop83.png b/res-xxhdpi/images/loop83.png Binary files differnew file mode 100644 index 000000000..c8cc938a2 --- /dev/null +++ b/res-xxhdpi/images/loop83.png diff --git a/res-xxhdpi/images/loop84.png b/res-xxhdpi/images/loop84.png Binary files differnew file mode 100644 index 000000000..dbfdaeb24 --- /dev/null +++ b/res-xxhdpi/images/loop84.png diff --git a/res-xxhdpi/images/loop85.png b/res-xxhdpi/images/loop85.png Binary files differnew file mode 100644 index 000000000..211098010 --- /dev/null +++ b/res-xxhdpi/images/loop85.png diff --git a/res-xxhdpi/images/loop86.png b/res-xxhdpi/images/loop86.png Binary files differnew file mode 100644 index 000000000..c402cecf4 --- /dev/null +++ b/res-xxhdpi/images/loop86.png diff --git a/res-xxhdpi/images/loop87.png b/res-xxhdpi/images/loop87.png Binary files differnew file mode 100644 index 000000000..0d7ff318f --- /dev/null +++ b/res-xxhdpi/images/loop87.png diff --git a/res-xxhdpi/images/loop88.png b/res-xxhdpi/images/loop88.png Binary files differnew file mode 100644 index 000000000..754537d36 --- /dev/null +++ b/res-xxhdpi/images/loop88.png diff --git a/res-xxhdpi/images/loop89.png b/res-xxhdpi/images/loop89.png Binary files differnew file mode 100644 index 000000000..68d4d6000 --- /dev/null +++ b/res-xxhdpi/images/loop89.png diff --git a/res-xxhdpi/images/loop90.png b/res-xxhdpi/images/loop90.png Binary files differnew file mode 100644 index 000000000..9d6154452 --- /dev/null +++ b/res-xxhdpi/images/loop90.png diff --git a/res-xxxhdpi/images/icon_installing.png b/res-xxxhdpi/images/icon_installing.png Binary files differdeleted file mode 100644 index 0fcfbc231..000000000 --- a/res-xxxhdpi/images/icon_installing.png +++ /dev/null diff --git a/res-xxxhdpi/images/loop00.png b/res-xxxhdpi/images/loop00.png Binary files differnew file mode 100644 index 000000000..76351c5a2 --- /dev/null +++ b/res-xxxhdpi/images/loop00.png diff --git a/res-xxxhdpi/images/loop01.png b/res-xxxhdpi/images/loop01.png Binary files differnew file mode 100644 index 000000000..acdefc064 --- /dev/null +++ b/res-xxxhdpi/images/loop01.png diff --git a/res-xxxhdpi/images/loop02.png b/res-xxxhdpi/images/loop02.png Binary files differnew file mode 100644 index 000000000..3fcb5e509 --- /dev/null +++ b/res-xxxhdpi/images/loop02.png diff --git a/res-xxxhdpi/images/loop03.png b/res-xxxhdpi/images/loop03.png Binary files differnew file mode 100644 index 000000000..47497a4a6 --- /dev/null +++ b/res-xxxhdpi/images/loop03.png diff --git a/res-xxxhdpi/images/loop04.png b/res-xxxhdpi/images/loop04.png Binary files differnew file mode 100644 index 000000000..1867381a7 --- /dev/null +++ b/res-xxxhdpi/images/loop04.png diff --git a/res-xxxhdpi/images/loop05.png b/res-xxxhdpi/images/loop05.png Binary files differnew file mode 100644 index 000000000..8b7574ccd --- /dev/null +++ b/res-xxxhdpi/images/loop05.png diff --git a/res-xxxhdpi/images/loop06.png b/res-xxxhdpi/images/loop06.png Binary files differnew file mode 100644 index 000000000..e3c0a7d33 --- /dev/null +++ b/res-xxxhdpi/images/loop06.png diff --git a/res-xxxhdpi/images/loop07.png b/res-xxxhdpi/images/loop07.png Binary files differnew file mode 100644 index 000000000..d783ca787 --- /dev/null +++ b/res-xxxhdpi/images/loop07.png diff --git a/res-xxxhdpi/images/loop08.png b/res-xxxhdpi/images/loop08.png Binary files differnew file mode 100644 index 000000000..eefcb3f97 --- /dev/null +++ b/res-xxxhdpi/images/loop08.png diff --git a/res-xxxhdpi/images/loop09.png b/res-xxxhdpi/images/loop09.png Binary files differnew file mode 100644 index 000000000..0f82c269a --- /dev/null +++ b/res-xxxhdpi/images/loop09.png diff --git a/res-xxxhdpi/images/loop10.png b/res-xxxhdpi/images/loop10.png Binary files differnew file mode 100644 index 000000000..bc8624685 --- /dev/null +++ b/res-xxxhdpi/images/loop10.png diff --git a/res-xxxhdpi/images/loop11.png b/res-xxxhdpi/images/loop11.png Binary files differnew file mode 100644 index 000000000..7bd108746 --- /dev/null +++ b/res-xxxhdpi/images/loop11.png diff --git a/res-xxxhdpi/images/loop12.png b/res-xxxhdpi/images/loop12.png Binary files differnew file mode 100644 index 000000000..b9dd44e36 --- /dev/null +++ b/res-xxxhdpi/images/loop12.png diff --git a/res-xxxhdpi/images/loop13.png b/res-xxxhdpi/images/loop13.png Binary files differnew file mode 100644 index 000000000..76c0d46bb --- /dev/null +++ b/res-xxxhdpi/images/loop13.png diff --git a/res-xxxhdpi/images/loop14.png b/res-xxxhdpi/images/loop14.png Binary files differnew file mode 100644 index 000000000..03ff4bd83 --- /dev/null +++ b/res-xxxhdpi/images/loop14.png diff --git a/res-xxxhdpi/images/loop15.png b/res-xxxhdpi/images/loop15.png Binary files differnew file mode 100644 index 000000000..b33cc28cb --- /dev/null +++ b/res-xxxhdpi/images/loop15.png diff --git a/res-xxxhdpi/images/loop16.png b/res-xxxhdpi/images/loop16.png Binary files differnew file mode 100644 index 000000000..cef8302bc --- /dev/null +++ b/res-xxxhdpi/images/loop16.png diff --git a/res-xxxhdpi/images/loop17.png b/res-xxxhdpi/images/loop17.png Binary files differnew file mode 100644 index 000000000..b1d6010fe --- /dev/null +++ b/res-xxxhdpi/images/loop17.png diff --git a/res-xxxhdpi/images/loop18.png b/res-xxxhdpi/images/loop18.png Binary files differnew file mode 100644 index 000000000..2df58f03c --- /dev/null +++ b/res-xxxhdpi/images/loop18.png diff --git a/res-xxxhdpi/images/loop19.png b/res-xxxhdpi/images/loop19.png Binary files differnew file mode 100644 index 000000000..0249bff35 --- /dev/null +++ b/res-xxxhdpi/images/loop19.png diff --git a/res-xxxhdpi/images/loop20.png b/res-xxxhdpi/images/loop20.png Binary files differnew file mode 100644 index 000000000..5968bbb1b --- /dev/null +++ b/res-xxxhdpi/images/loop20.png diff --git a/res-xxxhdpi/images/loop21.png b/res-xxxhdpi/images/loop21.png Binary files differnew file mode 100644 index 000000000..76758e3a1 --- /dev/null +++ b/res-xxxhdpi/images/loop21.png diff --git a/res-xxxhdpi/images/loop22.png b/res-xxxhdpi/images/loop22.png Binary files differnew file mode 100644 index 000000000..7ab40f985 --- /dev/null +++ b/res-xxxhdpi/images/loop22.png diff --git a/res-xxxhdpi/images/loop23.png b/res-xxxhdpi/images/loop23.png Binary files differnew file mode 100644 index 000000000..830569f95 --- /dev/null +++ b/res-xxxhdpi/images/loop23.png diff --git a/res-xxxhdpi/images/loop24.png b/res-xxxhdpi/images/loop24.png Binary files differnew file mode 100644 index 000000000..4b8f77f3a --- /dev/null +++ b/res-xxxhdpi/images/loop24.png diff --git a/res-xxxhdpi/images/loop25.png b/res-xxxhdpi/images/loop25.png Binary files differnew file mode 100644 index 000000000..83df09eeb --- /dev/null +++ b/res-xxxhdpi/images/loop25.png diff --git a/res-xxxhdpi/images/loop26.png b/res-xxxhdpi/images/loop26.png Binary files differnew file mode 100644 index 000000000..4df09dce3 --- /dev/null +++ b/res-xxxhdpi/images/loop26.png diff --git a/res-xxxhdpi/images/loop27.png b/res-xxxhdpi/images/loop27.png Binary files differnew file mode 100644 index 000000000..0b211fe47 --- /dev/null +++ b/res-xxxhdpi/images/loop27.png diff --git a/res-xxxhdpi/images/loop28.png b/res-xxxhdpi/images/loop28.png Binary files differnew file mode 100644 index 000000000..b40985b60 --- /dev/null +++ b/res-xxxhdpi/images/loop28.png diff --git a/res-xxxhdpi/images/loop29.png b/res-xxxhdpi/images/loop29.png Binary files differnew file mode 100644 index 000000000..be5899de7 --- /dev/null +++ b/res-xxxhdpi/images/loop29.png diff --git a/res-xxxhdpi/images/loop30.png b/res-xxxhdpi/images/loop30.png Binary files differnew file mode 100644 index 000000000..a7f95edf9 --- /dev/null +++ b/res-xxxhdpi/images/loop30.png diff --git a/res-xxxhdpi/images/loop31.png b/res-xxxhdpi/images/loop31.png Binary files differnew file mode 100644 index 000000000..1fe0bf3c1 --- /dev/null +++ b/res-xxxhdpi/images/loop31.png diff --git a/res-xxxhdpi/images/loop32.png b/res-xxxhdpi/images/loop32.png Binary files differnew file mode 100644 index 000000000..4bd34b4c7 --- /dev/null +++ b/res-xxxhdpi/images/loop32.png diff --git a/res-xxxhdpi/images/loop33.png b/res-xxxhdpi/images/loop33.png Binary files differnew file mode 100644 index 000000000..c800b02db --- /dev/null +++ b/res-xxxhdpi/images/loop33.png diff --git a/res-xxxhdpi/images/loop34.png b/res-xxxhdpi/images/loop34.png Binary files differnew file mode 100644 index 000000000..926b01089 --- /dev/null +++ b/res-xxxhdpi/images/loop34.png diff --git a/res-xxxhdpi/images/loop35.png b/res-xxxhdpi/images/loop35.png Binary files differnew file mode 100644 index 000000000..20f4cc1db --- /dev/null +++ b/res-xxxhdpi/images/loop35.png diff --git a/res-xxxhdpi/images/loop36.png b/res-xxxhdpi/images/loop36.png Binary files differnew file mode 100644 index 000000000..36e4abec1 --- /dev/null +++ b/res-xxxhdpi/images/loop36.png diff --git a/res-xxxhdpi/images/loop37.png b/res-xxxhdpi/images/loop37.png Binary files differnew file mode 100644 index 000000000..424bb0993 --- /dev/null +++ b/res-xxxhdpi/images/loop37.png diff --git a/res-xxxhdpi/images/loop38.png b/res-xxxhdpi/images/loop38.png Binary files differnew file mode 100644 index 000000000..9e83b0f18 --- /dev/null +++ b/res-xxxhdpi/images/loop38.png diff --git a/res-xxxhdpi/images/loop39.png b/res-xxxhdpi/images/loop39.png Binary files differnew file mode 100644 index 000000000..37c65be71 --- /dev/null +++ b/res-xxxhdpi/images/loop39.png diff --git a/res-xxxhdpi/images/loop40.png b/res-xxxhdpi/images/loop40.png Binary files differnew file mode 100644 index 000000000..961342a7d --- /dev/null +++ b/res-xxxhdpi/images/loop40.png diff --git a/res-xxxhdpi/images/loop41.png b/res-xxxhdpi/images/loop41.png Binary files differnew file mode 100644 index 000000000..28c4aac2a --- /dev/null +++ b/res-xxxhdpi/images/loop41.png diff --git a/res-xxxhdpi/images/loop42.png b/res-xxxhdpi/images/loop42.png Binary files differnew file mode 100644 index 000000000..75adbba4e --- /dev/null +++ b/res-xxxhdpi/images/loop42.png diff --git a/res-xxxhdpi/images/loop43.png b/res-xxxhdpi/images/loop43.png Binary files differnew file mode 100644 index 000000000..4ea659bb5 --- /dev/null +++ b/res-xxxhdpi/images/loop43.png diff --git a/res-xxxhdpi/images/loop44.png b/res-xxxhdpi/images/loop44.png Binary files differnew file mode 100644 index 000000000..a36e0667d --- /dev/null +++ b/res-xxxhdpi/images/loop44.png diff --git a/res-xxxhdpi/images/loop45.png b/res-xxxhdpi/images/loop45.png Binary files differnew file mode 100644 index 000000000..f986268c7 --- /dev/null +++ b/res-xxxhdpi/images/loop45.png diff --git a/res-xxxhdpi/images/loop46.png b/res-xxxhdpi/images/loop46.png Binary files differnew file mode 100644 index 000000000..6b6d52ebf --- /dev/null +++ b/res-xxxhdpi/images/loop46.png diff --git a/res-xxxhdpi/images/loop47.png b/res-xxxhdpi/images/loop47.png Binary files differnew file mode 100644 index 000000000..30c47f59d --- /dev/null +++ b/res-xxxhdpi/images/loop47.png diff --git a/res-xxxhdpi/images/loop48.png b/res-xxxhdpi/images/loop48.png Binary files differnew file mode 100644 index 000000000..35c5801be --- /dev/null +++ b/res-xxxhdpi/images/loop48.png diff --git a/res-xxxhdpi/images/loop49.png b/res-xxxhdpi/images/loop49.png Binary files differnew file mode 100644 index 000000000..849a8e830 --- /dev/null +++ b/res-xxxhdpi/images/loop49.png diff --git a/res-xxxhdpi/images/loop50.png b/res-xxxhdpi/images/loop50.png Binary files differnew file mode 100644 index 000000000..fd48c653a --- /dev/null +++ b/res-xxxhdpi/images/loop50.png diff --git a/res-xxxhdpi/images/loop51.png b/res-xxxhdpi/images/loop51.png Binary files differnew file mode 100644 index 000000000..9326afb6a --- /dev/null +++ b/res-xxxhdpi/images/loop51.png diff --git a/res-xxxhdpi/images/loop52.png b/res-xxxhdpi/images/loop52.png Binary files differnew file mode 100644 index 000000000..7a1686553 --- /dev/null +++ b/res-xxxhdpi/images/loop52.png diff --git a/res-xxxhdpi/images/loop53.png b/res-xxxhdpi/images/loop53.png Binary files differnew file mode 100644 index 000000000..5d4db5bbe --- /dev/null +++ b/res-xxxhdpi/images/loop53.png diff --git a/res-xxxhdpi/images/loop54.png b/res-xxxhdpi/images/loop54.png Binary files differnew file mode 100644 index 000000000..ac12a5c50 --- /dev/null +++ b/res-xxxhdpi/images/loop54.png diff --git a/res-xxxhdpi/images/loop55.png b/res-xxxhdpi/images/loop55.png Binary files differnew file mode 100644 index 000000000..6a2cbc1ca --- /dev/null +++ b/res-xxxhdpi/images/loop55.png diff --git a/res-xxxhdpi/images/loop56.png b/res-xxxhdpi/images/loop56.png Binary files differnew file mode 100644 index 000000000..5947d1864 --- /dev/null +++ b/res-xxxhdpi/images/loop56.png diff --git a/res-xxxhdpi/images/loop57.png b/res-xxxhdpi/images/loop57.png Binary files differnew file mode 100644 index 000000000..dddc757fa --- /dev/null +++ b/res-xxxhdpi/images/loop57.png diff --git a/res-xxxhdpi/images/loop58.png b/res-xxxhdpi/images/loop58.png Binary files differnew file mode 100644 index 000000000..5a7d24829 --- /dev/null +++ b/res-xxxhdpi/images/loop58.png diff --git a/res-xxxhdpi/images/loop59.png b/res-xxxhdpi/images/loop59.png Binary files differnew file mode 100644 index 000000000..34f68e8c6 --- /dev/null +++ b/res-xxxhdpi/images/loop59.png diff --git a/res-xxxhdpi/images/loop60.png b/res-xxxhdpi/images/loop60.png Binary files differnew file mode 100644 index 000000000..7c2b918a5 --- /dev/null +++ b/res-xxxhdpi/images/loop60.png diff --git a/res-xxxhdpi/images/loop61.png b/res-xxxhdpi/images/loop61.png Binary files differnew file mode 100644 index 000000000..b27c4af1b --- /dev/null +++ b/res-xxxhdpi/images/loop61.png diff --git a/res-xxxhdpi/images/loop62.png b/res-xxxhdpi/images/loop62.png Binary files differnew file mode 100644 index 000000000..36e1644d6 --- /dev/null +++ b/res-xxxhdpi/images/loop62.png diff --git a/res-xxxhdpi/images/loop63.png b/res-xxxhdpi/images/loop63.png Binary files differnew file mode 100644 index 000000000..a8126270f --- /dev/null +++ b/res-xxxhdpi/images/loop63.png diff --git a/res-xxxhdpi/images/loop64.png b/res-xxxhdpi/images/loop64.png Binary files differnew file mode 100644 index 000000000..97ff93099 --- /dev/null +++ b/res-xxxhdpi/images/loop64.png diff --git a/res-xxxhdpi/images/loop65.png b/res-xxxhdpi/images/loop65.png Binary files differnew file mode 100644 index 000000000..9d69ba7b2 --- /dev/null +++ b/res-xxxhdpi/images/loop65.png diff --git a/res-xxxhdpi/images/loop66.png b/res-xxxhdpi/images/loop66.png Binary files differnew file mode 100644 index 000000000..42d1a31f5 --- /dev/null +++ b/res-xxxhdpi/images/loop66.png diff --git a/res-xxxhdpi/images/loop67.png b/res-xxxhdpi/images/loop67.png Binary files differnew file mode 100644 index 000000000..bff98b351 --- /dev/null +++ b/res-xxxhdpi/images/loop67.png diff --git a/res-xxxhdpi/images/loop68.png b/res-xxxhdpi/images/loop68.png Binary files differnew file mode 100644 index 000000000..5bfc75b5d --- /dev/null +++ b/res-xxxhdpi/images/loop68.png diff --git a/res-xxxhdpi/images/loop69.png b/res-xxxhdpi/images/loop69.png Binary files differnew file mode 100644 index 000000000..488a245e0 --- /dev/null +++ b/res-xxxhdpi/images/loop69.png diff --git a/res-xxxhdpi/images/loop70.png b/res-xxxhdpi/images/loop70.png Binary files differnew file mode 100644 index 000000000..4a92b7bd1 --- /dev/null +++ b/res-xxxhdpi/images/loop70.png diff --git a/res-xxxhdpi/images/loop71.png b/res-xxxhdpi/images/loop71.png Binary files differnew file mode 100644 index 000000000..b2206383a --- /dev/null +++ b/res-xxxhdpi/images/loop71.png diff --git a/res-xxxhdpi/images/loop72.png b/res-xxxhdpi/images/loop72.png Binary files differnew file mode 100644 index 000000000..91c9d4448 --- /dev/null +++ b/res-xxxhdpi/images/loop72.png diff --git a/res-xxxhdpi/images/loop73.png b/res-xxxhdpi/images/loop73.png Binary files differnew file mode 100644 index 000000000..6cf94863d --- /dev/null +++ b/res-xxxhdpi/images/loop73.png diff --git a/res-xxxhdpi/images/loop74.png b/res-xxxhdpi/images/loop74.png Binary files differnew file mode 100644 index 000000000..d949bc0dc --- /dev/null +++ b/res-xxxhdpi/images/loop74.png diff --git a/res-xxxhdpi/images/loop75.png b/res-xxxhdpi/images/loop75.png Binary files differnew file mode 100644 index 000000000..1b22bc91a --- /dev/null +++ b/res-xxxhdpi/images/loop75.png diff --git a/res-xxxhdpi/images/loop76.png b/res-xxxhdpi/images/loop76.png Binary files differnew file mode 100644 index 000000000..09c8b8e93 --- /dev/null +++ b/res-xxxhdpi/images/loop76.png diff --git a/res-xxxhdpi/images/loop77.png b/res-xxxhdpi/images/loop77.png Binary files differnew file mode 100644 index 000000000..72fa8c890 --- /dev/null +++ b/res-xxxhdpi/images/loop77.png diff --git a/res-xxxhdpi/images/loop78.png b/res-xxxhdpi/images/loop78.png Binary files differnew file mode 100644 index 000000000..d5cc7b209 --- /dev/null +++ b/res-xxxhdpi/images/loop78.png diff --git a/res-xxxhdpi/images/loop79.png b/res-xxxhdpi/images/loop79.png Binary files differnew file mode 100644 index 000000000..207c75a3f --- /dev/null +++ b/res-xxxhdpi/images/loop79.png diff --git a/res-xxxhdpi/images/loop80.png b/res-xxxhdpi/images/loop80.png Binary files differnew file mode 100644 index 000000000..d0b38d764 --- /dev/null +++ b/res-xxxhdpi/images/loop80.png diff --git a/res-xxxhdpi/images/loop81.png b/res-xxxhdpi/images/loop81.png Binary files differnew file mode 100644 index 000000000..c8655eae1 --- /dev/null +++ b/res-xxxhdpi/images/loop81.png diff --git a/res-xxxhdpi/images/loop82.png b/res-xxxhdpi/images/loop82.png Binary files differnew file mode 100644 index 000000000..fca1ad52a --- /dev/null +++ b/res-xxxhdpi/images/loop82.png diff --git a/res-xxxhdpi/images/loop83.png b/res-xxxhdpi/images/loop83.png Binary files differnew file mode 100644 index 000000000..ba1b1bfb0 --- /dev/null +++ b/res-xxxhdpi/images/loop83.png diff --git a/res-xxxhdpi/images/loop84.png b/res-xxxhdpi/images/loop84.png Binary files differnew file mode 100644 index 000000000..9bcf1dd3f --- /dev/null +++ b/res-xxxhdpi/images/loop84.png diff --git a/res-xxxhdpi/images/loop85.png b/res-xxxhdpi/images/loop85.png Binary files differnew file mode 100644 index 000000000..fb1e08be6 --- /dev/null +++ b/res-xxxhdpi/images/loop85.png diff --git a/res-xxxhdpi/images/loop86.png b/res-xxxhdpi/images/loop86.png Binary files differnew file mode 100644 index 000000000..9e2311eff --- /dev/null +++ b/res-xxxhdpi/images/loop86.png diff --git a/res-xxxhdpi/images/loop87.png b/res-xxxhdpi/images/loop87.png Binary files differnew file mode 100644 index 000000000..4c6aee1cb --- /dev/null +++ b/res-xxxhdpi/images/loop87.png diff --git a/res-xxxhdpi/images/loop88.png b/res-xxxhdpi/images/loop88.png Binary files differnew file mode 100644 index 000000000..a40c5159d --- /dev/null +++ b/res-xxxhdpi/images/loop88.png diff --git a/res-xxxhdpi/images/loop89.png b/res-xxxhdpi/images/loop89.png Binary files differnew file mode 100644 index 000000000..c16adfbdc --- /dev/null +++ b/res-xxxhdpi/images/loop89.png diff --git a/res-xxxhdpi/images/loop90.png b/res-xxxhdpi/images/loop90.png Binary files differnew file mode 100644 index 000000000..76351c5a2 --- /dev/null +++ b/res-xxxhdpi/images/loop90.png @@ -175,7 +175,7 @@ static int exec_cmd(const char* path, char* const argv[]) { return WEXITSTATUS(status); } -int format_volume(const char* volume) { +int format_volume(const char* volume, const char* directory) { Volume* v = volume_for_path(volume); if (v == NULL) { LOGE("unknown volume \"%s\"\n", volume); @@ -241,7 +241,7 @@ int format_volume(const char* volume) { } int result; if (strcmp(v->fs_type, "ext4") == 0) { - result = make_ext4fs(v->blk_device, length, volume, sehandle); + result = make_ext4fs_directory(v->blk_device, length, volume, sehandle, directory); } else { /* Has to be f2fs because we checked earlier. */ if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) { LOGE("format_volume: crypt footer + negative length (%zd) not supported on %s\n", length, v->fs_type); @@ -273,6 +273,10 @@ int format_volume(const char* volume) { return -1; } +int format_volume(const char* volume) { + return format_volume(volume, NULL); +} + int setup_install_mounts() { if (fstab == NULL) { LOGE("can't set up install mounts: no fstab loaded\n"); @@ -41,6 +41,12 @@ int ensure_path_unmounted(const char* path); // it is mounted. int format_volume(const char* volume); +// Reformat the given volume (must be the mount point only, eg +// "/cache"), no paths permitted. Attempts to unmount the volume if +// it is mounted. +// Copies 'directory' to root of the newly formatted volume +int format_volume(const char* volume, const char* directory); + // Ensure that all and only the volumes that packages expect to find // mounted (/tmp and /cache) are mounted. Returns 0 on success. int setup_install_mounts(); diff --git a/screen_ui.cpp b/screen_ui.cpp index 522aa6b23..b32df3649 100644 --- a/screen_ui.cpp +++ b/screen_ui.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <dirent.h> #include <errno.h> #include <fcntl.h> #include <linux/input.h> @@ -40,8 +41,7 @@ #include "screen_ui.h" #include "ui.h" -static int char_width; -static int char_height; +#define TEXT_INDENT 4 // Return the current time as a double (including fractions of a second). static double now() { @@ -52,9 +52,9 @@ static double now() { ScreenRecoveryUI::ScreenRecoveryUI() : currentIcon(NONE), - installingFrame(0), locale(nullptr), - rtl_locale(false), + intro_done(false), + current_frame(0), progressBarType(EMPTY), progressScopeStart(0), progressScopeSize(0), @@ -73,30 +73,43 @@ ScreenRecoveryUI::ScreenRecoveryUI() : menu_items(0), menu_sel(0), file_viewer_text_(nullptr), - animation_fps(-1), - installing_frames(-1), + intro_frames(0), + loop_frames(0), + animation_fps(30), // TODO: there's currently no way to infer this. stage(-1), - max_stage(-1) { + max_stage(-1), + rtl_locale(false) { - for (int i = 0; i < 5; i++) { - backgroundIcon[i] = nullptr; - } pthread_mutex_init(&updateMutex, nullptr); } +GRSurface* ScreenRecoveryUI::GetCurrentFrame() { + if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { + return intro_done ? loopFrames[current_frame] : introFrames[current_frame]; + } + return error_icon; +} + +GRSurface* ScreenRecoveryUI::GetCurrentText() { + switch (currentIcon) { + case ERASING: return erasing_text; + case ERROR: return error_text; + case INSTALLING_UPDATE: return installing_text; + case NO_COMMAND: return no_command_text; + case NONE: abort(); + } +} + // Clear the screen and draw the currently selected background icon (if any). // Should only be called with updateMutex locked. -void ScreenRecoveryUI::draw_background_locked(Icon icon) { +void ScreenRecoveryUI::draw_background_locked() { pagesIdentical = false; gr_color(0, 0, 0, 255); gr_clear(); - if (icon) { - GRSurface* surface = backgroundIcon[icon]; - if (icon == INSTALLING_UPDATE || icon == ERASING) { - surface = installation[installingFrame]; - } - GRSurface* text_surface = backgroundText[icon]; + if (currentIcon != NONE) { + GRSurface* surface = GetCurrentFrame(); + GRSurface* text_surface = GetCurrentText(); int iconWidth = gr_get_width(surface); int iconHeight = gr_get_height(surface); @@ -133,14 +146,15 @@ void ScreenRecoveryUI::draw_background_locked(Icon icon) { // Should only be called with updateMutex locked. void ScreenRecoveryUI::draw_progress_locked() { if (currentIcon == ERROR) return; + if (progressBarType != DETERMINATE) return; if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { - GRSurface* icon = installation[installingFrame]; - gr_blit(icon, 0, 0, gr_get_width(icon), gr_get_height(icon), iconX, iconY); + GRSurface* frame = GetCurrentFrame(); + gr_blit(frame, 0, 0, gr_get_width(frame), gr_get_height(frame), iconX, iconY); } if (progressBarType != EMPTY) { - int iconHeight = gr_get_height(backgroundIcon[INSTALLING_UPDATE]); + int iconHeight = gr_get_height(loopFrames[0]); int width = gr_get_width(progressBarEmpty); int height = gr_get_height(progressBarEmpty); @@ -213,14 +227,14 @@ void ScreenRecoveryUI::DrawHorizontalRule(int* y) { *y += 4; } -void ScreenRecoveryUI::DrawTextLine(int* y, const char* line, bool bold) { - gr_text(4, *y, line, bold); - *y += char_height + 4; +void ScreenRecoveryUI::DrawTextLine(int x, int* y, const char* line, bool bold) { + gr_text(x, *y, line, bold); + *y += char_height_ + 4; } -void ScreenRecoveryUI::DrawTextLines(int* y, const char* const* lines) { +void ScreenRecoveryUI::DrawTextLines(int x, int* y, const char* const* lines) { for (size_t i = 0; lines != nullptr && lines[i] != nullptr; ++i) { - DrawTextLine(y, lines[i], false); + DrawTextLine(x, y, lines[i], false); } } @@ -239,7 +253,7 @@ static const char* LONG_PRESS_HELP[] = { // Should only be called with updateMutex locked. void ScreenRecoveryUI::draw_screen_locked() { if (!show_text) { - draw_background_locked(currentIcon); + draw_background_locked(); draw_progress_locked(); } else { gr_color(0, 0, 0, 255); @@ -251,14 +265,14 @@ void ScreenRecoveryUI::draw_screen_locked() { property_get("ro.bootimage.build.fingerprint", recovery_fingerprint, ""); SetColor(INFO); - DrawTextLine(&y, "Android Recovery", true); + DrawTextLine(TEXT_INDENT, &y, "Android Recovery", true); for (auto& chunk : android::base::Split(recovery_fingerprint, ":")) { - DrawTextLine(&y, chunk.c_str(), false); + DrawTextLine(TEXT_INDENT, &y, chunk.c_str(), false); } - DrawTextLines(&y, HasThreeButtons() ? REGULAR_HELP : LONG_PRESS_HELP); + DrawTextLines(TEXT_INDENT, &y, HasThreeButtons() ? REGULAR_HELP : LONG_PRESS_HELP); SetColor(HEADER); - DrawTextLines(&y, menu_headers_); + DrawTextLines(TEXT_INDENT, &y, menu_headers_); SetColor(MENU); DrawHorizontalRule(&y); @@ -267,7 +281,7 @@ void ScreenRecoveryUI::draw_screen_locked() { if (i == menu_sel) { // Draw the highlight bar. SetColor(IsLongPress() ? MENU_SEL_BG_ACTIVE : MENU_SEL_BG); - gr_fill(0, y - 2, gr_fb_width(), y + char_height + 2); + gr_fill(0, y - 2, gr_fb_width(), y + char_height_ + 2); // Bold white text for the selected item. SetColor(MENU_SEL_FG); gr_text(4, y, menu_[i], true); @@ -275,7 +289,7 @@ void ScreenRecoveryUI::draw_screen_locked() { } else { gr_text(4, y, menu_[i], false); } - y += char_height + 4; + y += char_height_ + 4; } DrawHorizontalRule(&y); } @@ -286,9 +300,9 @@ void ScreenRecoveryUI::draw_screen_locked() { SetColor(LOG); int row = (text_top_ + text_rows_ - 1) % text_rows_; size_t count = 0; - for (int ty = gr_fb_height() - char_height; + for (int ty = gr_fb_height() - char_height_; ty >= y && count < text_rows_; - ty -= char_height, ++count) { + ty -= char_height_, ++count) { gr_text(0, ty, text_[row], false); --row; if (row < 0) row = text_rows_ - 1; @@ -327,14 +341,23 @@ void ScreenRecoveryUI::ProgressThreadLoop() { double start = now(); pthread_mutex_lock(&updateMutex); - int redraw = 0; + bool redraw = false; // update the installation animation, if active // skip this if we have a text overlay (too expensive to update) - if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && - installing_frames > 0 && !show_text) { - installingFrame = (installingFrame + 1) % installing_frames; - redraw = 1; + if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && !show_text) { + if (!intro_done) { + if (current_frame == intro_frames - 1) { + intro_done = true; + current_frame = 0; + } else { + ++current_frame; + } + } else { + current_frame = (current_frame + 1) % loop_frames; + } + + redraw = true; } // move the progress bar forward on timed intervals, if configured @@ -345,7 +368,7 @@ void ScreenRecoveryUI::ProgressThreadLoop() { if (p > 1.0) p = 1.0; if (p > progress) { progress = p; - redraw = 1; + redraw = true; } } @@ -363,22 +386,14 @@ void ScreenRecoveryUI::ProgressThreadLoop() { void ScreenRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) { int result = res_create_display_surface(filename, surface); if (result < 0) { - LOGE("missing bitmap %s\n(Code %d)\n", filename, result); - } -} - -void ScreenRecoveryUI::LoadBitmapArray(const char* filename, int* frames, int* fps, - GRSurface*** surface) { - int result = res_create_multi_display_surface(filename, frames, fps, surface); - if (result < 0) { - LOGE("missing bitmap %s\n(Code %d)\n", filename, result); + LOGE("missing bitmap %s (error %d)\n", filename, result); } } void ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, GRSurface** surface) { int result = res_create_localized_alpha_surface(filename, locale, surface); if (result < 0) { - LOGE("missing bitmap %s\n(Code %d)\n", filename, result); + LOGE("missing bitmap %s (error %d)\n", filename, result); } } @@ -394,9 +409,9 @@ static char** Alloc2d(size_t rows, size_t cols) { void ScreenRecoveryUI::Init() { gr_init(); - gr_font_size(&char_width, &char_height); - text_rows_ = gr_fb_height() / char_height; - text_cols_ = gr_fb_width() / char_width; + gr_font_size(&char_width_, &char_height_); + text_rows_ = gr_fb_height() / char_height_; + text_cols_ = gr_fb_width() / char_width_; text_ = Alloc2d(text_rows_, text_cols_ + 1); file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1); @@ -405,31 +420,60 @@ void ScreenRecoveryUI::Init() { text_col_ = text_row_ = 0; text_top_ = 1; - backgroundIcon[NONE] = nullptr; - LoadBitmapArray("icon_installing", &installing_frames, &animation_fps, &installation); - backgroundIcon[INSTALLING_UPDATE] = installing_frames ? installation[0] : nullptr; - backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE]; - LoadBitmap("icon_error", &backgroundIcon[ERROR]); - backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR]; + LoadBitmap("icon_error", &error_icon); LoadBitmap("progress_empty", &progressBarEmpty); LoadBitmap("progress_fill", &progressBarFill); + LoadBitmap("stage_empty", &stageMarkerEmpty); LoadBitmap("stage_fill", &stageMarkerFill); - LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]); - LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]); - LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]); - LoadLocalizedBitmap("error_text", &backgroundText[ERROR]); + LoadLocalizedBitmap("installing_text", &installing_text); + LoadLocalizedBitmap("erasing_text", &erasing_text); + LoadLocalizedBitmap("no_command_text", &no_command_text); + LoadLocalizedBitmap("error_text", &error_text); + + LoadAnimation(); pthread_create(&progress_thread_, nullptr, ProgressThreadStartRoutine, this); RecoveryUI::Init(); } +void ScreenRecoveryUI::LoadAnimation() { + // How many frames of intro and loop do we have? + std::unique_ptr<DIR, decltype(&closedir)> dir(opendir("/res/images"), closedir); + dirent* de; + while ((de = readdir(dir.get())) != nullptr) { + int value; + if (sscanf(de->d_name, "intro%d", &value) == 1 && intro_frames < (value + 1)) { + intro_frames = value + 1; + } else if (sscanf(de->d_name, "loop%d", &value) == 1 && loop_frames < (value + 1)) { + loop_frames = value + 1; + } + } + + // It's okay to not have an intro. + if (intro_frames == 0) intro_done = true; + // But you must have an animation. + if (loop_frames == 0) abort(); + + introFrames = new GRSurface*[intro_frames]; + for (int i = 0; i < intro_frames; ++i) { + LoadBitmap(android::base::StringPrintf("intro%02d", i).c_str(), &introFrames[i]); + } + + loopFrames = new GRSurface*[loop_frames]; + for (int i = 0; i < loop_frames; ++i) { + LoadBitmap(android::base::StringPrintf("loop%02d", i).c_str(), &loopFrames[i]); + } +} + void ScreenRecoveryUI::SetLocale(const char* new_locale) { - if (new_locale) { - this->locale = new_locale; + this->locale = new_locale; + this->rtl_locale = false; + + if (locale) { char* lang = strdup(locale); for (char* p = lang; *p; ++p) { if (*p == '_') { @@ -438,8 +482,7 @@ void ScreenRecoveryUI::SetLocale(const char* new_locale) { } } - // A bit cheesy: keep an explicit list of supported languages - // that are RTL. + // A bit cheesy: keep an explicit list of supported RTL languages. if (strcmp(lang, "ar") == 0 || // Arabic strcmp(lang, "fa") == 0 || // Persian (Farsi) strcmp(lang, "he") == 0 || // Hebrew (new language code) @@ -448,8 +491,6 @@ void ScreenRecoveryUI::SetLocale(const char* new_locale) { rtl_locale = true; } free(lang); - } else { - new_locale = nullptr; } } diff --git a/screen_ui.h b/screen_ui.h index 08a5f44a9..233ff55e6 100644 --- a/screen_ui.h +++ b/screen_ui.h @@ -67,16 +67,23 @@ class ScreenRecoveryUI : public RecoveryUI { }; void SetColor(UIElement e); - private: + protected: Icon currentIcon; - int installingFrame; + const char* locale; - bool rtl_locale; + bool intro_done; + int current_frame; + + GRSurface* error_icon; + + GRSurface* erasing_text; + GRSurface* error_text; + GRSurface* installing_text; + GRSurface* no_command_text; + + GRSurface** introFrames; + GRSurface** loopFrames; - pthread_mutex_t updateMutex; - GRSurface* backgroundIcon[5]; - GRSurface* backgroundText[5]; - GRSurface** installation; GRSurface* progressBarEmpty; GRSurface* progressBarFill; GRSurface* stageMarkerEmpty; @@ -109,21 +116,31 @@ class ScreenRecoveryUI : public RecoveryUI { pthread_t progress_thread_; - // The following two are parsed from the image file - // (e.g. '/res/images/icon_installing.png'). + // Number of intro frames and loop frames in the animation. + int intro_frames; + int loop_frames; + + // Number of frames per sec (default: 30) for both parts of the animation. int animation_fps; - int installing_frames; int iconX, iconY; int stage, max_stage; - void draw_background_locked(Icon icon); + int char_width_; + int char_height_; + pthread_mutex_t updateMutex; + bool rtl_locale; + + void draw_background_locked(); void draw_progress_locked(); void draw_screen_locked(); void update_screen_locked(); void update_progress_locked(); + GRSurface* GetCurrentFrame(); + GRSurface* GetCurrentText(); + static void* ProgressThreadStartRoutine(void* data); void ProgressThreadLoop(); @@ -132,13 +149,13 @@ class ScreenRecoveryUI : public RecoveryUI { void PutChar(char); void ClearText(); - void DrawHorizontalRule(int* y); - void DrawTextLine(int* y, const char* line, bool bold); - void DrawTextLines(int* y, const char* const* lines); - + void LoadAnimation(); void LoadBitmap(const char* filename, GRSurface** surface); - void LoadBitmapArray(const char* filename, int* frames, int* fps, GRSurface*** surface); void LoadLocalizedBitmap(const char* filename, GRSurface** surface); + + void DrawHorizontalRule(int* y); + void DrawTextLine(int x, int* y, const char* line, bool bold); + void DrawTextLines(int x, int* y, const char* const* lines); }; #endif // RECOVERY_UI_H diff --git a/tests/Android.mk b/tests/Android.mk index 7b004b2a0..81435bea4 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -31,12 +31,18 @@ include $(BUILD_NATIVE_TEST) # Component tests include $(CLEAR_VARS) LOCAL_CLANG := true +LOCAL_CFLAGS += -Wno-unused-parameter LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_MODULE := recovery_component_test LOCAL_C_INCLUDES := bootable/recovery -LOCAL_SRC_FILES := component/verifier_test.cpp +LOCAL_SRC_FILES := \ + component/verifier_test.cpp \ + component/applypatch_test.cpp LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_STATIC_LIBRARIES := \ + libapplypatch \ + libotafault \ + libmtdutils \ libbase \ libverifier \ libcrypto_utils_static \ @@ -44,6 +50,8 @@ LOCAL_STATIC_LIBRARIES := \ libminui \ libminzip \ libcutils \ + libbz \ + libz \ libc testdata_out_path := $(TARGET_OUT_DATA_NATIVE_TESTS)/recovery diff --git a/tests/common/test_constants.h b/tests/common/test_constants.h new file mode 100644 index 000000000..3490f6805 --- /dev/null +++ b/tests/common/test_constants.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agree to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _OTA_TEST_CONSTANTS_H +#define _OTA_TEST_CONSTANTS_H + +#if defined(__LP64__) +#define NATIVE_TEST_PATH "/nativetest64" +#else +#define NATIVE_TEST_PATH "/nativetest" +#endif + +#endif diff --git a/tests/component/applypatch_test.cpp b/tests/component/applypatch_test.cpp new file mode 100644 index 000000000..b44ddd17c --- /dev/null +++ b/tests/component/applypatch_test.cpp @@ -0,0 +1,392 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agree to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <fcntl.h> +#include <gtest/gtest.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/statvfs.h> +#include <sys/types.h> +#include <time.h> + +#include <string> + +#include <android-base/file.h> +#include <android-base/stringprintf.h> +#include <android-base/test_utils.h> + +#include "applypatch/applypatch.h" +#include "common/test_constants.h" +#include "openssl/sha.h" +#include "print_sha1.h" + +static const std::string DATA_PATH = getenv("ANDROID_DATA"); +static const std::string TESTDATA_PATH = "/recovery/testdata"; +static const std::string WORK_FS = "/data"; + +static std::string sha1sum(const std::string& fname) { + uint8_t digest[SHA_DIGEST_LENGTH]; + std::string data; + android::base::ReadFileToString(fname, &data); + + SHA1((const uint8_t*)data.c_str(), data.size(), digest); + return print_sha1(digest); +} + +static void mangle_file(const std::string& fname) { + FILE* fh = fopen(&fname[0], "w"); + int r; + for (int i=0; i < 1024; i++) { + r = rand(); + fwrite(&r, sizeof(short), 1, fh); + } + fclose(fh); +} + +static bool file_cmp(std::string& f1, std::string& f2) { + std::string c1; + std::string c2; + android::base::ReadFileToString(f1, &c1); + android::base::ReadFileToString(f2, &c2); + return c1 == c2; +} + +static std::string from_testdata_base(const std::string fname) { + return android::base::StringPrintf("%s%s%s/%s", + &DATA_PATH[0], + &NATIVE_TEST_PATH[0], + &TESTDATA_PATH[0], + &fname[0]); +} + +class ApplyPatchTest : public ::testing::Test { + public: + static void SetUpTestCase() { + // set up files + old_file = from_testdata_base("old.file"); + new_file = from_testdata_base("new.file"); + patch_file = from_testdata_base("patch.bsdiff"); + rand_file = "/cache/applypatch_test_rand.file"; + cache_file = "/cache/saved.file"; + + // write stuff to rand_file + android::base::WriteStringToFile("hello", rand_file); + + // set up SHA constants + old_sha1 = sha1sum(old_file); + new_sha1 = sha1sum(new_file); + srand(time(NULL)); + bad_sha1_a = android::base::StringPrintf("%040x", rand()); + bad_sha1_b = android::base::StringPrintf("%040x", rand()); + + struct stat st; + stat(&new_file[0], &st); + new_size = st.st_size; + } + + static std::string old_file; + static std::string new_file; + static std::string rand_file; + static std::string cache_file; + static std::string patch_file; + + static std::string old_sha1; + static std::string new_sha1; + static std::string bad_sha1_a; + static std::string bad_sha1_b; + + static size_t new_size; +}; + +std::string ApplyPatchTest::old_file; +std::string ApplyPatchTest::new_file; + +static void cp(std::string src, std::string tgt) { + std::string cmd = android::base::StringPrintf("cp %s %s", + &src[0], + &tgt[0]); + system(&cmd[0]); +} + +static void backup_old() { + cp(ApplyPatchTest::old_file, ApplyPatchTest::cache_file); +} + +static void restore_old() { + cp(ApplyPatchTest::cache_file, ApplyPatchTest::old_file); +} + +class ApplyPatchCacheTest : public ApplyPatchTest { + public: + virtual void SetUp() { + backup_old(); + } + + virtual void TearDown() { + restore_old(); + } +}; + +class ApplyPatchFullTest : public ApplyPatchCacheTest { + public: + static void SetUpTestCase() { + ApplyPatchTest::SetUpTestCase(); + unsigned long free_kb = FreeSpaceForFile(&WORK_FS[0]); + ASSERT_GE(free_kb * 1024, new_size * 3 / 2); + output_f = new TemporaryFile(); + output_loc = std::string(output_f->path); + + struct FileContents fc; + + ASSERT_EQ(0, LoadFileContents(&rand_file[0], &fc)); + Value* patch1 = new Value(); + patch1->type = VAL_BLOB; + patch1->size = fc.data.size(); + patch1->data = static_cast<char*>(malloc(fc.data.size())); + memcpy(patch1->data, fc.data.data(), fc.data.size()); + patches.push_back(patch1); + + ASSERT_EQ(0, LoadFileContents(&patch_file[0], &fc)); + Value* patch2 = new Value(); + patch2->type = VAL_BLOB; + patch2->size = fc.st.st_size; + patch2->data = static_cast<char*>(malloc(fc.data.size())); + memcpy(patch2->data, fc.data.data(), fc.data.size()); + patches.push_back(patch2); + } + static void TearDownTestCase() { + delete output_f; + for (auto it = patches.begin(); it != patches.end(); ++it) { + free((*it)->data); + delete *it; + } + patches.clear(); + } + + static std::vector<Value*> patches; + static TemporaryFile* output_f; + static std::string output_loc; +}; + +class ApplyPatchDoubleCacheTest : public ApplyPatchFullTest { + public: + virtual void SetUp() { + ApplyPatchCacheTest::SetUp(); + cp(cache_file, "/cache/reallysaved.file"); + } + + virtual void TearDown() { + cp("/cache/reallysaved.file", cache_file); + ApplyPatchCacheTest::TearDown(); + } +}; + +std::string ApplyPatchTest::rand_file; +std::string ApplyPatchTest::patch_file; +std::string ApplyPatchTest::cache_file; +std::string ApplyPatchTest::old_sha1; +std::string ApplyPatchTest::new_sha1; +std::string ApplyPatchTest::bad_sha1_a; +std::string ApplyPatchTest::bad_sha1_b; + +size_t ApplyPatchTest::new_size; + +std::vector<Value*> ApplyPatchFullTest::patches; +TemporaryFile* ApplyPatchFullTest::output_f; +std::string ApplyPatchFullTest::output_loc; + +TEST_F(ApplyPatchTest, CheckModeSingle) { + char* s = &old_sha1[0]; + ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s)); +} + +TEST_F(ApplyPatchTest, CheckModeMultiple) { + char* argv[3] = { + &bad_sha1_a[0], + &old_sha1[0], + &bad_sha1_b[0] + }; + ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv)); +} + +TEST_F(ApplyPatchTest, CheckModeFailure) { + char* argv[2] = { + &bad_sha1_a[0], + &bad_sha1_b[0] + }; + ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv)); +} + +TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSingle) { + mangle_file(old_file); + char* s = &old_sha1[0]; + ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s)); +} + +TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedMultiple) { + mangle_file(old_file); + char* argv[3] = { + &bad_sha1_a[0], + &old_sha1[0], + &bad_sha1_b[0] + }; + ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv)); +} + +TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedFailure) { + mangle_file(old_file); + char* argv[2] = { + &bad_sha1_a[0], + &bad_sha1_b[0] + }; + ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv)); +} + +TEST_F(ApplyPatchCacheTest, CheckCacheMissingSingle) { + unlink(&old_file[0]); + char* s = &old_sha1[0]; + ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s)); +} + +TEST_F(ApplyPatchCacheTest, CheckCacheMissingMultiple) { + unlink(&old_file[0]); + char* argv[3] = { + &bad_sha1_a[0], + &old_sha1[0], + &bad_sha1_b[0] + }; + ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv)); +} + +TEST_F(ApplyPatchCacheTest, CheckCacheMissingFailure) { + unlink(&old_file[0]); + char* argv[2] = { + &bad_sha1_a[0], + &bad_sha1_b[0] + }; + ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv)); +} + +TEST_F(ApplyPatchFullTest, ApplyInPlace) { + std::vector<char*> sha1s; + sha1s.push_back(&bad_sha1_a[0]); + sha1s.push_back(&old_sha1[0]); + + int ap_result = applypatch(&old_file[0], + "-", + &new_sha1[0], + new_size, + 2, + sha1s.data(), + patches.data(), + nullptr); + ASSERT_EQ(0, ap_result); + ASSERT_TRUE(file_cmp(old_file, new_file)); + // reapply, applypatch is idempotent so it should succeed + ap_result = applypatch(&old_file[0], + "-", + &new_sha1[0], + new_size, + 2, + sha1s.data(), + patches.data(), + nullptr); + ASSERT_EQ(0, ap_result); + ASSERT_TRUE(file_cmp(old_file, new_file)); +} + +TEST_F(ApplyPatchFullTest, ApplyInNewLocation) { + std::vector<char*> sha1s; + sha1s.push_back(&bad_sha1_a[0]); + sha1s.push_back(&old_sha1[0]); + int ap_result = applypatch(&old_file[0], + &output_loc[0], + &new_sha1[0], + new_size, + 2, + sha1s.data(), + patches.data(), + nullptr); + ASSERT_EQ(0, ap_result); + ASSERT_TRUE(file_cmp(output_loc, new_file)); + ap_result = applypatch(&old_file[0], + &output_loc[0], + &new_sha1[0], + new_size, + 2, + sha1s.data(), + patches.data(), + nullptr); + ASSERT_EQ(0, ap_result); + ASSERT_TRUE(file_cmp(output_loc, new_file)); +} + +TEST_F(ApplyPatchFullTest, ApplyCorruptedInNewLocation) { + mangle_file(old_file); + std::vector<char*> sha1s; + sha1s.push_back(&bad_sha1_a[0]); + sha1s.push_back(&old_sha1[0]); + int ap_result = applypatch(&old_file[0], + &output_loc[0], + &new_sha1[0], + new_size, + 2, + sha1s.data(), + patches.data(), + nullptr); + ASSERT_EQ(0, ap_result); + ASSERT_TRUE(file_cmp(output_loc, new_file)); + ap_result = applypatch(&old_file[0], + &output_loc[0], + &new_sha1[0], + new_size, + 2, + sha1s.data(), + patches.data(), + nullptr); + ASSERT_EQ(0, ap_result); + ASSERT_TRUE(file_cmp(output_loc, new_file)); +} + +TEST_F(ApplyPatchDoubleCacheTest, ApplyDoubleCorruptedInNewLocation) { + mangle_file(old_file); + mangle_file(cache_file); + + std::vector<char*> sha1s; + sha1s.push_back(&bad_sha1_a[0]); + sha1s.push_back(&old_sha1[0]); + int ap_result = applypatch(&old_file[0], + &output_loc[0], + &new_sha1[0], + new_size, + 2, + sha1s.data(), + patches.data(), + nullptr); + ASSERT_NE(0, ap_result); + ASSERT_FALSE(file_cmp(output_loc, new_file)); + ap_result = applypatch(&old_file[0], + &output_loc[0], + &new_sha1[0], + new_size, + 2, + sha1s.data(), + patches.data(), + nullptr); + ASSERT_NE(0, ap_result); + ASSERT_FALSE(file_cmp(output_loc, new_file)); +} diff --git a/tests/component/verifier_test.cpp b/tests/component/verifier_test.cpp index b5d70327e..6a5e36901 100644 --- a/tests/component/verifier_test.cpp +++ b/tests/component/verifier_test.cpp @@ -31,16 +31,11 @@ #include <android-base/stringprintf.h> #include "common.h" +#include "common/test_constants.h" #include "minzip/SysUtil.h" #include "ui.h" #include "verifier.h" -#if defined(__LP64__) -#define NATIVE_TEST_PATH "/nativetest64" -#else -#define NATIVE_TEST_PATH "/nativetest" -#endif - static const char* DATA_PATH = getenv("ANDROID_DATA"); static const char* TESTDATA_PATH = "/recovery/testdata/"; diff --git a/tests/testdata/new.file b/tests/testdata/new.file Binary files differnew file mode 100644 index 000000000..cdeb8fd50 --- /dev/null +++ b/tests/testdata/new.file diff --git a/tests/testdata/old.file b/tests/testdata/old.file Binary files differnew file mode 100644 index 000000000..166c8732e --- /dev/null +++ b/tests/testdata/old.file diff --git a/tests/testdata/patch.bsdiff b/tests/testdata/patch.bsdiff Binary files differnew file mode 100644 index 000000000..b78d38573 --- /dev/null +++ b/tests/testdata/patch.bsdiff diff --git a/tools/recovery_l10n/res/layout/main.xml b/tools/recovery_l10n/res/layout/main.xml index 0900b1102..05a16e1e4 100644 --- a/tools/recovery_l10n/res/layout/main.xml +++ b/tools/recovery_l10n/res/layout/main.xml @@ -19,7 +19,9 @@ <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="#ffffffff" + android:fontFamily="sans-serif-medium" + android:textColor="#fff5f5f5" + android:textSize="14sp" android:background="#ff000000" android:maxWidth="480px" android:gravity="center" diff --git a/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java b/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java index 3f2bebe60..817a3ad7d 100644 --- a/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java +++ b/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java @@ -149,12 +149,9 @@ public class Main extends Activity { String[] localeNames = getAssets().getLocales(); Arrays.sort(localeNames); ArrayList<Locale> locales = new ArrayList<Locale>(); - for (String ln : localeNames) { - int u = ln.indexOf('_'); - if (u >= 0) { - Log.i(TAG, "locale = " + ln); - locales.add(new Locale(ln.substring(0, u), ln.substring(u+1))); - } + for (String localeName : localeNames) { + Log.i(TAG, "locale = " + localeName); + locales.add(Locale.forLanguageTag(localeName)); } final Runnable seq = buildSequence(locales.toArray(new Locale[0])); diff --git a/uncrypt/Android.mk b/uncrypt/Android.mk index 6422cb2f4..09cfdfca5 100644 --- a/uncrypt/Android.mk +++ b/uncrypt/Android.mk @@ -15,6 +15,15 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) +LOCAL_CLANG := true +LOCAL_SRC_FILES := bootloader_message_writer.cpp +LOCAL_MODULE := libbootloader_message_writer +LOCAL_STATIC_LIBRARIES := libbase libfs_mgr +LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) LOCAL_CLANG := true @@ -24,7 +33,8 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. LOCAL_MODULE := uncrypt -LOCAL_STATIC_LIBRARIES := libbase liblog libfs_mgr libcutils +LOCAL_STATIC_LIBRARIES := libbootloader_message_writer libbase \ + liblog libfs_mgr libcutils \ LOCAL_INIT_RC := uncrypt.rc diff --git a/uncrypt/bootloader_message_writer.cpp b/uncrypt/bootloader_message_writer.cpp new file mode 100644 index 000000000..3bb106aa0 --- /dev/null +++ b/uncrypt/bootloader_message_writer.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <sys/system_properties.h> + +#include <string> +#include <vector> + +#include <android-base/file.h> +#include <android-base/stringprintf.h> +#include <android-base/unique_fd.h> +#include <fs_mgr.h> + +#include "bootloader.h" + +static struct fstab* read_fstab(std::string* err) { + // The fstab path is always "/fstab.${ro.hardware}". + std::string fstab_path = "/fstab."; + char value[PROP_VALUE_MAX]; + if (__system_property_get("ro.hardware", value) == 0) { + *err = "failed to get ro.hardware"; + return nullptr; + } + fstab_path += value; + struct fstab* fstab = fs_mgr_read_fstab(fstab_path.c_str()); + if (fstab == nullptr) { + *err = "failed to read " + fstab_path; + } + return fstab; +} + +static std::string get_misc_blk_device(std::string* err) { + struct fstab* fstab = read_fstab(err); + if (fstab == nullptr) { + return ""; + } + fstab_rec* record = fs_mgr_get_entry_for_mount_point(fstab, "/misc"); + if (record == nullptr) { + *err = "failed to find /misc partition"; + return ""; + } + return record->blk_device; +} + +static bool write_bootloader_message(const bootloader_message& boot, std::string* err) { + std::string misc_blk_device = get_misc_blk_device(err); + if (misc_blk_device.empty()) { + return false; + } + android::base::unique_fd fd(open(misc_blk_device.c_str(), O_WRONLY | O_SYNC)); + if (fd.get() == -1) { + *err = android::base::StringPrintf("failed to open %s: %s", misc_blk_device.c_str(), + strerror(errno)); + return false; + } + if (!android::base::WriteFully(fd.get(), &boot, sizeof(boot))) { + *err = android::base::StringPrintf("failed to write %s: %s", misc_blk_device.c_str(), + strerror(errno)); + return false; + } + // TODO: O_SYNC and fsync duplicates each other? + if (fsync(fd.get()) == -1) { + *err = android::base::StringPrintf("failed to fsync %s: %s", misc_blk_device.c_str(), + strerror(errno)); + return false; + } + return true; +} + +bool clear_bootloader_message(std::string* err) { + bootloader_message boot = {}; + return write_bootloader_message(boot, err); +} + +bool write_bootloader_message(const std::vector<std::string>& options, std::string* err) { + bootloader_message boot = {}; + strlcpy(boot.command, "boot-recovery", sizeof(boot.command)); + strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery)); + for (const auto& s : options) { + strlcat(boot.recovery, s.c_str(), sizeof(boot.recovery)); + if (s.back() != '\n') { + strlcat(boot.recovery, "\n", sizeof(boot.recovery)); + } + } + return write_bootloader_message(boot, err); +} + +extern "C" bool write_bootloader_message(const char* options) { + std::string err; + return write_bootloader_message({options}, &err); +} diff --git a/uncrypt/include/bootloader_message_writer.h b/uncrypt/include/bootloader_message_writer.h new file mode 100644 index 000000000..e0ca3f44a --- /dev/null +++ b/uncrypt/include/bootloader_message_writer.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BOOTLOADER_MESSAGE_WRITER_H +#define BOOTLOADER_MESSAGE_WRITER_H + +#ifdef __cplusplus +#include <string> +#include <vector> + +bool clear_bootloader_message(std::string* err); + +bool write_bootloader_message(const std::vector<std::string>& options, std::string* err); + +#else +#include <stdbool.h> + +// C Interface. +bool write_bootloader_message(const char* options); +#endif + +#endif // BOOTLOADER_MESSAGE_WRITER_H diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp index 43a2c2ab4..0e14da13f 100644 --- a/uncrypt/uncrypt.cpp +++ b/uncrypt/uncrypt.cpp @@ -39,6 +39,53 @@ // Recovery can take this block map file and retrieve the underlying // file data to use as an update package. +/** + * In addition to the uncrypt work, uncrypt also takes care of setting and + * clearing the bootloader control block (BCB) at /misc partition. + * + * uncrypt is triggered as init services on demand. It uses socket to + * communicate with its caller (i.e. system_server). The socket is managed by + * init (i.e. created prior to the service starts, and destroyed when uncrypt + * exits). + * + * Below is the uncrypt protocol. + * + * a. caller b. init c. uncrypt + * --------------- ------------ -------------- + * a1. ctl.start: + * setup-bcb / + * clear-bcb / + * uncrypt + * + * b2. create socket at + * /dev/socket/uncrypt + * + * c3. listen and accept + * + * a4. send a 4-byte int + * (message length) + * c5. receive message length + * a6. send message + * c7. receive message + * c8. <do the work; may send + * the progress> + * a9. <may handle progress> + * c10. <upon finishing> + * send "100" or "-1" + * + * a11. receive status code + * a12. send a 4-byte int to + * ack the receive of the + * final status code + * c13. receive and exit + * + * b14. destroy the socket + * + * Note that a12 and c13 are necessary to ensure a11 happens before the socket + * gets destroyed in b14. + */ + +#include <arpa/inet.h> #include <errno.h> #include <fcntl.h> #include <inttypes.h> @@ -49,6 +96,7 @@ #include <stdlib.h> #include <string.h> #include <sys/mman.h> +#include <sys/socket.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -62,23 +110,32 @@ #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <android-base/unique_fd.h> +#include <bootloader_message_writer.h> #include <cutils/android_reboot.h> #include <cutils/properties.h> +#include <cutils/sockets.h> #include <fs_mgr.h> #define LOG_TAG "uncrypt" #include <log/log.h> -#include "bootloader.h" - #define WINDOW_SIZE 5 +// uncrypt provides three services: SETUP_BCB, CLEAR_BCB and UNCRYPT. +// +// SETUP_BCB and CLEAR_BCB services use socket communication and do not rely +// on /cache partitions. They will handle requests to reboot into recovery +// (for applying updates for non-A/B devices, or factory resets for all +// devices). +// +// UNCRYPT service still needs files on /cache partition (UNCRYPT_PATH_FILE +// and CACHE_BLOCK_MAP). It will be working (and needed) only for non-A/B +// devices, on which /cache partitions always exist. static const std::string CACHE_BLOCK_MAP = "/cache/recovery/block.map"; -static const std::string COMMAND_FILE = "/cache/recovery/command"; -static const std::string STATUS_FILE = "/cache/recovery/uncrypt_status"; static const std::string UNCRYPT_PATH_FILE = "/cache/recovery/uncrypt_file"; +static const std::string UNCRYPT_SOCKET = "uncrypt"; -static struct fstab* fstab = NULL; +static struct fstab* fstab = nullptr; static int write_at_offset(unsigned char* buffer, size_t size, int wfd, off64_t offset) { if (TEMP_FAILURE_RETRY(lseek64(wfd, offset, SEEK_SET)) == -1) { @@ -152,6 +209,11 @@ static const char* find_block_device(const char* path, bool* encryptable, bool* return NULL; } +static bool write_status_to_socket(int status, int socket) { + int status_out = htonl(status); + return android::base::WriteFully(socket, &status_out, sizeof(int)); +} + // Parse uncrypt_file to find the update package name. static bool find_uncrypt_package(const std::string& uncrypt_path_file, std::string* package_name) { CHECK(package_name != nullptr); @@ -167,7 +229,7 @@ static bool find_uncrypt_package(const std::string& uncrypt_path_file, std::stri } static int produce_block_map(const char* path, const char* map_file, const char* blk_dev, - bool encrypted, int status_fd) { + bool encrypted, int socket) { std::string err; if (!android::base::RemoveFileIfExists(map_file, &err)) { ALOGE("failed to remove the existing map file %s: %s", map_file, err.c_str()); @@ -181,9 +243,9 @@ static int produce_block_map(const char* path, const char* map_file, const char* return -1; } - // Make sure we can write to the status_file. - if (!android::base::WriteStringToFd("0\n", status_fd)) { - ALOGE("failed to update \"%s\"\n", STATUS_FILE.c_str()); + // Make sure we can write to the socket. + if (!write_status_to_socket(0, socket)) { + ALOGE("failed to write to socket %d\n", socket); return -1; } @@ -235,8 +297,8 @@ static int produce_block_map(const char* path, const char* map_file, const char* // Update the status file, progress must be between [0, 99]. int progress = static_cast<int>(100 * (double(pos) / double(sb.st_size))); if (progress > last_progress) { - last_progress = progress; - android::base::WriteStringToFd(std::to_string(progress) + "\n", status_fd); + last_progress = progress; + write_status_to_socket(progress, socket); } if ((tail+1) % WINDOW_SIZE == head) { @@ -349,54 +411,7 @@ static int produce_block_map(const char* path, const char* map_file, const char* return 0; } -static std::string get_misc_blk_device() { - struct fstab* fstab = read_fstab(); - if (fstab == nullptr) { - return ""; - } - for (int i = 0; i < fstab->num_entries; ++i) { - fstab_rec* v = &fstab->recs[i]; - if (v->mount_point != nullptr && strcmp(v->mount_point, "/misc") == 0) { - return v->blk_device; - } - } - return ""; -} - -static int write_bootloader_message(const bootloader_message* in) { - std::string misc_blk_device = get_misc_blk_device(); - if (misc_blk_device.empty()) { - ALOGE("failed to find /misc partition."); - return -1; - } - android::base::unique_fd fd(open(misc_blk_device.c_str(), O_WRONLY | O_SYNC)); - if (fd == -1) { - ALOGE("failed to open %s: %s", misc_blk_device.c_str(), strerror(errno)); - return -1; - } - if (!android::base::WriteFully(fd, in, sizeof(*in))) { - ALOGE("failed to write %s: %s", misc_blk_device.c_str(), strerror(errno)); - return -1; - } - // TODO: O_SYNC and fsync() duplicates each other? - if (fsync(fd) == -1) { - ALOGE("failed to fsync %s: %s", misc_blk_device.c_str(), strerror(errno)); - return -1; - } - return 0; -} - -static void reboot_to_recovery() { - ALOGI("rebooting to recovery"); - property_set("sys.powerctl", "reboot,recovery"); - while (true) { - pause(); - } - ALOGE("reboot didn't succeed?"); -} - -static int uncrypt(const char* input_path, const char* map_file, int status_fd) { - +static int uncrypt(const char* input_path, const char* map_file, const int socket) { ALOGI("update package is \"%s\"", input_path); // Turn the name of the file we're supposed to convert into an @@ -407,10 +422,6 @@ static int uncrypt(const char* input_path, const char* map_file, int status_fd) return 1; } - if (read_fstab() == NULL) { - return 1; - } - bool encryptable; bool encrypted; const char* blk_dev = find_block_device(path, &encryptable, &encrypted); @@ -434,7 +445,7 @@ static int uncrypt(const char* input_path, const char* map_file, int status_fd) // and /sdcard we leave the file alone. if (strncmp(path, "/data/", 6) == 0) { ALOGI("writing block map %s", map_file); - if (produce_block_map(path, map_file, blk_dev, encrypted, status_fd) != 0) { + if (produce_block_map(path, map_file, blk_dev, encrypted, socket) != 0) { return 1; } } @@ -442,102 +453,141 @@ static int uncrypt(const char* input_path, const char* map_file, int status_fd) return 0; } -static int uncrypt_wrapper(const char* input_path, const char* map_file, - const std::string& status_file) { - // The pipe has been created by the system server. - android::base::unique_fd status_fd(open(status_file.c_str(), - O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR)); - if (status_fd == -1) { - ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno)); - return 1; - } - +static bool uncrypt_wrapper(const char* input_path, const char* map_file, const int socket) { std::string package; if (input_path == nullptr) { if (!find_uncrypt_package(UNCRYPT_PATH_FILE, &package)) { - android::base::WriteStringToFd("-1\n", status_fd); - return 1; + write_status_to_socket(-1, socket); + return false; } input_path = package.c_str(); } CHECK(map_file != nullptr); - int status = uncrypt(input_path, map_file, status_fd); + int status = uncrypt(input_path, map_file, socket); if (status != 0) { - android::base::WriteStringToFd("-1\n", status_fd); - return 1; + write_status_to_socket(-1, socket); + return false; } - android::base::WriteStringToFd("100\n", status_fd); - return 0; + write_status_to_socket(100, socket); + return true; } -static int clear_bcb(const std::string& status_file) { - android::base::unique_fd status_fd(open(status_file.c_str(), - O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR)); - if (status_fd == -1) { - ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno)); - return 1; - } - bootloader_message boot = {}; - if (write_bootloader_message(&boot) != 0) { - android::base::WriteStringToFd("-1\n", status_fd); - return 1; +static bool clear_bcb(const int socket) { + std::string err; + if (!clear_bootloader_message(&err)) { + ALOGE("failed to clear bootloader message: %s", err.c_str()); + write_status_to_socket(-1, socket); + return false; } - android::base::WriteStringToFd("100\n", status_fd); - return 0; + write_status_to_socket(100, socket); + return true; } -static int setup_bcb(const std::string& command_file, const std::string& status_file) { - android::base::unique_fd status_fd(open(status_file.c_str(), - O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR)); - if (status_fd == -1) { - ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno)); - return 1; +static bool setup_bcb(const int socket) { + // c5. receive message length + int length; + if (!android::base::ReadFully(socket, &length, 4)) { + ALOGE("failed to read the length: %s", strerror(errno)); + return false; } + length = ntohl(length); + + // c7. receive message std::string content; - if (!android::base::ReadFileToString(command_file, &content)) { - ALOGE("failed to read \"%s\": %s", command_file.c_str(), strerror(errno)); - android::base::WriteStringToFd("-1\n", status_fd); - return 1; + content.resize(length); + if (!android::base::ReadFully(socket, &content[0], length)) { + ALOGE("failed to read the length: %s", strerror(errno)); + return false; } - bootloader_message boot = {}; - strlcpy(boot.command, "boot-recovery", sizeof(boot.command)); - strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery)); - strlcat(boot.recovery, content.c_str(), sizeof(boot.recovery)); - if (write_bootloader_message(&boot) != 0) { - ALOGE("failed to set bootloader message"); - android::base::WriteStringToFd("-1\n", status_fd); - return 1; + ALOGI(" received command: [%s] (%zu)", content.c_str(), content.size()); + + // c8. setup the bcb command + std::string err; + if (!write_bootloader_message({content}, &err)) { + ALOGE("failed to set bootloader message: %s", err.c_str()); + write_status_to_socket(-1, socket); + return false; } - android::base::WriteStringToFd("100\n", status_fd); - return 0; + // c10. send "100" status + write_status_to_socket(100, socket); + return true; } static void usage(const char* exename) { fprintf(stderr, "Usage of %s:\n", exename); fprintf(stderr, "%s [<package_path> <map_file>] Uncrypt ota package.\n", exename); - fprintf(stderr, "%s --reboot Clear BCB data and reboot to recovery.\n", exename); fprintf(stderr, "%s --clear-bcb Clear BCB data in misc partition.\n", exename); fprintf(stderr, "%s --setup-bcb Setup BCB data by command file.\n", exename); } int main(int argc, char** argv) { - if (argc == 2) { - if (strcmp(argv[1], "--reboot") == 0) { - reboot_to_recovery(); - } else if (strcmp(argv[1], "--clear-bcb") == 0) { - return clear_bcb(STATUS_FILE); - } else if (strcmp(argv[1], "--setup-bcb") == 0) { - return setup_bcb(COMMAND_FILE, STATUS_FILE); - } - } else if (argc == 1 || argc == 3) { - const char* input_path = nullptr; - const char* map_file = CACHE_BLOCK_MAP.c_str(); - if (argc == 3) { - input_path = argv[1]; - map_file = argv[2]; - } - return uncrypt_wrapper(input_path, map_file, STATUS_FILE); + enum { UNCRYPT, SETUP_BCB, CLEAR_BCB } action; + const char* input_path = nullptr; + const char* map_file = CACHE_BLOCK_MAP.c_str(); + + if (argc == 2 && strcmp(argv[1], "--clear-bcb") == 0) { + action = CLEAR_BCB; + } else if (argc == 2 && strcmp(argv[1], "--setup-bcb") == 0) { + action = SETUP_BCB; + } else if (argc == 1) { + action = UNCRYPT; + } else if (argc == 3) { + input_path = argv[1]; + map_file = argv[2]; + action = UNCRYPT; + } else { + usage(argv[0]); + return 2; + } + + if ((fstab = read_fstab()) == nullptr) { + return 1; + } + + // c3. The socket is created by init when starting the service. uncrypt + // will use the socket to communicate with its caller. + android::base::unique_fd service_socket(android_get_control_socket(UNCRYPT_SOCKET.c_str())); + if (service_socket == -1) { + ALOGE("failed to open socket \"%s\": %s", UNCRYPT_SOCKET.c_str(), strerror(errno)); + return 1; + } + fcntl(service_socket, F_SETFD, FD_CLOEXEC); + + if (listen(service_socket, 1) == -1) { + ALOGE("failed to listen on socket %d: %s", service_socket.get(), strerror(errno)); + return 1; + } + + android::base::unique_fd socket_fd(accept4(service_socket, nullptr, nullptr, SOCK_CLOEXEC)); + if (socket_fd == -1) { + ALOGE("failed to accept on socket %d: %s", service_socket.get(), strerror(errno)); + return 1; + } + + bool success = false; + switch (action) { + case UNCRYPT: + success = uncrypt_wrapper(input_path, map_file, socket_fd); + break; + case SETUP_BCB: + success = setup_bcb(socket_fd); + break; + case CLEAR_BCB: + success = clear_bcb(socket_fd); + break; + default: // Should never happen. + ALOGE("Invalid uncrypt action code: %d", action); + return 1; + } + + // c13. Read a 4-byte code from the client before uncrypt exits. This is to + // ensure the client to receive the last status code before the socket gets + // destroyed. + int code; + if (android::base::ReadFully(socket_fd, &code, 4)) { + ALOGI(" received %d, exiting now", code); + } else { + ALOGE("failed to read the code: %s", strerror(errno)); } - usage(argv[0]); - return 2; + return success ? 0 : 1; } diff --git a/uncrypt/uncrypt.rc b/uncrypt/uncrypt.rc index b07c1dada..52f564eb6 100644 --- a/uncrypt/uncrypt.rc +++ b/uncrypt/uncrypt.rc @@ -1,19 +1,17 @@ service uncrypt /system/bin/uncrypt class main - disabled - oneshot - -service pre-recovery /system/bin/uncrypt --reboot - class main + socket uncrypt stream 600 system system disabled oneshot service setup-bcb /system/bin/uncrypt --setup-bcb class main + socket uncrypt stream 600 system system disabled oneshot service clear-bcb /system/bin/uncrypt --clear-bcb class main + socket uncrypt stream 600 system system disabled - oneshot
\ No newline at end of file + oneshot diff --git a/verifier.cpp b/verifier.cpp index 1d6cf811a..a2ef946b5 100644 --- a/verifier.cpp +++ b/verifier.cpp @@ -33,6 +33,8 @@ extern RecoveryUI* ui; +static constexpr size_t MiB = 1024 * 1024; + /* * Simple version of PKCS#7 SignedData extraction. This extracts the * signature OCTET STRING to be used for signature verification. @@ -188,8 +190,6 @@ int verify_file(unsigned char* addr, size_t length, } } -#define BUFFER_SIZE 4096 - bool need_sha1 = false; bool need_sha256 = false; for (const auto& key : keys) { @@ -207,8 +207,10 @@ int verify_file(unsigned char* addr, size_t length, double frac = -1.0; size_t so_far = 0; while (so_far < signed_len) { - size_t size = signed_len - so_far; - if (size > BUFFER_SIZE) size = BUFFER_SIZE; + // On a Nexus 9, experiment didn't show any performance improvement with + // larger sizes past 1MiB, and they reduce the granularity of the progress + // bar. http://b/28135231. + size_t size = std::min(signed_len - so_far, 1 * MiB); if (need_sha1) SHA1_Update(&sha1_ctx, addr + so_far, size); if (need_sha256) SHA256_Update(&sha256_ctx, addr + so_far, size); diff --git a/wear_touch.cpp b/wear_touch.cpp new file mode 100644 index 000000000..f22d40b88 --- /dev/null +++ b/wear_touch.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" +#include "wear_touch.h" + +#include <dirent.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +#include <linux/input.h> + +#define DEVICE_PATH "/dev/input" + +WearSwipeDetector::WearSwipeDetector(int low, int high, OnSwipeCallback callback, void* cookie): + mLowThreshold(low), + mHighThreshold(high), + mCallback(callback), + mCookie(cookie), + mCurrentSlot(-1) { + pthread_create(&mThread, NULL, touch_thread, this); +} + +WearSwipeDetector::~WearSwipeDetector() { +} + +void WearSwipeDetector::detect(int dx, int dy) { + enum SwipeDirection direction; + + if (abs(dy) < mLowThreshold && abs(dx) > mHighThreshold) { + direction = dx < 0 ? LEFT : RIGHT; + } else if (abs(dx) < mLowThreshold && abs(dy) > mHighThreshold) { + direction = dy < 0 ? UP : DOWN; + } else { + LOGD("Ignore %d %d\n", dx, dy); + return; + } + + LOGD("Swipe direction=%d\n", direction); + mCallback(mCookie, direction); +} + +void WearSwipeDetector::process(struct input_event *event) { + if (mCurrentSlot < 0) { + mCallback(mCookie, UP); + mCurrentSlot = 0; + } + + if (event->type == EV_ABS) { + if (event->code == ABS_MT_SLOT) + mCurrentSlot = event->value; + + // Ignore other fingers + if (mCurrentSlot > 0) { + return; + } + + switch (event->code) { + case ABS_MT_POSITION_X: + mX = event->value; + mFingerDown = true; + break; + + case ABS_MT_POSITION_Y: + mY = event->value; + mFingerDown = true; + break; + + case ABS_MT_TRACKING_ID: + if (event->value < 0) + mFingerDown = false; + break; + } + } else if (event->type == EV_SYN) { + if (event->code == SYN_REPORT) { + if (mFingerDown && !mSwiping) { + mStartX = mX; + mStartY = mY; + mSwiping = true; + } else if (!mFingerDown && mSwiping) { + mSwiping = false; + detect(mX - mStartX, mY - mStartY); + } + } + } +} + +void WearSwipeDetector::run() { + int fd = findDevice(DEVICE_PATH); + if (fd < 0) { + LOGE("no input devices found\n"); + return; + } + + struct input_event event; + while (read(fd, &event, sizeof(event)) == sizeof(event)) { + process(&event); + } + + close(fd); +} + +void* WearSwipeDetector::touch_thread(void* cookie) { + ((WearSwipeDetector*)cookie)->run(); + return NULL; +} + +#define test_bit(bit, array) (array[bit/8] & (1<<(bit%8))) + +int WearSwipeDetector::openDevice(const char *device) { + int fd = open(device, O_RDONLY); + if (fd < 0) { + LOGE("could not open %s, %s\n", device, strerror(errno)); + return false; + } + + char name[80]; + name[sizeof(name) - 1] = '\0'; + if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { + LOGE("could not get device name for %s, %s\n", device, strerror(errno)); + name[0] = '\0'; + } + + uint8_t bits[512]; + memset(bits, 0, sizeof(bits)); + int ret = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bits)), bits); + if (ret > 0) { + if (test_bit(ABS_MT_POSITION_X, bits) && test_bit(ABS_MT_POSITION_Y, bits)) { + LOGD("Found %s %s\n", device, name); + return fd; + } + } + + close(fd); + return -1; +} + +int WearSwipeDetector::findDevice(const char* path) { + DIR* dir = opendir(path); + if (dir == NULL) { + LOGE("Could not open directory %s", path); + return false; + } + + struct dirent* entry; + int ret = -1; + while (ret < 0 && (entry = readdir(dir)) != NULL) { + if (entry->d_name[0] == '.') continue; + + char device[PATH_MAX]; + device[PATH_MAX-1] = '\0'; + snprintf(device, PATH_MAX-1, "%s/%s", path, entry->d_name); + + ret = openDevice(device); + } + + closedir(dir); + return ret; +} + diff --git a/wear_touch.h b/wear_touch.h new file mode 100644 index 000000000..9a1d3150c --- /dev/null +++ b/wear_touch.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WEAR_TOUCH_H +#define __WEAR_TOUCH_H + +#include <pthread.h> + +class WearSwipeDetector { + +public: + enum SwipeDirection { UP, DOWN, RIGHT, LEFT }; + typedef void (*OnSwipeCallback)(void* cookie, enum SwipeDirection direction); + + WearSwipeDetector(int low, int high, OnSwipeCallback cb, void* cookie); + ~WearSwipeDetector(); + +private: + void run(); + void process(struct input_event *event); + void detect(int dx, int dy); + + pthread_t mThread; + static void* touch_thread(void* cookie); + + int findDevice(const char* path); + int openDevice(const char* device); + + int mLowThreshold; + int mHighThreshold; + + OnSwipeCallback mCallback; + void *mCookie; + + int mX; + int mY; + int mStartX; + int mStartY; + + int mCurrentSlot; + bool mFingerDown; + bool mSwiping; +}; + +#endif // __WEAR_TOUCH_H diff --git a/wear_ui.cpp b/wear_ui.cpp index 50aeb3849..2502313ff 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -16,9 +16,7 @@ #include <errno.h> #include <fcntl.h> -#include <pthread.h> #include <stdarg.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> @@ -31,14 +29,10 @@ #include "common.h" #include "device.h" -#include "minui/minui.h" #include "wear_ui.h" -#include "ui.h" #include "cutils/properties.h" #include "android-base/strings.h" - -static int char_width; -static int char_height; +#include "android-base/stringprintf.h" // There's only (at most) one of these objects, and global callbacks // (for pthread_create, and the input event system) need to find it, @@ -65,7 +59,6 @@ WearRecoveryUI::WearRecoveryUI() : currentIcon(NONE), intro_done(false), current_frame(0), - rtl_locale(false), progressBarType(EMPTY), progressScopeStart(0), progressScopeSize(0), @@ -84,7 +77,6 @@ WearRecoveryUI::WearRecoveryUI() : for (size_t i = 0; i < 5; i++) backgroundIcon[i] = NULL; - pthread_mutex_init(&updateMutex, NULL); self = this; } @@ -148,41 +140,6 @@ void WearRecoveryUI::draw_progress_locked() } } -void WearRecoveryUI::SetColor(UIElement e) { - switch (e) { - case HEADER: - gr_color(247, 0, 6, 255); - break; - case MENU: - case MENU_SEL_BG: - gr_color(0, 106, 157, 255); - break; - case MENU_SEL_FG: - gr_color(255, 255, 255, 255); - break; - case LOG: - gr_color(249, 194, 0, 255); - break; - case TEXT_FILL: - gr_color(0, 0, 0, 160); - break; - default: - gr_color(255, 255, 255, 255); - break; - } -} - -void WearRecoveryUI::DrawTextLine(int x, int* y, const char* line, bool bold) { - gr_text(x, *y, line, bold); - *y += char_height + 4; -} - -void WearRecoveryUI::DrawTextLines(int x, int* y, const char* const* lines) { - for (size_t i = 0; lines != nullptr && lines[i] != nullptr; ++i) { - DrawTextLine(x, y, lines[i], false); - } -} - static const char* HEADERS[] = { "Swipe up/down to move.", "Swipe left/right to select.", @@ -221,7 +178,7 @@ void WearRecoveryUI::draw_screen_locked() if (menu_items > menu_end - menu_start) { sprintf(cur_selection_str, "Current item: %d/%d", menu_sel + 1, menu_items); gr_text(x+4, y, cur_selection_str, 1); - y += char_height+4; + y += char_height_+4; } // Menu begins here @@ -232,7 +189,7 @@ void WearRecoveryUI::draw_screen_locked() if (i == menu_sel) { // draw the highlight bar SetColor(MENU_SEL_BG); - gr_fill(x, y-2, gr_fb_width()-x, y+char_height+2); + gr_fill(x, y-2, gr_fb_width()-x, y+char_height_+2); // white text of selected item SetColor(MENU_SEL_FG); if (menu[i][0]) gr_text(x+4, y, menu[i], 1); @@ -240,7 +197,7 @@ void WearRecoveryUI::draw_screen_locked() } else { if (menu[i][0]) gr_text(x+4, y, menu[i], 0); } - y += char_height+4; + y += char_height_+4; } SetColor(MENU); y += 4; @@ -256,9 +213,9 @@ void WearRecoveryUI::draw_screen_locked() int ty; int row = (text_top+text_rows-1) % text_rows; size_t count = 0; - for (int ty = gr_fb_height() - char_height - outer_height; + for (int ty = gr_fb_height() - char_height_ - outer_height; ty > y+2 && count < text_rows; - ty -= char_height, ++count) { + ty -= char_height_, ++count) { gr_text(x+4, ty, text[row], 0); --row; if (row < 0) row = text_rows-1; @@ -324,26 +281,19 @@ void WearRecoveryUI::progress_loop() { } } -void WearRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) { - int result = res_create_display_surface(filename, surface); - if (result < 0) { - LOGE("missing bitmap %s\n(Code %d)\n", filename, result); - } -} - void WearRecoveryUI::Init() { gr_init(); - gr_font_size(&char_width, &char_height); + gr_font_size(&char_width_, &char_height_); text_col = text_row = 0; - text_rows = (gr_fb_height()) / char_height; - visible_text_rows = (gr_fb_height() - (outer_height * 2)) / char_height; + text_rows = (gr_fb_height()) / char_height_; + visible_text_rows = (gr_fb_height() - (outer_height * 2)) / char_height_; if (text_rows > kMaxRows) text_rows = kMaxRows; text_top = 1; - text_cols = (gr_fb_width() - (outer_width * 2)) / char_width; + text_cols = (gr_fb_width() - (outer_width * 2)) / char_width_; if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1; LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]); @@ -369,29 +319,6 @@ void WearRecoveryUI::Init() RecoveryUI::Init(); } -void WearRecoveryUI::SetLocale(const char* locale) { - if (locale) { - char* lang = strdup(locale); - for (char* p = lang; *p; ++p) { - if (*p == '_') { - *p = '\0'; - break; - } - } - - // A bit cheesy: keep an explicit list of supported languages - // that are RTL. - if (strcmp(lang, "ar") == 0 || // Arabic - strcmp(lang, "fa") == 0 || // Persian (Farsi) - strcmp(lang, "he") == 0 || // Hebrew (new language code) - strcmp(lang, "iw") == 0 || // Hebrew (old language code) - strcmp(lang, "ur") == 0) { // Urdu - rtl_locale = true; - } - free(lang); - } -} - void WearRecoveryUI::SetBackground(Icon icon) { pthread_mutex_lock(&updateMutex); @@ -653,3 +580,35 @@ void WearRecoveryUI::ClearText() { } pthread_mutex_unlock(&updateMutex); } + +void WearRecoveryUI::PrintOnScreenOnly(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + PrintV(fmt, false, ap); + va_end(ap); +} + +void WearRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) { + std::string str; + android::base::StringAppendV(&str, fmt, ap); + + if (copy_to_stdout) { + fputs(str.c_str(), stdout); + } + + pthread_mutex_lock(&updateMutex); + if (text_rows > 0 && text_cols > 0) { + for (const char* ptr = str.c_str(); *ptr != '\0'; ++ptr) { + if (*ptr == '\n' || text_col >= text_cols) { + text[text_row][text_col] = '\0'; + text_col = 0; + text_row = (text_row + 1) % text_rows; + if (text_row == text_top) text_top = (text_top + 1) % text_rows; + } + if (*ptr != '\n') text[text_row][text_col++] = *ptr; + } + text[text_row][text_col] = '\0'; + update_screen_locked(); + } + pthread_mutex_unlock(&updateMutex); +} @@ -17,19 +17,13 @@ #ifndef RECOVERY_WEAR_UI_H #define RECOVERY_WEAR_UI_H -#include <pthread.h> -#include <stdio.h> +#include "screen_ui.h" -#include "ui.h" -#include "minui/minui.h" - -class WearRecoveryUI : public RecoveryUI { +class WearRecoveryUI : public ScreenRecoveryUI { public: WearRecoveryUI(); void Init(); - void SetLocale(const char* locale); - // overall recovery state ("background image") void SetBackground(Icon icon); @@ -47,6 +41,7 @@ class WearRecoveryUI : public RecoveryUI { // printing messages void Print(const char* fmt, ...); + void PrintOnScreenOnly(const char* fmt, ...) __printflike(2, 3); void ShowFile(const char* filename); void ShowFile(FILE* fp); @@ -58,9 +53,6 @@ class WearRecoveryUI : public RecoveryUI { void Redraw(); - enum UIElement { HEADER, MENU, MENU_SEL_BG, MENU_SEL_FG, LOG, TEXT_FILL }; - virtual void SetColor(UIElement e); - protected: int progress_bar_height, progress_bar_width; @@ -89,9 +81,6 @@ class WearRecoveryUI : public RecoveryUI { int current_frame; - bool rtl_locale; - - pthread_mutex_t updateMutex; GRSurface* backgroundIcon[5]; GRSurface* *introFrames; GRSurface* *loopFrames; @@ -128,11 +117,9 @@ class WearRecoveryUI : public RecoveryUI { void update_screen_locked(); static void* progress_thread(void* cookie); void progress_loop(); - void LoadBitmap(const char* filename, GRSurface** surface); void PutChar(char); void ClearText(); - void DrawTextLine(int x, int* y, const char* line, bool bold); - void DrawTextLines(int x, int* y, const char* const* lines); + void PrintV(const char*, bool, va_list); }; #endif // RECOVERY_WEAR_UI_H |