aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrancesco rigamonti <francesco@MacBook-Pro-di-francesco.local>2014-03-01 11:19:46 +0100
committerfrancesco rigamonti <francesco@MacBook-Pro-di-francesco.local>2014-03-01 11:19:46 +0100
commit9fb445c0b56f315413346391cda8fae1c04fa982 (patch)
treeaa5a03d13de841256fb01f5ffa62b9d61f53e4cd
first commit
-rw-r--r--.DS_Storebin0 -> 6148 bytes
-rw-r--r--.classpath13
-rw-r--r--.gitignore1
-rw-r--r--.project33
-rw-r--r--AndroidManifest.xml42
-rw-r--r--LICENSE.txt674
-rw-r--r--README.md0
-rw-r--r--assets/09cron73
-rw-r--r--assets/98tweaks5
-rwxr-xr-xassets/fix_permissions160
-rw-r--r--assets/helpers.sh612
-rwxr-xr-xassets/sql_optimize43
-rwxr-xr-xassets/sqlite3bin0 -> 37688 bytes
-rwxr-xr-xassets/utils44
-rw-r--r--assets/zipbin0 -> 822807 bytes
-rw-r--r--assets/zipalignbin0 -> 83456 bytes
-rw-r--r--gen/com/dsht/kerneltweaker/BuildConfig.java6
-rw-r--r--gen/com/dsht/kerneltweaker/R.java1834
-rw-r--r--gen/com/jeremyfeinstein/slidingmenu/lib/R.java54
-rw-r--r--ic_launcher-web.pngbin0 -> 112818 bytes
-rw-r--r--proguard-project.txt20
-rw-r--r--project.properties15
-rw-r--r--res/anim/card_flip_left_in.xml19
-rw-r--r--res/anim/card_flip_right_out.xml17
-rwxr-xr-xres/anim/push_right_in.xml12
-rwxr-xr-xres/anim/push_right_out.xml12
-rw-r--r--res/drawable-hdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.pngbin0 -> 1368 bytes
-rw-r--r--res/drawable-hdpi/apptheme_btn_radio_off_disabled_holo_dark.pngbin0 -> 654 bytes
-rw-r--r--res/drawable-hdpi/apptheme_btn_radio_off_focused_holo_dark.pngbin0 -> 1385 bytes
-rw-r--r--res/drawable-hdpi/apptheme_btn_radio_off_holo_dark.pngbin0 -> 607 bytes
-rw-r--r--res/drawable-hdpi/apptheme_btn_radio_off_pressed_holo_dark.pngbin0 -> 1234 bytes
-rw-r--r--res/drawable-hdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.pngbin0 -> 2246 bytes
-rw-r--r--res/drawable-hdpi/apptheme_btn_radio_on_disabled_holo_dark.pngbin0 -> 1058 bytes
-rw-r--r--res/drawable-hdpi/apptheme_btn_radio_on_focused_holo_dark.pngbin0 -> 2047 bytes
-rw-r--r--res/drawable-hdpi/apptheme_btn_radio_on_holo_dark.pngbin0 -> 1270 bytes
-rw-r--r--res/drawable-hdpi/apptheme_btn_radio_on_pressed_holo_dark.pngbin0 -> 1532 bytes
-rw-r--r--res/drawable-hdpi/apptheme_fastscroll_thumb_default_holo.pngbin0 -> 263 bytes
-rw-r--r--res/drawable-hdpi/apptheme_fastscroll_thumb_pressed_holo.pngbin0 -> 466 bytes
-rw-r--r--res/drawable-hdpi/apptheme_scrubber_control_disabled_holo.pngbin0 -> 855 bytes
-rw-r--r--res/drawable-hdpi/apptheme_scrubber_control_focused_holo.pngbin0 -> 993 bytes
-rw-r--r--res/drawable-hdpi/apptheme_scrubber_control_normal_holo.pngbin0 -> 1244 bytes
-rw-r--r--res/drawable-hdpi/apptheme_scrubber_control_pressed_holo.pngbin0 -> 1646 bytes
-rw-r--r--res/drawable-hdpi/apptheme_scrubber_primary_holo.9.pngbin0 -> 148 bytes
-rw-r--r--res/drawable-hdpi/apptheme_scrubber_secondary_holo.9.pngbin0 -> 147 bytes
-rw-r--r--res/drawable-hdpi/apptheme_scrubber_track_holo_dark.9.pngbin0 -> 167 bytes
-rw-r--r--res/drawable-hdpi/apptheme_textfield_activated_holo_dark.9.pngbin0 -> 196 bytes
-rw-r--r--res/drawable-hdpi/apptheme_textfield_default_holo_dark.9.pngbin0 -> 188 bytes
-rw-r--r--res/drawable-hdpi/apptheme_textfield_disabled_focused_holo_dark.9.pngbin0 -> 1203 bytes
-rw-r--r--res/drawable-hdpi/apptheme_textfield_disabled_holo_dark.9.pngbin0 -> 1115 bytes
-rw-r--r--res/drawable-hdpi/apptheme_textfield_focused_holo_dark.9.pngbin0 -> 295 bytes
-rw-r--r--res/drawable-hdpi/btn_radio_off_pressed_holo_light.pngbin0 -> 1406 bytes
-rw-r--r--res/drawable-hdpi/btn_radio_on_pressed_holo_light.pngbin0 -> 1711 bytes
-rw-r--r--res/drawable-hdpi/divider_horizontal_dark_opaque.9.pngbin0 -> 106 bytes
-rw-r--r--res/drawable-hdpi/divider_horizontal_holo_dark.9.pngbin0 -> 165 bytes
-rw-r--r--res/drawable-hdpi/divider_horizontal_holo_light.9.pngbin0 -> 164 bytes
-rw-r--r--res/drawable-hdpi/ic_add.pngbin0 -> 794 bytes
-rw-r--r--res/drawable-hdpi/ic_boot.pngbin0 -> 1017 bytes
-rw-r--r--res/drawable-hdpi/ic_checkbox__on.pngbin0 -> 955 bytes
-rw-r--r--res/drawable-hdpi/ic_checkbox_off.pngbin0 -> 190 bytes
-rwxr-xr-xres/drawable-hdpi/ic_colorpicker_swatch_selected.pngbin0 -> 2414 bytes
-rw-r--r--res/drawable-hdpi/ic_delete.pngbin0 -> 898 bytes
-rw-r--r--res/drawable-hdpi/ic_dots.pngbin0 -> 342 bytes
-rw-r--r--res/drawable-hdpi/ic_favcheck.pngbin0 -> 977 bytes
-rw-r--r--res/drawable-hdpi/ic_favuncheck.pngbin0 -> 1213 bytes
-rw-r--r--res/drawable-hdpi/ic_file.pngbin0 -> 397 bytes
-rw-r--r--res/drawable-hdpi/ic_folder.pngbin0 -> 575 bytes
-rw-r--r--res/drawable-hdpi/ic_help.pngbin0 -> 765 bytes
-rw-r--r--res/drawable-hdpi/ic_launcher.pngbin0 -> 4638 bytes
-rwxr-xr-xres/drawable-hdpi/ic_menu_refresh.pngbin0 -> 805 bytes
-rw-r--r--res/drawable-hdpi/ic_plus.pngbin0 -> 289 bytes
-rw-r--r--res/drawable-hdpi/ic_sdcard.pngbin0 -> 575 bytes
-rw-r--r--res/drawable-mdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.pngbin0 -> 770 bytes
-rw-r--r--res/drawable-mdpi/apptheme_btn_radio_off_disabled_holo_dark.pngbin0 -> 464 bytes
-rw-r--r--res/drawable-mdpi/apptheme_btn_radio_off_focused_holo_dark.pngbin0 -> 769 bytes
-rw-r--r--res/drawable-mdpi/apptheme_btn_radio_off_holo_dark.pngbin0 -> 342 bytes
-rw-r--r--res/drawable-mdpi/apptheme_btn_radio_off_pressed_holo_dark.pngbin0 -> 741 bytes
-rw-r--r--res/drawable-mdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.pngbin0 -> 1172 bytes
-rw-r--r--res/drawable-mdpi/apptheme_btn_radio_on_disabled_holo_dark.pngbin0 -> 684 bytes
-rw-r--r--res/drawable-mdpi/apptheme_btn_radio_on_focused_holo_dark.pngbin0 -> 1141 bytes
-rw-r--r--res/drawable-mdpi/apptheme_btn_radio_on_holo_dark.pngbin0 -> 752 bytes
-rw-r--r--res/drawable-mdpi/apptheme_btn_radio_on_pressed_holo_dark.pngbin0 -> 888 bytes
-rw-r--r--res/drawable-mdpi/apptheme_fastscroll_thumb_default_holo.pngbin0 -> 170 bytes
-rw-r--r--res/drawable-mdpi/apptheme_fastscroll_thumb_pressed_holo.pngbin0 -> 302 bytes
-rw-r--r--res/drawable-mdpi/apptheme_scrubber_control_disabled_holo.pngbin0 -> 516 bytes
-rw-r--r--res/drawable-mdpi/apptheme_scrubber_control_focused_holo.pngbin0 -> 620 bytes
-rw-r--r--res/drawable-mdpi/apptheme_scrubber_control_normal_holo.pngbin0 -> 748 bytes
-rw-r--r--res/drawable-mdpi/apptheme_scrubber_control_pressed_holo.pngbin0 -> 935 bytes
-rw-r--r--res/drawable-mdpi/apptheme_scrubber_primary_holo.9.pngbin0 -> 139 bytes
-rw-r--r--res/drawable-mdpi/apptheme_scrubber_secondary_holo.9.pngbin0 -> 137 bytes
-rw-r--r--res/drawable-mdpi/apptheme_scrubber_track_holo_dark.9.pngbin0 -> 161 bytes
-rw-r--r--res/drawable-mdpi/apptheme_textfield_activated_holo_dark.9.pngbin0 -> 164 bytes
-rw-r--r--res/drawable-mdpi/apptheme_textfield_default_holo_dark.9.pngbin0 -> 154 bytes
-rw-r--r--res/drawable-mdpi/apptheme_textfield_disabled_focused_holo_dark.9.pngbin0 -> 1137 bytes
-rw-r--r--res/drawable-mdpi/apptheme_textfield_disabled_holo_dark.9.pngbin0 -> 1091 bytes
-rw-r--r--res/drawable-mdpi/apptheme_textfield_focused_holo_dark.9.pngbin0 -> 259 bytes
-rw-r--r--res/drawable-mdpi/btn_radio_off_pressed_holo_light.pngbin0 -> 873 bytes
-rw-r--r--res/drawable-mdpi/btn_radio_on_pressed_holo_light.pngbin0 -> 1079 bytes
-rw-r--r--res/drawable-mdpi/divider_horizontal_dark_opaque.9.pngbin0 -> 106 bytes
-rw-r--r--res/drawable-mdpi/divider_horizontal_holo_dark.9.pngbin0 -> 164 bytes
-rw-r--r--res/drawable-mdpi/divider_horizontal_holo_light.9.pngbin0 -> 165 bytes
-rw-r--r--res/drawable-mdpi/ic_add.pngbin0 -> 530 bytes
-rw-r--r--res/drawable-mdpi/ic_boot.pngbin0 -> 711 bytes
-rw-r--r--res/drawable-mdpi/ic_checkbox__on.pngbin0 -> 580 bytes
-rw-r--r--res/drawable-mdpi/ic_checkbox_off.pngbin0 -> 102 bytes
-rwxr-xr-xres/drawable-mdpi/ic_colorpicker_swatch_selected.pngbin0 -> 1662 bytes
-rw-r--r--res/drawable-mdpi/ic_delete.pngbin0 -> 576 bytes
-rw-r--r--res/drawable-mdpi/ic_dots.pngbin0 -> 216 bytes
-rw-r--r--res/drawable-mdpi/ic_favcheck.pngbin0 -> 655 bytes
-rw-r--r--res/drawable-mdpi/ic_favuncheck.pngbin0 -> 724 bytes
-rw-r--r--res/drawable-mdpi/ic_file.pngbin0 -> 276 bytes
-rw-r--r--res/drawable-mdpi/ic_folder.pngbin0 -> 402 bytes
-rw-r--r--res/drawable-mdpi/ic_help.pngbin0 -> 519 bytes
-rw-r--r--res/drawable-mdpi/ic_launcher.pngbin0 -> 2567 bytes
-rwxr-xr-xres/drawable-mdpi/ic_menu_refresh.pngbin0 -> 606 bytes
-rw-r--r--res/drawable-mdpi/ic_plus.pngbin0 -> 171 bytes
-rw-r--r--res/drawable-mdpi/ic_sdcard.pngbin0 -> 387 bytes
-rw-r--r--res/drawable-nodpi/aokp.pngbin0 -> 66364 bytes
-rw-r--r--res/drawable-nodpi/backup.pngbin0 -> 3863 bytes
-rw-r--r--res/drawable-nodpi/bar_chart.pngbin0 -> 3192 bytes
-rw-r--r--res/drawable-nodpi/battery_med.pngbin0 -> 3352 bytes
-rw-r--r--res/drawable-nodpi/beaker.pngbin0 -> 4233 bytes
-rw-r--r--res/drawable-nodpi/cesco.pngbin0 -> 108134 bytes
-rw-r--r--res/drawable-nodpi/command.pngbin0 -> 3739 bytes
-rw-r--r--res/drawable-nodpi/doc.pngbin0 -> 3565 bytes
-rw-r--r--res/drawable-nodpi/doc_zip.pngbin0 -> 3970 bytes
-rw-r--r--res/drawable-nodpi/dsht_logo.pngbin0 -> 189605 bytes
-rw-r--r--res/drawable-nodpi/du.pngbin0 -> 30505 bytes
-rw-r--r--res/drawable-nodpi/eye.pngbin0 -> 4502 bytes
-rw-r--r--res/drawable-nodpi/flash_on.pngbin0 -> 4863 bytes
-rw-r--r--res/drawable-nodpi/folder.pngbin0 -> 3518 bytes
-rw-r--r--res/drawable-nodpi/github.pngbin0 -> 26429 bytes
-rw-r--r--res/drawable-nodpi/heart.pngbin0 -> 4146 bytes
-rw-r--r--res/drawable-nodpi/info.pngbin0 -> 4665 bytes
-rw-r--r--res/drawable-nodpi/lcd.pngbin0 -> 3555 bytes
-rw-r--r--res/drawable-nodpi/life_guard.pngbin0 -> 5048 bytes
-rw-r--r--res/drawable-nodpi/magic_wand.pngbin0 -> 3885 bytes
-rw-r--r--res/drawable-nodpi/meter.pngbin0 -> 4436 bytes
-rw-r--r--res/drawable-nodpi/omni.pngbin0 -> 3306 bytes
-rw-r--r--res/drawable-nodpi/plus_minus.pngbin0 -> 3583 bytes
-rw-r--r--res/drawable-nodpi/radiation.pngbin0 -> 4808 bytes
-rw-r--r--res/drawable-nodpi/settings_one.pngbin0 -> 4225 bytes
-rw-r--r--res/drawable-nodpi/settings_two.pngbin0 -> 4514 bytes
-rw-r--r--res/drawable-nodpi/sollyx_google.pngbin0 -> 73614 bytes
-rw-r--r--res/drawable-nodpi/veil.pngbin0 -> 3643 bytes
-rw-r--r--res/drawable-xhdpi/ab_texture_tile.pngbin0 -> 122 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.pngbin0 -> 2012 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_btn_radio_off_disabled_holo_dark.pngbin0 -> 817 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_btn_radio_off_focused_holo_dark.pngbin0 -> 2047 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_btn_radio_off_holo_dark.pngbin0 -> 835 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_btn_radio_off_pressed_holo_dark.pngbin0 -> 1759 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.pngbin0 -> 3293 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_btn_radio_on_disabled_holo_dark.pngbin0 -> 1446 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_btn_radio_on_focused_holo_dark.pngbin0 -> 3444 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_btn_radio_on_holo_dark.pngbin0 -> 2190 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_btn_radio_on_pressed_holo_dark.pngbin0 -> 2212 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_fastscroll_thumb_default_holo.pngbin0 -> 328 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_fastscroll_thumb_pressed_holo.pngbin0 -> 608 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_scrubber_control_disabled_holo.pngbin0 -> 1105 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_scrubber_control_focused_holo.pngbin0 -> 1285 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_scrubber_control_normal_holo.pngbin0 -> 1525 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_scrubber_control_pressed_holo.pngbin0 -> 2137 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_scrubber_primary_holo.9.pngbin0 -> 155 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_scrubber_secondary_holo.9.pngbin0 -> 153 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_scrubber_track_holo_dark.9.pngbin0 -> 174 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_textfield_activated_holo_dark.9.pngbin0 -> 234 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_textfield_default_holo_dark.9.pngbin0 -> 219 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_textfield_disabled_focused_holo_dark.9.pngbin0 -> 1238 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_textfield_disabled_holo_dark.9.pngbin0 -> 1129 bytes
-rw-r--r--res/drawable-xhdpi/apptheme_textfield_focused_holo_dark.9.pngbin0 -> 430 bytes
-rw-r--r--res/drawable-xhdpi/bg_stripes_dark.pngbin0 -> 123 bytes
-rw-r--r--res/drawable-xhdpi/bg_stripes_dark_light.pngbin0 -> 136 bytes
-rw-r--r--res/drawable-xhdpi/btn_radio_off_pressed_holo_light.pngbin0 -> 2159 bytes
-rw-r--r--res/drawable-xhdpi/btn_radio_on_pressed_holo_light.pngbin0 -> 2675 bytes
-rw-r--r--res/drawable-xhdpi/divider_horizontal_dark_opaque.9.pngbin0 -> 106 bytes
-rw-r--r--res/drawable-xhdpi/divider_horizontal_holo_dark.9.pngbin0 -> 171 bytes
-rw-r--r--res/drawable-xhdpi/divider_horizontal_holo_light.9.pngbin0 -> 173 bytes
-rw-r--r--res/drawable-xhdpi/ic_add.pngbin0 -> 1097 bytes
-rw-r--r--res/drawable-xhdpi/ic_boot.pngbin0 -> 1419 bytes
-rw-r--r--res/drawable-xhdpi/ic_checkbox__on.pngbin0 -> 1353 bytes
-rw-r--r--res/drawable-xhdpi/ic_checkbox_off.pngbin0 -> 189 bytes
-rwxr-xr-xres/drawable-xhdpi/ic_colorpicker_swatch_selected.pngbin0 -> 3241 bytes
-rw-r--r--res/drawable-xhdpi/ic_delete.pngbin0 -> 1146 bytes
-rw-r--r--res/drawable-xhdpi/ic_dots.pngbin0 -> 355 bytes
-rw-r--r--res/drawable-xhdpi/ic_favcheck.pngbin0 -> 1391 bytes
-rw-r--r--res/drawable-xhdpi/ic_favuncheck.pngbin0 -> 1756 bytes
-rw-r--r--res/drawable-xhdpi/ic_file.pngbin0 -> 470 bytes
-rw-r--r--res/drawable-xhdpi/ic_folder.pngbin0 -> 751 bytes
-rw-r--r--res/drawable-xhdpi/ic_help.pngbin0 -> 1021 bytes
-rw-r--r--res/drawable-xhdpi/ic_launcher.pngbin0 -> 6950 bytes
-rwxr-xr-xres/drawable-xhdpi/ic_menu_refresh.pngbin0 -> 893 bytes
-rw-r--r--res/drawable-xhdpi/ic_plus.pngbin0 -> 336 bytes
-rw-r--r--res/drawable-xhdpi/ic_sdcard.pngbin0 -> 705 bytes
-rw-r--r--res/drawable-xhdpi/view_pager_background_texture.pngbin0 -> 120 bytes
-rw-r--r--res/drawable-xhdpi/view_pager_background_texture_light.pngbin0 -> 110 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.pngbin0 -> 2434 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_btn_radio_off_disabled_holo_dark.pngbin0 -> 2144 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_btn_radio_off_focused_holo_dark.pngbin0 -> 2534 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_btn_radio_off_holo_dark.pngbin0 -> 1241 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_btn_radio_off_pressed_holo_dark.pngbin0 -> 2390 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.pngbin0 -> 4393 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_btn_radio_on_disabled_holo_dark.pngbin0 -> 3826 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_btn_radio_on_focused_holo_dark.pngbin0 -> 4632 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_btn_radio_on_holo_dark.pngbin0 -> 3110 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_btn_radio_on_pressed_holo_dark.pngbin0 -> 2914 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_fastscroll_thumb_default_holo.pngbin0 -> 606 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_fastscroll_thumb_pressed_holo.pngbin0 -> 910 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_scrubber_control_disabled_holo.pngbin0 -> 1411 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_scrubber_control_focused_holo.pngbin0 -> 1942 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_scrubber_control_normal_holo.pngbin0 -> 2413 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_scrubber_control_pressed_holo.pngbin0 -> 2531 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_scrubber_primary_holo.9.pngbin0 -> 148 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_scrubber_secondary_holo.9.pngbin0 -> 151 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_scrubber_track_holo_dark.9.pngbin0 -> 1094 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_textfield_activated_holo_dark.9.pngbin0 -> 336 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_textfield_default_holo_dark.9.pngbin0 -> 332 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_textfield_disabled_focused_holo_dark.9.pngbin0 -> 486 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_textfield_disabled_holo_dark.9.pngbin0 -> 317 bytes
-rw-r--r--res/drawable-xxhdpi/apptheme_textfield_focused_holo_dark.9.pngbin0 -> 510 bytes
-rw-r--r--res/drawable-xxhdpi/btn_radio_off_pressed_holo_light.pngbin0 -> 2923 bytes
-rw-r--r--res/drawable-xxhdpi/btn_radio_on_pressed_holo_light.pngbin0 -> 3666 bytes
-rw-r--r--res/drawable-xxhdpi/divider_horizontal_dark_opaque.9.pngbin0 -> 106 bytes
-rw-r--r--res/drawable-xxhdpi/ic_add.pngbin0 -> 1658 bytes
-rw-r--r--res/drawable-xxhdpi/ic_boot.pngbin0 -> 2344 bytes
-rw-r--r--res/drawable-xxhdpi/ic_checkbox__on.pngbin0 -> 2417 bytes
-rw-r--r--res/drawable-xxhdpi/ic_checkbox_off.pngbin0 -> 384 bytes
-rw-r--r--res/drawable-xxhdpi/ic_delete.pngbin0 -> 1843 bytes
-rw-r--r--res/drawable-xxhdpi/ic_dots.pngbin0 -> 617 bytes
-rw-r--r--res/drawable-xxhdpi/ic_favcheck.pngbin0 -> 2106 bytes
-rw-r--r--res/drawable-xxhdpi/ic_favuncheck.pngbin0 -> 2816 bytes
-rw-r--r--res/drawable-xxhdpi/ic_file.pngbin0 -> 597 bytes
-rw-r--r--res/drawable-xxhdpi/ic_folder.pngbin0 -> 1087 bytes
-rw-r--r--res/drawable-xxhdpi/ic_help.pngbin0 -> 1600 bytes
-rw-r--r--res/drawable-xxhdpi/ic_launcher.pngbin0 -> 12879 bytes
-rw-r--r--res/drawable-xxhdpi/ic_plus.pngbin0 -> 645 bytes
-rw-r--r--res/drawable-xxhdpi/ic_sdcard.pngbin0 -> 1127 bytes
-rw-r--r--res/drawable-xxxhdpi/ic_boot.pngbin0 -> 3259 bytes
-rw-r--r--res/drawable/apptheme_btn_radio_holo_dark.xml59
-rw-r--r--res/drawable/apptheme_edit_text_holo_dark.xml25
-rw-r--r--res/drawable/apptheme_fastscroll_thumb_holo.xml20
-rw-r--r--res/drawable/apptheme_scrubber_control_selector_holo_dark.xml22
-rw-r--r--res/drawable/apptheme_scrubber_progress_horizontal_holo_dark.xml28
-rw-r--r--res/drawable/background_holo_dark.xml22
-rw-r--r--res/drawable/background_holo_light.xml22
-rw-r--r--res/drawable/bg_dark.xml3
-rw-r--r--res/drawable/bg_light.xml3
-rw-r--r--res/drawable/bg_menu_dark.xml3
-rw-r--r--res/drawable/bg_menu_light.xml3
-rw-r--r--res/drawable/bottombutton.xml7
-rwxr-xr-xres/drawable/calendar_color_picker_swatch.xml16
-rwxr-xr-xres/drawable/calendar_color_square.xml16
-rw-r--r--res/drawable/card_bg.xml28
-rw-r--r--res/drawable/checkbox_selector.xml7
-rw-r--r--res/drawable/checkbox_selector_light.xml7
-rw-r--r--res/drawable/screen_background_selector_dark.xml21
-rw-r--r--res/drawable/screen_background_selector_light.xml21
-rw-r--r--res/drawable/selector.xml8
-rw-r--r--res/drawable/shadow.xml9
-rw-r--r--res/drawable/shadow_right.xml9
-rw-r--r--res/drawable/top_shadow.xml9
-rw-r--r--res/layout/activity_main.xml19
-rw-r--r--res/layout/activity_main_container.xml6
-rw-r--r--res/layout/backup_dialog_layout.xml91
-rw-r--r--res/layout/backup_list.xml182
-rw-r--r--res/layout/backup_list_item.xml24
-rw-r--r--res/layout/boot_dialog_layout.xml25
-rwxr-xr-xres/layout/calendar_color_picker_dialog.xml45
-rwxr-xr-xres/layout/calendar_color_picker_swatch.xml28
-rwxr-xr-xres/layout/calendar_grid_item_color.xml28
-rwxr-xr-xres/layout/cpu_info.xml51
-rwxr-xr-xres/layout/cpu_info_item.xml23
-rwxr-xr-xres/layout/dialog_about.xml9
-rw-r--r--res/layout/dialog_layout.xml16
-rw-r--r--res/layout/dragsort_list.xml81
-rw-r--r--res/layout/dragsort_list_item.xml49
-rw-r--r--res/layout/empty_test.xml18
-rw-r--r--res/layout/file_list_item.xml40
-rw-r--r--res/layout/header.xml21
-rw-r--r--res/layout/layout_list.xml61
-rw-r--r--res/layout/layout_list_file.xml23
-rw-r--r--res/layout/list_item.xml56
-rw-r--r--res/layout/lmk_footer.xml14
-rw-r--r--res/layout/lmk_layout.xml12
-rw-r--r--res/layout/log_dialog.xml23
-rw-r--r--res/layout/menu_glossary.xml18
-rw-r--r--res/layout/menu_header.xml14
-rw-r--r--res/layout/menu_list.xml16
-rw-r--r--res/layout/menu_list_item.xml30
-rw-r--r--res/layout/menu_main_list_item.xml30
-rw-r--r--res/layout/preference.xml97
-rw-r--r--res/layout/preference_widget_seekbar.xml84
-rwxr-xr-xres/layout/seekbar_dialog.xml47
-rwxr-xr-xres/layout/state_row.xml64
-rwxr-xr-xres/layout/time_in_state.xml96
-rw-r--r--res/layout/wallpaper_effects.xml71
-rwxr-xr-xres/menu/cpu_info_menu.xml8
-rw-r--r--res/menu/main.xml16
-rw-r--r--res/menu/menu_lmk.xml10
-rw-r--r--res/menu/menu_main_container.xml4
-rw-r--r--res/menu/menu_recovery.xml10
-rw-r--r--res/menu/menu_review.xml9
-rw-r--r--res/menu/menu_uv.xml20
-rwxr-xr-xres/menu/time_in_state_menu.xml16
-rw-r--r--res/values-sw600dp/dimens.xml8
-rw-r--r--res/values-sw720dp-land/dimens.xml9
-rw-r--r--res/values-v11/styles.xml11
-rw-r--r--res/values-v14/styles.xml12
-rw-r--r--res/values/analytics.xml12
-rw-r--r--res/values/attrs.xml7
-rwxr-xr-xres/values/calendar_attrs.xml9
-rwxr-xr-xres/values/calendar_dimens.xml21
-rwxr-xr-xres/values/calendar_strings.xml47
-rw-r--r--res/values/colors.xml10
-rwxr-xr-xres/values/config.xml32
-rw-r--r--res/values/dimens.xml11
-rwxr-xr-xres/values/dslv_attrs.xml30
-rw-r--r--res/values/strings.xml1167
-rw-r--r--res/values/styles.xml55
-rw-r--r--res/values/themes.xml18
-rw-r--r--res/xml/infos.xml16
-rw-r--r--res/xml/init_d.xml27
-rwxr-xr-xres/xml/pc_settings.xml30
-rw-r--r--res/xml/pref_sccreen_uv.xml8
-rw-r--r--res/xml/pref_screen_cpu.xml36
-rw-r--r--res/xml/pref_screen_governor.xml9
-rw-r--r--res/xml/pref_screen_gpu.xml13
-rw-r--r--res/xml/pref_screen_kernel.xml75
-rw-r--r--res/xml/pref_screen_minfree.xml2
-rw-r--r--res/xml/pref_screen_review.xml41
-rw-r--r--res/xml/pref_screen_scheduler.xml9
-rw-r--r--res/xml/pref_settings.xml169
-rw-r--r--res/xml/propmodder.xml131
-rwxr-xr-xres/xml/vm.xml46
-rwxr-xr-xres/xml/vm_settings.xml47
-rw-r--r--res/xml/wallpaper.xml5
-rw-r--r--src/com/dsht/glossary/ConservativeGlossaryFragment.java41
-rw-r--r--src/com/dsht/glossary/CpuGlossaryFragment.java66
-rw-r--r--src/com/dsht/glossary/GovernorGlossaryFragment.java42
-rw-r--r--src/com/dsht/glossary/GpuGlossaryFragment.java41
-rw-r--r--src/com/dsht/glossary/InteractiveGlossaryFragment.java41
-rw-r--r--src/com/dsht/glossary/KernelGlossaryFragment.java73
-rw-r--r--src/com/dsht/glossary/LmkGlossaryFragment.java41
-rw-r--r--src/com/dsht/glossary/OndemandGlossaryFragment.java41
-rw-r--r--src/com/dsht/glossary/SchedGlossaryFragment.java41
-rw-r--r--src/com/dsht/glossary/TcpGlossaryFragment.java41
-rw-r--r--src/com/dsht/glossary/UvGlossaryFragment.java41
-rw-r--r--src/com/dsht/glossary/VmGlossaryFragment.java41
-rw-r--r--src/com/dsht/kerneltweaker/BackupBaseAdapter.java85
-rw-r--r--src/com/dsht/kerneltweaker/CircleAnimatedCheckBox.java147
-rw-r--r--src/com/dsht/kerneltweaker/CustomArrayAdapter.java169
-rw-r--r--src/com/dsht/kerneltweaker/CustomBaseAdapter.java171
-rw-r--r--src/com/dsht/kerneltweaker/CustomCheckBoxPreference.java170
-rw-r--r--src/com/dsht/kerneltweaker/CustomListPreference.java169
-rw-r--r--src/com/dsht/kerneltweaker/CustomPreference.java220
-rw-r--r--src/com/dsht/kerneltweaker/FileBaseAdapter.java75
-rw-r--r--src/com/dsht/kerneltweaker/GlossaryArrayAdapter.java72
-rw-r--r--src/com/dsht/kerneltweaker/Helpers.java730
-rw-r--r--src/com/dsht/kerneltweaker/ListViewMultiChoiceModeListener.java344
-rw-r--r--src/com/dsht/kerneltweaker/MainActivity.java456
-rw-r--r--src/com/dsht/kerneltweaker/PresetsBaseAdapter.java73
-rw-r--r--src/com/dsht/kerneltweaker/RecoveryBaseAdapter.java111
-rw-r--r--src/com/dsht/kerneltweaker/Startup.java118
-rw-r--r--src/com/dsht/kerneltweaker/SwipeDismissListViewTouchListener.java370
-rw-r--r--src/com/dsht/kerneltweaker/SwipeDismissTouchListener.java255
-rw-r--r--src/com/dsht/kerneltweaker/ZoomOutPageTransformer.java43
-rw-r--r--src/com/dsht/kerneltweaker/database/DataItem.java82
-rw-r--r--src/com/dsht/kerneltweaker/database/DatabaseHandler.java173
-rw-r--r--src/com/dsht/kerneltweaker/database/VddDatabaseHandler.java173
-rw-r--r--src/com/dsht/kerneltweaker/fragments/BackupFragment.java279
-rw-r--r--src/com/dsht/kerneltweaker/fragments/CpuGovernorPreferenceFragment.java250
-rw-r--r--src/com/dsht/kerneltweaker/fragments/CpuPreferenceFragment.java409
-rw-r--r--src/com/dsht/kerneltweaker/fragments/CpuSchedulerPreferenceFragment.java216
-rw-r--r--src/com/dsht/kerneltweaker/fragments/CpuquietGovernorPreferenceFragment.java223
-rw-r--r--src/com/dsht/kerneltweaker/fragments/CustomRecoveryCommandFragment.java477
-rw-r--r--src/com/dsht/kerneltweaker/fragments/DialogCreatable.java29
-rw-r--r--src/com/dsht/kerneltweaker/fragments/FileManagerFragment.java203
-rw-r--r--src/com/dsht/kerneltweaker/fragments/GpuPreferenceFragment.java302
-rw-r--r--src/com/dsht/kerneltweaker/fragments/InitD.java346
-rw-r--r--src/com/dsht/kerneltweaker/fragments/KernelPreferenceFragment.java944
-rw-r--r--src/com/dsht/kerneltweaker/fragments/LowMemoryKillerFragment.java214
-rw-r--r--src/com/dsht/kerneltweaker/fragments/PropModder.java487
-rw-r--r--src/com/dsht/kerneltweaker/fragments/ReviewBootPreferenceFragment.java523
-rw-r--r--src/com/dsht/kerneltweaker/fragments/UvPreferenceFragment.java466
-rw-r--r--src/com/dsht/kerneltweaker/fragments/WallpaperEffectsFragment.java138
-rwxr-xr-xsrc/com/dsht/kernetweaker/cmdprocessor/AbstractAsyncSuCMDProcessor.java104
-rwxr-xr-xsrc/com/dsht/kernetweaker/cmdprocessor/CMDProcessor.java163
-rwxr-xr-xsrc/com/dsht/kernetweaker/cmdprocessor/ChildProcess.java144
-rwxr-xr-xsrc/com/dsht/kernetweaker/cmdprocessor/CommandResult.java168
-rwxr-xr-xsrc/com/dsht/kernetweaker/cmdprocessor/Executable.java142
-rwxr-xr-xsrc/com/dsht/open/CPUInfo.java134
-rwxr-xr-xsrc/com/dsht/open/CPUStateMonitor.java153
-rwxr-xr-xsrc/com/dsht/open/Constants.java225
-rwxr-xr-xsrc/com/dsht/open/PCSettings.java72
-rwxr-xr-xsrc/com/dsht/open/TimeInState.java399
-rwxr-xr-xsrc/com/dsht/open/VM.java351
-rw-r--r--src/com/dsht/settings/SettingsFragment.java322
-rw-r--r--src/com/dsht/settings/infos.java129
-rwxr-xr-xsrc/com/mobeta/android/dslv/DragSortController.java468
-rwxr-xr-xsrc/com/mobeta/android/dslv/DragSortCursorAdapter.java242
-rwxr-xr-xsrc/com/mobeta/android/dslv/DragSortItemView.java99
-rwxr-xr-xsrc/com/mobeta/android/dslv/DragSortItemViewCheckable.java50
-rwxr-xr-xsrc/com/mobeta/android/dslv/DragSortListView.java3075
-rwxr-xr-xsrc/com/mobeta/android/dslv/ResourceDragSortCursorAdapter.java133
-rwxr-xr-xsrc/com/mobeta/android/dslv/SimpleDragSortCursorAdapter.java422
-rwxr-xr-xsrc/com/mobeta/android/dslv/SimpleFloatViewManager.java88
-rwxr-xr-xsrc/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerDialog.java208
-rwxr-xr-xsrc/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerPalette.java193
-rwxr-xr-xsrc/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerPreference.java192
-rwxr-xr-xsrc/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerSwatch.java85
-rwxr-xr-xsrc/it/gmariotti/android/example/colorpicker/calendarstock/ColorStateDrawable.java76
-rwxr-xr-xsrc/it/gmariotti/android/example/colorpicker/calendarstock/Utils.java153
410 files changed, 26037 insertions, 0 deletions
diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..087d2a9
--- /dev/null
+++ b/.DS_Store
Binary files differ
diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..f70415c
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+ <classpathentry exported="true" kind="lib" path="/Users/francesco/sdk/extras/android/support/v4/android-support-v4.jar"/>
+ <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+ <classpathentry exported="true" kind="lib" path="/Users/francesco/sdk/build-tools/android-4.4/renderscript/lib/renderscript-v8.jar"/>
+ <classpathentry exported="true" kind="lib" path="/Users/francesco/Documents/lib/RootTools-3.3.jar"/>
+ <classpathentry exported="true" kind="lib" path="/Users/francesco/Documents/lib/GoogleAnalyticsServicesAndroid_3.01/libGoogleAnalyticsServices.jar"/>
+ <classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e660fd9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+bin/
diff --git a/.project b/.project
new file mode 100644
index 0000000..fa58f46
--- /dev/null
+++ b/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>KernelTweaker</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..596f775
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.dsht.kerneltweaker"
+ android:versionCode="18"
+ android:versionName="1.2.10.0" >
+
+ <uses-sdk
+ android:minSdkVersion="16"
+ android:targetSdkVersion="19" />
+
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.SET_WALLPAPER"/>
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.dsht.kerneltweaker.MainActivity"
+ android:label="@string/app_name"
+ android:screenOrientation="portrait" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <receiver android:name="com.dsht.kerneltweaker.Startup" >
+ <intent-filter android:priority="100" >
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ </intent-filter>
+ </receiver>
+ </application>
+
+</manifest> \ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..ef7e7ef
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,674 @@
+GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ {one line to give the program's name and a brief idea of what it does.}
+ Copyright (C) {year} {name of author}
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ {project} Copyright (C) {year} {fullname}
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/README.md
diff --git a/assets/09cron b/assets/09cron
new file mode 100644
index 0000000..42c3386
--- /dev/null
+++ b/assets/09cron
@@ -0,0 +1,73 @@
+#!/system/bin/sh
+: '
+ ============ Copyright (C) 2010 Jared Rummler (JRummy16) ============
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ =====================================================================
+'
+
+#############
+# FUNCTIONS #
+#############
+
+symlink_system_bin() {
+ # crond has "/bin/sh" hardcoded
+ if busybox [ ! -h /bin ]
+ then
+ mount -o remount,rw rootfs /
+ busybox ln -s /system/bin /bin
+ mount -o remount,ro rootfs /
+ fi
+}
+
+export_timezone() {
+ # set timezone (if you're not between -0500 and -0800 you get PST)
+ # todo - support other timezones
+ timezone=`date +%z`
+ if busybox [ $timezone = "-0800" ]; then
+ TZ=PST8PDT
+ elif busybox [ $timezone = "-0700" ]; then
+ TZ=MST7MDT
+ elif busybox [ $timezone = "-0600" ]; then
+ TZ=CST6CDT
+ elif busybox [ $timezone = "-0500" ]; then
+ TZ=EST5EDT
+ else
+ TZ=PST8PDT
+ fi
+ export TZ
+}
+
+set_crontab() {
+ # use /data/cron, call the crontab file "root"
+ if busybox [ -e /data/cron/root ]
+ then
+ mkdir -p /data/cron
+ cat > /data/cron/root << EOF
+01 * * * * busybox run-parts /system/etc/cron/cron.hourly
+02 4 * * * busybox run-parts /system/etc/cron/cron.daily
+22 4 * * 0 busybox run-parts /system/etc/cron/cron.weekly
+EOF
+ fi
+ busybox crond -c /data/cron
+}
+
+########
+# MAIN #
+########
+
+symlink_system_bin
+export_timezone
+set_crontab
diff --git a/assets/98tweaks b/assets/98tweaks
new file mode 100644
index 0000000..a3298eb
--- /dev/null
+++ b/assets/98tweaks
@@ -0,0 +1,5 @@
+#!/system/bin/sh
+
+busybox mount -o remount,noatime,barrier=0,nobh /system
+busybox mount -o remount,noatime /data
+busybox mount -o remount,noatime,barrier=0,nobh /cache \ No newline at end of file
diff --git a/assets/fix_permissions b/assets/fix_permissions
new file mode 100755
index 0000000..f2571ff
--- /dev/null
+++ b/assets/fix_permissions
@@ -0,0 +1,160 @@
+#
+#
+sysrw() {
+busybox mount -o remount,rw /system
+}
+sysro() {
+busybox mount -o remount,ro /system
+}
+
+get_runtime() {
+starttime=$1
+stoptime=$2
+runtime=`busybox expr $stoptime - $starttime`
+hours=`busybox expr $runtime / 3600`
+remainder=`busybox expr $runtime % 3600`
+mins=`busybox expr $remainder / 60`
+secs=`busybox expr $remainder % 60`
+busybox printf "%02d:%02d:%02d\n" "$hours" "$mins" "$secs"
+}
+
+fp_print(){
+ MSG="$*";
+ if [ $LOGGING -eq 1 ]; then
+ busybox echo "$MSG" >> $LOG_FILE;
+ fi
+}
+
+set_package_permission() {
+ packagename=$1
+ apk_path=$2
+ packageuid=`busybox grep $apk_path /data/system/packages.xml | busybox sed 's%.*serId="\(.*\)".*%\1%' | busybox cut -d '"' -f1 `
+ data_path=/data/data/$packagename
+
+ if busybox [ -e $apk_path ]; then
+
+ appdir=`busybox dirname $apk_path `
+
+ if busybox [ $appdir == /system/app ]; then
+ busybox chown 0 $apk_path
+ busybox chown :0 $apk_path
+ busybox chmod 644 $apk_path
+ fp_print "${apk_path}:0:0:rw-r--r--";
+
+ elif busybox [ $appdir == /data/app ]; then
+ busybox chown 1000 $apk_path
+ busybox chown :1000 $apk_path
+ busybox chmod 644 $apk_path
+ fp_print "${apk_path}:1000:1000:rw-r--r--";
+
+ elif busybox [ $appdir == /sd-ext/app ]; then
+ busybox chown 1000 $apk_path
+ busybox chown :1000 $apk_path
+ busybox chmod 644 $apk_path
+ fp_print "${apk_path}:1000:1000:rw-r--r--";
+
+ elif busybox [ $appdir == /data/app-private ]; then
+ busybox chown 1000 $apk_path
+ busybox chown :$packageuid $apk_path
+ busybox chmod 640 $apk_path
+ fp_print "${apk_path}:1000:${packageuid}:rw-r-----";
+
+ elif busybox [ $appdir == /sd-ext/app-private ]; then
+ busybox chown 1000 $apk_path
+ busybox chown :$packageuid $apk_path
+ busybox chmod 640 $apk_path
+ fp_print "${apk_path}:1000:${packageuid}:rw-r-----";
+ fi
+
+ if busybox [ -d $data_path ]; then
+
+ busybox chmod 755 $data_path
+ busybox chown $packageuid $data_path
+ busybox chown :$packageuid $data_path
+ fp_print "${data_path}:${packageuid}:${packageuid}:rwxr-xr-x";
+ dirs=`busybox find $data_path -mindepth 1 -type d `
+
+ for file in $dirs; do
+ perm=755
+ newuid=$packageuid
+ newgid=$packageuid
+ fname=`busybox basename $file `
+ case $fname in
+ lib)
+ busybox chmod 755 $file
+ newuid=1000
+ newgid=1000
+ perm=755
+ ;;
+ shared_prefs)
+ busybox chmod 771 $file
+ perm=660
+ ;;
+ databases)
+ busybox chmod 771 $file
+ perm=660
+ ;;
+ cache)
+ busybox chmod 771 $file
+ perm=600
+ ;;
+ *)
+ busybox chmod 771 $file
+ perm=771
+ ;;
+ esac
+
+ busybox chown $newuid $file
+ busybox chown :$newgid $file
+
+ busybox find $file -type f -maxdepth 1 ! -perm $perm -exec busybox chmod $perm {} ';'
+ busybox find $file -type f -maxdepth 1 ! -user $newuid -exec busybox chown $newuid {} ';'
+ busybox find $file -type f -maxdepth 1 ! -group $newgid -exec busybox chown :$newgid {} ';'
+
+ done
+ fi
+ fi
+}
+
+fp_all() {
+ starttime=`busybox date +%s `
+ packages=`pm list packages -f | busybox cut -d: -f2 `
+
+ fp_print "Fixing permissions start at $FPSTART";
+
+ sysrw
+
+ for package in $packages; do
+ packagename=`echo $package | busybox cut -d '=' -f2 `
+ apk_path=`echo $package | busybox cut -d '=' -f1 `
+ set_package_permission $packagename $apk_path
+ done
+
+ sysro
+ sync
+
+ stoptime=`busybox date +%s `
+ runtime=`get_runtime $starttime $stoptime `
+
+ fp_print "Fix permissions complete! Runtime: ${runtime}";
+
+}
+FPSTART=$( busybox date +"%m-%d-%Y %H:%M:%S" );
+SD=`busybox mount | busybox egrep -v "asec|android_secure|external_sd|sdcard1" | busybox egrep -i "(sdcard|sdcard0)" | busybox awk '{print $3}'`;
+if [ "$SD" == "" ]; then
+ LOG_FILE="/data/fix_permissions.log"
+else
+ LOG_FILE="$SD/fix_permissions.log"
+fi
+busybox rm -f "$LOG_FILE";
+
+arg=$1;
+if [ "$arg" == "-l" ]; then
+ LOGGING=1;
+else
+ LOGGING=0;
+fi;
+if [ $LOGGING -eq 1 ]; then
+ busybox touch "$LOG_FILE";
+fi
+fp_all; \ No newline at end of file
diff --git a/assets/helpers.sh b/assets/helpers.sh
new file mode 100644
index 0000000..8ac1440
--- /dev/null
+++ b/assets/helpers.sh
@@ -0,0 +1,612 @@
+#!/system/bin/sh
+: '
+ ============ Copyright (C) 2010 Jared Rummler (JRummy16) ============
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ =====================================================================
+'
+
+: ' =========================================================
+ function name: sysrw
+ parameters: void
+ returns: void
+ description:
+ Mounts system read/write
+============================================================= '
+sysrw() {
+ busybox mount -o remount,rw /system
+}
+
+: ' =========================================================
+ function name: sysro
+ parameters: void
+ returns: void
+ description:
+ Mounts system read-only
+============================================================= '
+sysro() {
+ busybox mount -o remount,ro /system
+}
+
+: ' =========================================================
+ function name: get_system_reboot
+ parameters: void
+ returns: void
+ description:
+ Performs a system reboot
+============================================================= '
+get_system_reboot() {
+ am start -a android.intent.action.REBOOT
+}
+
+: ' =========================================================
+ function name: get_reboot
+ parameters: void
+ returns: void
+ description:
+ Performs a system reboot
+============================================================= '
+get_reboot() {
+ reboot
+}
+
+: ' =========================================================
+ function name: get_fast_reboot
+ parameters: void
+ returns: void
+ description:
+ Restarts the system
+============================================================= '
+get_fast_reboot() {
+ busybox killall system_server
+}
+
+: ' =========================================================
+ function name: get_shutdown
+ parameters: void
+ returns: void
+ description:
+ Shutdown the system
+============================================================= '
+get_shutdown() {
+ reboot -p
+}
+
+: ' =========================================================
+ function name: get_reboot_recovery
+ parameters: void
+ returns: void
+ description:
+ Reboots into recovery
+============================================================= '
+get_reboot_recovery() {
+ reboot recovery
+}
+
+: ' =========================================================
+ function name: get_system_mount
+ parameters: void
+ returns:
+ "rw": if system is mounted read/write
+ "ro": if system is mounted read-only
+ description:
+ Returns the current system mount
+============================================================= '
+get_system_mount() {
+ mount | busybox grep /system | busybox awk '{print $4}' | busybox cut -d ',' -f1
+}
+
+: ' =========================================================
+ function name: is_busybox_installed
+ parameters: void
+ returns: 0 if busybox is installed, 1 if not installed
+ description:
+ Checks if busybox is installed
+============================================================= '
+is_busybox_installed() {
+ if ! busybox > /dev/null 2>&1; then
+ return 1
+ fi
+ return 0
+}
+
+: ' =========================================================
+ function name: is_busybox_applet_available
+ parameters:
+ $1: name of the applet
+ returns: 0 if applet is available, 1 otherwise
+ description:
+ Checks if busybox contains a certain applet
+============================================================= '
+is_busybox_applet_available() {
+ applet=$1
+ applets=` busybox --list `
+ exit_code=$?
+ if busybox [ $exit_code -eq 0 ]
+ then
+ for i in $applets
+ do
+ if busybox [ $applet == $i ]
+ then
+ return 0
+ fi
+ done
+ fi
+ return 1
+}
+
+: ' =========================================================
+ function name:
+ parameters:
+ $1: binary name
+ returns: 0 if the binary is installed, 1 if not installed
+ description:
+ Checks if a binary is installed to the system
+============================================================= '
+is_binary_installed() {
+ if busybox [ $# -ne 1 ]; then
+ return 1
+ fi
+
+ binary=$1
+ busybox which $binary > /dev/nul 2>&1
+ return $?
+}
+
+: ' =========================================================
+ function name: is_running_as_root
+ parameters: void
+ returns: 0 if true, 1 if false
+ description:
+ Checks if the current script is being run as root
+============================================================= '
+is_running_as_root() {
+ if busybox [ $( busybox id -u ) -ne 0 ]; then
+ return 1
+ fi
+ return 0
+}
+
+: ' =========================================================
+ function name: is_rooted
+ parameters: void
+ returns: 0 if true, 1 if false
+ description:
+ Checks if the device has root access
+============================================================= '
+is_rooted() {
+ if ! su -c 'id > /dev/nul 2>&1'; then
+ return 1
+ fi
+ return 0
+}
+
+: ' =========================================================
+ function name: is_process_running
+ parameters:
+ $1: name of the proccess
+ returns: 0 if true, 1 if false
+ description:
+ Checks if a process is currently running
+============================================================= '
+is_process_running() {
+ if busybox [ $# -ne 1 ]; then
+ return 1
+ fi
+
+ process_name=$1
+ busybox pidof $process_name > /dev/nul 2>&1
+ return $?
+}
+
+: ' =========================================================
+ function name: is_sd_present
+ parameters: void
+ returns: 0 if true, 1 if false
+ description:
+ Checks if the sdcard is mounted
+============================================================= '
+is_sd_present() {
+ if busybox [ -z "$( busybox mount | busybox grep /sdcard )" ]; then
+ return 1
+ fi
+ return 0
+}
+
+: ' =========================================================
+ function name: open_website
+ parameters:
+ $1: the url to open
+ returns: void
+ description:
+ Opens a url with the default browser
+============================================================= '
+open_website() {
+ url=$1
+ case $url in
+ http*)
+ am start ${url}
+ ;;
+ *)
+ url="http://${url}"
+ am start ${url}
+ ;;
+ esac
+}
+
+: ' =========================================================
+ function name: view_file
+ parameters:
+ $1: path to the file
+ returns: void
+ description:
+ Opens an activity chooser to view a file
+============================================================= '
+view_file() {
+ path=$1
+ am start -a android.intent.action.VIEW -t "text/*" -d "file://${path}"
+}
+
+: ' =========================================================
+ function name: send_email
+ parameters:
+ $1: email address
+ $2: subject
+ $3: email body
+ returns: void
+ description:
+ Opens the default email app to send an email
+============================================================= '
+send_email() {
+ email_address=$1
+ subject=$2
+ message=$3
+ am start -a android.intent.action.SENDTO -d mailto:"${email_address}" \
+ --es android.intent.extra.SUBJECT "${subject}" \
+ --es android.intent.extra.TEXT "${message}"
+}
+
+: ' =========================================================
+ function name: get_installed_packages
+ parameters:
+ $1: (--filter_system|--filter_data|--filter_sd)
+ Filter apps on system, data or sdcard
+ $2: (--get_package_path)
+ Return the code path instead of the package names
+ returns: void
+ description:
+ Gets a list of installed packages
+============================================================= '
+get_installed_packages() {
+ get_package_path=false
+ filter=""
+
+ for i in $@; do
+ case $i in
+ --filter_system)
+ filter="/system/"
+ ;;
+ --filter_data)
+ filter="/data/app"
+ ;;
+ --filter_sd)
+ filter="/mnt/"
+ ;;
+ --get_package_path)
+ get_package_path=true
+ ;;
+ esac
+ done
+
+ if $get_package_path
+ then
+ pm list packages -f \
+ | busybox grep "${filter}" \
+ | busybox cut -d: -f2 \
+ | busybox cut -d= -f1 \
+ | busybox sort
+ else
+ pm list packages -f \
+ | busybox grep "${filter}" \
+ | busybox cut -d: -f2 \
+ | busybox cut -d= -f2 \
+ | busybox sort
+ fi
+}
+
+: ' =========================================================
+ function name: installApks
+ parameters:
+ $1: "-r" search all sub directories for apks, or...
+ path to directory
+ $2: path to directory (if recursize)
+ returns: void
+ description:
+ Installs apks to device using package manager
+============================================================= '
+install_apks() {
+ installer_package_name="com.android.vending"
+ recursive=false
+ case $1 in
+ -r|--recursive)
+ recursive=true
+ shift;
+ ;;
+ esac
+
+ apks_dir=${1:-$EXTERNAL_STORAGE}
+
+ if busybox [ -d $apks_dir ]; then
+ if $recursive
+ then
+ apks=` busybox find $apks_dir -type f -name *.apk -print `
+ else
+ apks=` ls $apks_dir/*.apk `
+ fi
+
+ for apk in $apks; do
+ pm install -i $installer_package_name -r $apk
+ done
+ fi
+}
+
+: ' =========================================================
+ function name: set_prop
+ parameters:
+ $1: property key
+ $2: property value
+ $3: path to .prop file to modify
+ returns: 0 for success, 1 for failure
+ description:
+ Set a system property. Reboot may be necessary for
+ changes to take affect.
+============================================================= '
+set_prop() {
+ prop_key=$1
+ prop_value=$2
+ prop_file=${3:-/system/build.prop}
+ seperator="="
+ exit_status=1
+
+ setprop $prop_key $prop_value
+
+ if busybox [ -e $prop_file ]
+ then
+ prop_line=` busybox grep -m 1 $prop_key $prop_file `
+ if busybox [ -n "${prop_line}" ]
+ then
+ if busybox [ -n "$( echo $prop_line | busybox grep ' = ' )" ]
+ then
+ seperator=" = "
+ fi
+ sysrw
+ busybox sed -i "s|${prop_key}${seperator}.*|${prop_key}${seperator}${prop_value}|g" $prop_file
+ exit_status=$?
+ sysro
+ fi
+ fi
+
+ return $exit_status
+}
+
+: ' =========================================================
+ function name: get_runtime
+ parameters:
+ $1: start time of the process
+ $2: end time of the process
+ returns:
+ The time it took for the process to complete
+ format: HH:mm:ss
+ description:
+ Gets the runtime for a given process
+============================================================= '
+get_runtime() {
+ starttime=$1
+ stoptime=$2
+ runtime=` busybox expr $stoptime - $starttime`
+ hours=` busybox expr $runtime / 3600`
+ remainder=` busybox expr $runtime % 3600`
+ mins=` busybox expr $remainder / 60`
+ secs=` busybox expr $remainder % 60`
+ busybox printf "%02d:%02d:%02d\n" "$hours" "$mins" "$secs"
+}
+
+: ' =========================================================
+ function name: zipalign_apk
+ parameters:
+ $1: path to the apk file
+ returns: void
+ description:
+ zipaligns an apk file if needed
+============================================================= '
+zipalign_apk() {
+ apk=$1
+ if busybox [ -e $apk ]; then
+ zipalign -c 4 $apk
+ exit_status=$?
+ case $exit_status in
+ 0)
+ echo "[!] ${apk} is already zipaligned"
+ ;;
+ *)
+ if zipalign -f 4 $apk /data/local/pkg.apk
+ then
+ busybox cp -f /data/local/pkg.apk $apk
+ busybox rm -f /data/local/pkg.apk
+ echo "[X] Zipaligned ${apk}"
+ fi
+ ;;
+ esac
+ fi
+}
+
+: ' =========================================================
+ function name: zipalign_apks
+ parameters: void
+ returns: void
+ description:
+ zipaligns all installed apks
+============================================================= '
+zipalign_apks() {
+ if ! is_binary_installed zipalign
+ then
+ echo "Error: zipalign binary missing."
+ return
+ fi
+
+ starttime=` busybox date +%s `
+ apks=` get_installed_packages --get_package_path `
+
+ echo
+ echo "Zipaligning..."
+ echo
+
+ sysrw
+
+ for apk in $apks; do
+ zipalign_apk $apk
+ done
+
+ sysro
+ sync
+
+ stoptime=` busybox date +%s `
+ runtime=` get_runtime $starttime $stoptime `
+
+ echo
+ echo "Zipalign complete! Runtime: ${runtime}"
+ echo
+}
+
+: ' =========================================================
+ function name: set_package_permission
+ parameters:
+ $1: package name
+ $2: package code path
+ returns: void
+ description:
+ Fixes permission on a package
+============================================================= '
+set_package_permission() {
+
+ packagename=$1
+ apk_path=$2
+ packageuid=` busybox grep $apk_path /data/system/packages.xml | busybox sed 's%.*serId="\(.*\)".*%\1%' | busybox cut -d '"' -f1 `
+ data_path=/data/data/$packagename
+
+ if busybox [ -e $apk_path ]; then
+
+ echo "Setting permissions for ${packagename} ..."
+ appdir=` busybox dirname $apk_path `
+
+ if busybox [ $appdir == /system/app ]; then
+ busybox chown 0 $apk_path
+ busybox chown :0 $apk_path
+ busybox chmod 644 $apk_path
+ elif busybox [ $appdir == /data/app ]; then
+ busybox chown 1000 $apk_path
+ busybox chown :1000 $apk_path
+ busybox chmod 644 $apk_path
+ elif busybox [ $appdir == /data/app-private ]; then
+ busybox chown 1000 $apk_path
+ busybox chown :$packageuid $apk_path
+ busybox chmod 640 $apk_path
+ fi
+
+ if busybox [ -d $data_path ]; then
+
+ busybox chmod 755 $data_path
+ busybox chown $packageuid $data_path
+ busybox chown :$packageuid $data_path
+
+ dirs=` busybox find $data_path -mindepth 1 -type d `
+
+ for file in $dirs; do
+
+ perm=755
+ newuid=$packageuid
+ newgid=$packageuid
+ fname=` busybox basename $file `
+
+ case $fname in
+ lib)
+ busybox chmod 755 $file
+ newuid=1000
+ newgid=1000
+ perm=755
+ ;;
+ shared_prefs)
+ busybox chmod 771 $file
+ perm=660
+ ;;
+ databases)
+ busybox chmod 771 $file
+ perm=660
+ ;;
+ cache)
+ busybox chmod 771 $file
+ perm=600
+ ;;
+ *)
+ busybox chmod 771 $file
+ perm=771
+ ;;
+ esac
+
+ busybox chown $newuid $file
+ busybox chown :$newgid $file
+
+ busybox find $file -type f -maxdepth 1 ! -perm $perm -exec busybox chmod $perm {} ';'
+ busybox find $file -type f -maxdepth 1 ! -user $newuid -exec busybox chown $newuid {} ';'
+ busybox find $file -type f -maxdepth 1 ! -group $newgid -exec busybox chown :$newgid {} ';'
+
+ done
+ fi
+ fi
+}
+
+: ' =========================================================
+ function name: fix_permissions
+ parameters: void
+ returns: void
+ description:
+ Fixes permissions for all installed packages
+============================================================= '
+fix_permissions() {
+ starttime=` busybox date +%s `
+ packages=` pm list packages -f | busybox cut -d: -f2 `
+
+ echo
+ echo "Fixing permissions..."
+ echo
+
+ sysrw
+
+ for package in $packages; do
+ packagename=` echo $package | busybox cut -d '=' -f2 `
+ apk_path=` echo $package | busybox cut -d '=' -f1 `
+ set_package_permission $packagename $apk_path
+ done
+
+ sysro
+ sync
+
+ stoptime=` busybox date +%s `
+ runtime=` get_runtime $starttime $stoptime `
+ echo
+ echo
+ echo "Fix permissions complete! Runtime: ${runtime}"
+ echo
+}
diff --git a/assets/sql_optimize b/assets/sql_optimize
new file mode 100755
index 0000000..2997c21
--- /dev/null
+++ b/assets/sql_optimize
@@ -0,0 +1,43 @@
+#
+#
+function optimize(){
+sql3=`busybox which sqlite3`;
+db=0;
+for i in `busybox find /data -iname "*.db"`; do
+ $sql3 $i 'VACUUM;';
+ db=`busybox expr $db + 1`;
+done;
+if [ -d "/dbdata" ]; then
+ for i in `busybox find /dbdata -iname "*.db"`; do
+ $sql3 $i 'VACUUM;';
+ db=`busybox expr $db + 1`;
+ done;
+fi;
+if [ -d "/system" ]; then
+ for i in `busybox find /system -iname "*.db"`; do
+ $sql3 $i 'VACUUM;';
+ db=`busybox expr $db + 1`;
+ done;
+fi;
+if [ -d "/datadata" ]; then
+ for i in `busybox find /datadata -iname "*.db"`; do
+ $sql3 $i 'VACUUM;';
+ db=`busybox expr $db + 1`;
+ done;
+fi;
+
+SD=`busybox mount | busybox egrep -v "asec|android_secure" | busybox egrep -i "(sdcard|sdcard0|external_sd|sdcard1)" | busybox awk '{print $3}' `;
+
+for d in $SD; do
+for i in `busybox find $d -iname "*.db"`; do
+ $sql3 $i 'VACUUM;';
+ db=`busybox expr $db + 1`;
+done;
+done;
+busybox echo $db;
+}
+
+#optimize 2>&1 >> /sdcard/sql.log
+optimize;
+
+
diff --git a/assets/sqlite3 b/assets/sqlite3
new file mode 100755
index 0000000..f352d13
--- /dev/null
+++ b/assets/sqlite3
Binary files differ
diff --git a/assets/utils b/assets/utils
new file mode 100755
index 0000000..711f2d4
--- /dev/null
+++ b/assets/utils
@@ -0,0 +1,44 @@
+#
+####### made by h0rn3t #######
+#
+count_files(){
+if [ "X$2" == "X" ]; then
+ ext="*";
+else
+ ext="$2";
+fi;
+r="";
+for d in $1; do
+ if [ -d $d ]; then
+ i=$( busybox find $d -type f -name "$ext" | busybox wc -l );
+ else
+ i=0;
+ fi;
+ if [ "X$r" == "X" ]; then
+ r="$i";
+ else
+ r="$r:$i";
+ fi;
+done;
+echo "$r";
+}
+arg=$1;
+if [ "$arg" == "-count" ]; then
+ count_files "$DIRS";
+elif [ "$arg" == "-govprop" ]; then
+ r="";
+ gov=$2;
+ if [ "X$gov" == "X" ]; then
+ echo "";
+ exit;
+ fi;
+ for f in $(busybox find /sys/devices/system/cpu/cpufreq/$gov/* -type f -prune -perm -644); do
+ v=$(busybox cat $f);
+ if [ "X$r" == "X" ]; then
+ r="$f:$v";
+ else
+ r="$r;$f:$v";
+ fi;
+ done;
+ echo "$r";
+fi; \ No newline at end of file
diff --git a/assets/zip b/assets/zip
new file mode 100644
index 0000000..8cdfb36
--- /dev/null
+++ b/assets/zip
Binary files differ
diff --git a/assets/zipalign b/assets/zipalign
new file mode 100644
index 0000000..47e41c1
--- /dev/null
+++ b/assets/zipalign
Binary files differ
diff --git a/gen/com/dsht/kerneltweaker/BuildConfig.java b/gen/com/dsht/kerneltweaker/BuildConfig.java
new file mode 100644
index 0000000..15d48bc
--- /dev/null
+++ b/gen/com/dsht/kerneltweaker/BuildConfig.java
@@ -0,0 +1,6 @@
+/** Automatically generated file. DO NOT MODIFY */
+package com.dsht.kerneltweaker;
+
+public final class BuildConfig {
+ public final static boolean DEBUG = true;
+} \ No newline at end of file
diff --git a/gen/com/dsht/kerneltweaker/R.java b/gen/com/dsht/kerneltweaker/R.java
new file mode 100644
index 0000000..a10d476
--- /dev/null
+++ b/gen/com/dsht/kerneltweaker/R.java
@@ -0,0 +1,1834 @@
+/* AUTO-GENERATED FILE. DO NOT MODIFY.
+ *
+ * This class was automatically generated by the
+ * aapt tool from the resource data it found. It
+ * should not be modified by hand.
+ */
+
+package com.dsht.kerneltweaker;
+
+public final class R {
+ public static final class anim {
+ public static final int card_flip_left_in=0x7f040000;
+ public static final int card_flip_right_out=0x7f040001;
+ public static final int push_right_in=0x7f040002;
+ public static final int push_right_out=0x7f040003;
+ }
+ public static final class array {
+ public static final int batt_status=0x7f0a0023;
+ public static final int default_color_choice_values=0x7f0a0000;
+ public static final int entries_fast_up=0x7f0a002a;
+ public static final int entries_fast_up_explain=0x7f0a0029;
+ public static final int entries_lcd_density=0x7f0a0025;
+ public static final int entries_max_events=0x7f0a0026;
+ public static final int entries_prox_delay=0x7f0a002c;
+ public static final int entries_prox_delay_explain=0x7f0a002b;
+ public static final int entries_ring_delay=0x7f0a0027;
+ public static final int entries_sleep=0x7f0a002e;
+ public static final int entries_sleep_explain=0x7f0a002d;
+ public static final int entries_vm_heapsize=0x7f0a0028;
+ /** PropModder
+ */
+ public static final int entries_wifi_scan=0x7f0a0024;
+ public static final int flash_dialog=0x7f0a0005;
+ public static final int glo_conservative_descs=0x7f0a0012;
+ public static final int glo_conservative_titles=0x7f0a0011;
+ public static final int glo_cpu_descs=0x7f0a000a;
+ public static final int glo_cpu_titles=0x7f0a0009;
+ public static final int glo_gov_descs=0x7f0a000c;
+ public static final int glo_gov_titles=0x7f0a000b;
+ public static final int glo_gpu_descs=0x7f0a0014;
+ public static final int glo_gpu_titles=0x7f0a0013;
+ public static final int glo_interactive_descs=0x7f0a0010;
+ public static final int glo_interactive_titles=0x7f0a000f;
+ public static final int glo_kernel_descs=0x7f0a0019;
+ public static final int glo_kernel_titles=0x7f0a0017;
+ public static final int glo_lmk_descs=0x7f0a0021;
+ public static final int glo_lmk_titles=0x7f0a0020;
+ public static final int glo_ondemand_descs=0x7f0a000e;
+ public static final int glo_ondemand_titles=0x7f0a000d;
+ public static final int glo_sched_descs=0x7f0a001b;
+ public static final int glo_sched_titles=0x7f0a001a;
+ public static final int glo_tcp_descs=0x7f0a001d;
+ public static final int glo_tcp_titles=0x7f0a001c;
+ public static final int glo_uv_descs=0x7f0a0016;
+ public static final int glo_uv_titles=0x7f0a0015;
+ public static final int glo_vm_descs=0x7f0a001f;
+ public static final int glo_vm_titles=0x7f0a001e;
+ public static final int homescreen_color_choice_values=0x7f0a0001;
+ public static final int install_image_dialog=0x7f0a0006;
+ public static final int lmk_descs=0x7f0a0008;
+ public static final int lmk_titles=0x7f0a0007;
+ public static final int menu_colors=0x7f0a0004;
+ public static final int menu_descs=0x7f0a0003;
+ public static final int menu_entries=0x7f0a0002;
+ public static final int pie_colors=0x7f0a0018;
+ public static final int residual_info=0x7f0a0022;
+ }
+ public static final class attr {
+ /** <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int behindOffset=0x7f010003;
+ /** <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int behindScrollScale=0x7f010005;
+ /** <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int behindWidth=0x7f010004;
+ /** <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ */
+ public static final int cal_choices=0x7f010011;
+ /** <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ */
+ public static final int cal_itemLayout=0x7f010010;
+ /** <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int cal_numColumns=0x7f010012;
+ /** <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int cb_color=0x7f01000e;
+ /** <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int cb_pressed_ring_width=0x7f01000f;
+ /** <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int click_remove_id=0x7f010023;
+ /** <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int collapsed_height=0x7f010013;
+ /** <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int drag_enabled=0x7f01001d;
+ /** <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int drag_handle_id=0x7f010021;
+ /** <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int drag_scroll_start=0x7f010014;
+ /** <p>Must be one of the following constant values.</p>
+<table>
+<colgroup align="left" />
+<colgroup align="left" />
+<colgroup align="left" />
+<tr><th>Constant</th><th>Value</th><th>Description</th></tr>
+<tr><td><code>onDown</code></td><td>0</td><td></td></tr>
+<tr><td><code>onMove</code></td><td>1</td><td></td></tr>
+<tr><td><code>onLongPress</code></td><td>2</td><td></td></tr>
+</table>
+ */
+ public static final int drag_start_mode=0x7f010020;
+ /** <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int drop_animation_duration=0x7f01001c;
+ /** <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int fadeDegree=0x7f01000b;
+ /** <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int fadeEnabled=0x7f01000a;
+ /** <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int fling_handle_id=0x7f010022;
+ /** <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int float_alpha=0x7f010019;
+ /** <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int float_background_color=0x7f010016;
+ /** <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int max_drag_scroll_speed=0x7f010015;
+ /** <p>Must be one of the following constant values.</p>
+<table>
+<colgroup align="left" />
+<colgroup align="left" />
+<colgroup align="left" />
+<tr><th>Constant</th><th>Value</th><th>Description</th></tr>
+<tr><td><code>left</code></td><td>0</td><td></td></tr>
+<tr><td><code>right</code></td><td>1</td><td></td></tr>
+</table>
+ */
+ public static final int mode=0x7f010000;
+ /** <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int remove_animation_duration=0x7f01001b;
+ /** <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int remove_enabled=0x7f01001f;
+ /** <p>Must be one of the following constant values.</p>
+<table>
+<colgroup align="left" />
+<colgroup align="left" />
+<colgroup align="left" />
+<tr><th>Constant</th><th>Value</th><th>Description</th></tr>
+<tr><td><code>clickRemove</code></td><td>0</td><td></td></tr>
+<tr><td><code>flingRemove</code></td><td>1</td><td></td></tr>
+</table>
+ */
+ public static final int remove_mode=0x7f010017;
+ /** <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ */
+ public static final int selectorDrawable=0x7f01000d;
+ /** <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int selectorEnabled=0x7f01000c;
+ /** <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ */
+ public static final int shadowDrawable=0x7f010008;
+ /** <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int shadowWidth=0x7f010009;
+ /** <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int slide_shuffle_speed=0x7f01001a;
+ /** <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int sort_enabled=0x7f01001e;
+ /** <p>Must be one of the following constant values.</p>
+<table>
+<colgroup align="left" />
+<colgroup align="left" />
+<colgroup align="left" />
+<tr><th>Constant</th><th>Value</th><th>Description</th></tr>
+<tr><td><code>margin</code></td><td>0</td><td></td></tr>
+<tr><td><code>fullscreen</code></td><td>1</td><td></td></tr>
+</table>
+ */
+ public static final int touchModeAbove=0x7f010006;
+ /** <p>Must be one of the following constant values.</p>
+<table>
+<colgroup align="left" />
+<colgroup align="left" />
+<colgroup align="left" />
+<tr><th>Constant</th><th>Value</th><th>Description</th></tr>
+<tr><td><code>margin</code></td><td>0</td><td></td></tr>
+<tr><td><code>fullscreen</code></td><td>1</td><td></td></tr>
+</table>
+ */
+ public static final int touchModeBehind=0x7f010007;
+ /** <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int track_drag_sort=0x7f010018;
+ /** <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ */
+ public static final int use_default_controller=0x7f010024;
+ /** <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ */
+ public static final int viewAbove=0x7f010001;
+ /** <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ */
+ public static final int viewBehind=0x7f010002;
+ }
+ public static final class bool {
+ /** If false, user can't switch between menu_tabbed and menu_drawer mode
+ */
+ public static final int config_allow_toggle_tabbed=0x7f080005;
+ /** Whether or not the app is meant to be run as a system app,
+ bypassing the need of busybox/su
+ */
+ public static final int config_isSystemApp=0x7f080002;
+ /** Whether or not to only show performance-related options
+ */
+ public static final int config_showPerformanceOnly=0x7f080003;
+ /** If true, menu_tabbed view is used, else it uses the menu_drawer mode
+ */
+ public static final int config_use_tabbed=0x7f080004;
+ /** Enable automatic activity tracking
+ */
+ public static final int ga_autoActivityTracking=0x7f080000;
+ /** Enable automatic exception tracking
+ */
+ public static final int ga_reportUncaughtExceptions=0x7f080001;
+ }
+ public static final class color {
+ public static final int holo_white_normal=0x7f0b0003;
+ public static final int mca__holo_blue_light=0x7f0b0001;
+ public static final int mca__holo_blue_light_transparent=0x7f0b0002;
+ public static final int mca__list_item_bg_checked=0x7f0b0005;
+ public static final int mca__list_item_bg_normal=0x7f0b0004;
+ public static final int mca__list_item_bg_pressed=0x7f0b0006;
+ public static final int pressed_customapptheme=0x7f0b0000;
+ }
+ public static final class dimen {
+ /** Default screen margins, per the Android Design guidelines.
+
+ Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
+
+ */
+ public static final int activity_horizontal_margin=0x7f090004;
+ public static final int activity_vertical_margin=0x7f090005;
+ public static final int color_swatch_large=0x7f090000;
+ public static final int color_swatch_margins_large=0x7f090002;
+ public static final int color_swatch_margins_small=0x7f090003;
+ public static final int color_swatch_small=0x7f090001;
+ public static final int dessert_case_cell_size=0x7f090009;
+ public static final int list_padding=0x7f090007;
+ public static final int shadow_width=0x7f090008;
+ public static final int slidingmenu_offset=0x7f090006;
+ }
+ public static final class drawable {
+ public static final int ab_texture_tile=0x7f020000;
+ public static final int aokp=0x7f020001;
+ public static final int apptheme_btn_radio_holo_dark=0x7f020002;
+ public static final int apptheme_btn_radio_off_disabled_focused_holo_dark=0x7f020003;
+ public static final int apptheme_btn_radio_off_disabled_holo_dark=0x7f020004;
+ public static final int apptheme_btn_radio_off_focused_holo_dark=0x7f020005;
+ public static final int apptheme_btn_radio_off_holo_dark=0x7f020006;
+ public static final int apptheme_btn_radio_off_pressed_holo_dark=0x7f020007;
+ public static final int apptheme_btn_radio_on_disabled_focused_holo_dark=0x7f020008;
+ public static final int apptheme_btn_radio_on_disabled_holo_dark=0x7f020009;
+ public static final int apptheme_btn_radio_on_focused_holo_dark=0x7f02000a;
+ public static final int apptheme_btn_radio_on_holo_dark=0x7f02000b;
+ public static final int apptheme_btn_radio_on_pressed_holo_dark=0x7f02000c;
+ public static final int apptheme_edit_text_holo_dark=0x7f02000d;
+ public static final int apptheme_fastscroll_thumb_default_holo=0x7f02000e;
+ public static final int apptheme_fastscroll_thumb_holo=0x7f02000f;
+ public static final int apptheme_fastscroll_thumb_pressed_holo=0x7f020010;
+ public static final int apptheme_scrubber_control_disabled_holo=0x7f020011;
+ public static final int apptheme_scrubber_control_focused_holo=0x7f020012;
+ public static final int apptheme_scrubber_control_normal_holo=0x7f020013;
+ public static final int apptheme_scrubber_control_pressed_holo=0x7f020014;
+ public static final int apptheme_scrubber_control_selector_holo_dark=0x7f020015;
+ public static final int apptheme_scrubber_primary_holo=0x7f020016;
+ public static final int apptheme_scrubber_progress_horizontal_holo_dark=0x7f020017;
+ public static final int apptheme_scrubber_secondary_holo=0x7f020018;
+ public static final int apptheme_scrubber_track_holo_dark=0x7f020019;
+ public static final int apptheme_textfield_activated_holo_dark=0x7f02001a;
+ public static final int apptheme_textfield_default_holo_dark=0x7f02001b;
+ public static final int apptheme_textfield_disabled_focused_holo_dark=0x7f02001c;
+ public static final int apptheme_textfield_disabled_holo_dark=0x7f02001d;
+ public static final int apptheme_textfield_focused_holo_dark=0x7f02001e;
+ public static final int background_holo_dark=0x7f02001f;
+ public static final int background_holo_light=0x7f020020;
+ public static final int backup=0x7f020021;
+ public static final int bar_chart=0x7f020022;
+ public static final int battery_med=0x7f020023;
+ public static final int beaker=0x7f020024;
+ public static final int bg_dark=0x7f020025;
+ public static final int bg_light=0x7f020026;
+ public static final int bg_menu_dark=0x7f020027;
+ public static final int bg_menu_light=0x7f020028;
+ public static final int bg_stripes_dark=0x7f020029;
+ public static final int bg_stripes_dark_light=0x7f02002a;
+ public static final int bottombutton=0x7f02002b;
+ public static final int btn_radio_off_pressed_holo_light=0x7f02002c;
+ public static final int btn_radio_on_pressed_holo_light=0x7f02002d;
+ public static final int calendar_color_picker_swatch=0x7f02002e;
+ public static final int calendar_color_square=0x7f02002f;
+ public static final int card_bg=0x7f020030;
+ public static final int cesco=0x7f020031;
+ public static final int checkbox_selector=0x7f020032;
+ public static final int checkbox_selector_light=0x7f020033;
+ public static final int command=0x7f020034;
+ public static final int divider_horizontal_dark_opaque=0x7f020035;
+ public static final int divider_horizontal_holo_dark=0x7f020036;
+ public static final int divider_horizontal_holo_light=0x7f020037;
+ public static final int doc=0x7f020038;
+ public static final int doc_zip=0x7f020039;
+ public static final int dsht_logo=0x7f02003a;
+ public static final int du=0x7f02003b;
+ public static final int eye=0x7f02003c;
+ public static final int flash_on=0x7f02003d;
+ public static final int folder=0x7f02003e;
+ public static final int github=0x7f02003f;
+ public static final int heart=0x7f020040;
+ public static final int ic_add=0x7f020041;
+ public static final int ic_boot=0x7f020042;
+ public static final int ic_checkbox__on=0x7f020043;
+ public static final int ic_checkbox_off=0x7f020044;
+ public static final int ic_colorpicker_swatch_selected=0x7f020045;
+ public static final int ic_delete=0x7f020046;
+ public static final int ic_dots=0x7f020047;
+ public static final int ic_favcheck=0x7f020048;
+ public static final int ic_favuncheck=0x7f020049;
+ public static final int ic_file=0x7f02004a;
+ public static final int ic_folder=0x7f02004b;
+ public static final int ic_help=0x7f02004c;
+ public static final int ic_launcher=0x7f02004d;
+ public static final int ic_menu_refresh=0x7f02004e;
+ public static final int ic_plus=0x7f02004f;
+ public static final int ic_sdcard=0x7f020050;
+ public static final int info=0x7f020051;
+ public static final int lcd=0x7f020052;
+ public static final int life_guard=0x7f020053;
+ public static final int magic_wand=0x7f020054;
+ public static final int meter=0x7f020055;
+ public static final int omni=0x7f020056;
+ public static final int plus_minus=0x7f020057;
+ public static final int radiation=0x7f020058;
+ public static final int screen_background_selector_dark=0x7f020059;
+ public static final int screen_background_selector_light=0x7f02005a;
+ public static final int selector=0x7f02005b;
+ public static final int settings_one=0x7f02005c;
+ public static final int settings_two=0x7f02005d;
+ public static final int shadow=0x7f02005e;
+ public static final int shadow_right=0x7f02005f;
+ public static final int sollyx_google=0x7f020060;
+ public static final int top_shadow=0x7f020061;
+ public static final int veil=0x7f020062;
+ public static final int view_pager_background_texture=0x7f020063;
+ public static final int view_pager_background_texture_light=0x7f020064;
+ }
+ public static final class id {
+ public static final int TextView01=0x7f060024;
+ public static final int TextView02=0x7f060023;
+ public static final int View2=0x7f060020;
+ public static final int action_add=0x7f06005e;
+ public static final int action_boot=0x7f06005f;
+ public static final int action_delete=0x7f06005d;
+ public static final int action_edit=0x7f060062;
+ public static final int action_minus=0x7f060063;
+ public static final int action_plus=0x7f060061;
+ public static final int activity_container=0x7f06000c;
+ public static final int backup_boot=0x7f060017;
+ public static final int backup_recovery=0x7f06001c;
+ public static final int btn_apply=0x7f06003b;
+ public static final int btn_cancel=0x7f06003c;
+ public static final int btn_layout=0x7f06003a;
+ public static final int calendar_color_view=0x7f06002a;
+ public static final int cancel=0x7f060032;
+ public static final int cb=0x7f060043;
+ public static final int cb_boot=0x7f060010;
+ public static final int cb_cache=0x7f060011;
+ public static final int cb_compression=0x7f060013;
+ public static final int cb_data=0x7f06000e;
+ public static final int cb_md5=0x7f060014;
+ public static final int cb_recovery=0x7f060012;
+ public static final int cb_secure=0x7f06000f;
+ public static final int cb_system=0x7f06000d;
+ public static final int clickRemove=0x7f060005;
+ public static final int color_picker=0x7f060027;
+ public static final int color_picker_checkmark=0x7f060029;
+ public static final int color_picker_swatch=0x7f060028;
+ public static final int cpu_info=0x7f06002c;
+ public static final int cpu_info_core=0x7f06002e;
+ public static final int cpu_info_freq=0x7f06002f;
+ public static final int cpu_info_list=0x7f060052;
+ public static final int currvalue=0x7f060047;
+ public static final int dslist=0x7f060031;
+ public static final int empty=0x7f060022;
+ public static final int et=0x7f060030;
+ public static final int et_name=0x7f060016;
+ public static final int filename=0x7f060025;
+ public static final int flingRemove=0x7f060006;
+ public static final int fullscreen=0x7f060003;
+ public static final int help=0x7f060060;
+ public static final int icon=0x7f060037;
+ public static final int image=0x7f060018;
+ public static final int image2=0x7f06001d;
+ public static final int imageView1=0x7f060039;
+ public static final int info=0x7f060038;
+ public static final int item_container=0x7f060034;
+ public static final int kernel_info=0x7f06002b;
+ public static final int left=0x7f060000;
+ public static final int list=0x7f06003d;
+ public static final int margin=0x7f060002;
+ public static final int mem_info=0x7f06002d;
+ public static final int menu_frame=0x7f060040;
+ public static final int menu_header=0x7f060041;
+ public static final int name=0x7f060035;
+ public static final int navbarlist=0x7f060021;
+ public static final int onDown=0x7f060007;
+ public static final int onLongPress=0x7f060009;
+ public static final int onMove=0x7f060008;
+ public static final int pager=0x7f06000b;
+ public static final int preset_layout=0x7f06003e;
+ public static final int reboot=0x7f060033;
+ public static final int refresh=0x7f06005c;
+ public static final int reset=0x7f060064;
+ public static final int restore=0x7f060065;
+ public static final int right=0x7f060001;
+ public static final int sb_blur=0x7f06005b;
+ public static final int scrollView1=0x7f06003f;
+ public static final int seek_bar=0x7f060049;
+ public static final int seekbar=0x7f060046;
+ public static final int seekbar_dialog=0x7f060048;
+ public static final int selected_view=0x7f060004;
+ public static final int separator=0x7f060042;
+ public static final int setting_text=0x7f06004a;
+ public static final int slidingmenumain=0x7f06004b;
+ public static final int speed=0x7f060051;
+ public static final int summary=0x7f060045;
+ public static final int summaryboot=0x7f06001a;
+ public static final int summaryrecovery=0x7f06001f;
+ public static final int tabs=0x7f06000a;
+ public static final int text=0x7f060015;
+ public static final int textView1=0x7f06005a;
+ public static final int title=0x7f060044;
+ public static final int titleboot=0x7f060019;
+ public static final int titlerecovery=0x7f06001e;
+ public static final int tv_boot=0x7f060026;
+ public static final int ui_additional_states=0x7f060056;
+ public static final int ui_bar=0x7f060050;
+ public static final int ui_duration_text=0x7f06004f;
+ public static final int ui_freq_text=0x7f06004d;
+ public static final int ui_header_additional_states=0x7f060055;
+ public static final int ui_header_total_state_time=0x7f060053;
+ public static final int ui_percentage_text=0x7f06004e;
+ public static final int ui_state_row=0x7f06004c;
+ public static final int ui_states_view=0x7f060057;
+ public static final int ui_states_warning=0x7f060058;
+ public static final int ui_total_state_time=0x7f060054;
+ public static final int value=0x7f060036;
+ public static final int view1=0x7f06001b;
+ public static final int wall=0x7f060059;
+ }
+ public static final class layout {
+ public static final int activity_main=0x7f030000;
+ public static final int activity_main_container=0x7f030001;
+ public static final int backup_dialog_layout=0x7f030002;
+ public static final int backup_list=0x7f030003;
+ public static final int backup_list_item=0x7f030004;
+ public static final int boot_dialog_layout=0x7f030005;
+ public static final int calendar_color_picker_dialog=0x7f030006;
+ public static final int calendar_color_picker_swatch=0x7f030007;
+ public static final int calendar_grid_item_color=0x7f030008;
+ public static final int cpu_info=0x7f030009;
+ public static final int cpu_info_item=0x7f03000a;
+ public static final int dialog_about=0x7f03000b;
+ public static final int dialog_layout=0x7f03000c;
+ public static final int dragsort_list=0x7f03000d;
+ public static final int dragsort_list_item=0x7f03000e;
+ public static final int empty_test=0x7f03000f;
+ public static final int file_list_item=0x7f030010;
+ public static final int header=0x7f030011;
+ public static final int layout_list=0x7f030012;
+ public static final int layout_list_file=0x7f030013;
+ public static final int list_item=0x7f030014;
+ public static final int lmk_footer=0x7f030015;
+ public static final int lmk_layout=0x7f030016;
+ public static final int log_dialog=0x7f030017;
+ public static final int menu_glossary=0x7f030018;
+ public static final int menu_header=0x7f030019;
+ public static final int menu_list=0x7f03001a;
+ public static final int menu_list_item=0x7f03001b;
+ public static final int menu_main_list_item=0x7f03001c;
+ public static final int preference=0x7f03001d;
+ public static final int preference_widget_seekbar=0x7f03001e;
+ public static final int seekbar_dialog=0x7f03001f;
+ public static final int slidingmenumain=0x7f030020;
+ public static final int state_row=0x7f030021;
+ public static final int time_in_state=0x7f030022;
+ public static final int wallpaper_effects=0x7f030023;
+ }
+ public static final class menu {
+ public static final int cpu_info_menu=0x7f0d0000;
+ public static final int main=0x7f0d0001;
+ public static final int menu_lmk=0x7f0d0002;
+ public static final int menu_main_container=0x7f0d0003;
+ public static final int menu_recovery=0x7f0d0004;
+ public static final int menu_review=0x7f0d0005;
+ public static final int menu_uv=0x7f0d0006;
+ public static final int time_in_state_menu=0x7f0d0007;
+ }
+ public static final class string {
+ public static final int about_body=0x7f07000a;
+ public static final int about_ok=0x7f070009;
+ public static final int action_settings=0x7f070006;
+ public static final int app_name=0x7f070005;
+ public static final int apply_values=0x7f0700a1;
+ public static final int arrow_down=0x7f070109;
+ public static final int arrow_right=0x7f070108;
+ public static final int bad_zip=0x7f0700e5;
+ public static final int bb_desc=0x7f070017;
+ public static final int bb_title=0x7f070016;
+ public static final int bk_boot=0x7f07000c;
+ public static final int bk_boot_desc=0x7f07000d;
+ public static final int bk_comp=0x7f07000f;
+ public static final int bk_md5=0x7f070010;
+ public static final int bk_recovery=0x7f07000b;
+ public static final int bk_recovery_desc=0x7f07000e;
+ public static final int bkexit=0x7f0700d4;
+ public static final int bltimeout_title=0x7f07007b;
+ /** blx
+ */
+ public static final int blx_info=0x7f070070;
+ public static final int blx_title=0x7f070074;
+ public static final int btn_choose=0x7f0700cf;
+ public static final int btncleanall=0x7f0700d7;
+ public static final int buildprop_settings_warning=0x7f070118;
+ public static final int buildprop_summary=0x7f070127;
+ public static final int buildprop_title=0x7f070117;
+ public static final int cancel=0x7f070040;
+ public static final int clean_files_msg=0x7f0700d8;
+ public static final int clear=0x7f0700c3;
+ public static final int closebtn=0x7f0700e6;
+ /** Default title for color picker dialog [CHAR LIMIT=30]
+ */
+ public static final int color_picker_default_title=0x7f070001;
+ /** Content description for a color square.
+ */
+ public static final int color_swatch_description=0x7f070002;
+ /** Content description for a selected color square.
+ */
+ public static final int color_swatch_description_selected=0x7f070003;
+ public static final int core=0x7f070045;
+ public static final int core_offline=0x7f070044;
+ public static final int cpu_adv_gov_desc=0x7f07002b;
+ public static final int cpu_adv_gov_title=0x7f07002a;
+ public static final int cpu_adv_quiet_desc=0x7f07002d;
+ public static final int cpu_adv_quiet_title=0x7f07002c;
+ public static final int cpu_advanced=0x7f070029;
+ public static final int cpu_cpuquiet_desc=0x7f070028;
+ public static final int cpu_cpuquiet_title=0x7f070027;
+ public static final int cpu_governor=0x7f070025;
+ public static final int cpu_hotplug=0x7f070026;
+ public static final int cpu_info=0x7f0700b6;
+ public static final int cpu_info_list_header=0x7f070041;
+ public static final int cpu_max=0x7f070023;
+ public static final int cpu_min=0x7f070024;
+ public static final int cpu_speed_header=0x7f070042;
+ public static final int current=0x7f0700a3;
+ public static final int current_max=0x7f07003a;
+ public static final int current_min=0x7f07003b;
+ /** CPU settings
+ */
+ public static final int current_speed=0x7f070039;
+ public static final int db_exit=0x7f070183;
+ public static final int deep_sleep=0x7f0700b4;
+ public static final int defcolor=0x7f070004;
+ public static final int del_file_msg=0x7f0700e8;
+ public static final int delallbtn=0x7f0700e7;
+ /** Color picker
+ */
+ public static final int dialog_color_picker=0x7f070106;
+ public static final int dir=0x7f0700d3;
+ public static final int dir_parent=0x7f0700d2;
+ public static final int dirty_background_title=0x7f0700a9;
+ public static final int dirty_expire_title=0x7f0700aa;
+ public static final int dirty_ratio_summary=0x7f0700a8;
+ public static final int dirty_ratio_title=0x7f0700a7;
+ public static final int dirty_writeback_title=0x7f0700ab;
+ public static final int dm_init_d_error=0x7f070182;
+ /** dsync
+ */
+ public static final int dsync_info=0x7f070075;
+ public static final int dt_free_memory=0x7f07004b;
+ public static final int dt_init_d_error=0x7f070181;
+ public static final int dt_read_ahead=0x7f07004c;
+ public static final int dynamic_write_back_title=0x7f07008b;
+ public static final int dynamic_writeback_active_title=0x7f07008d;
+ /** dynamic write back
+ */
+ public static final int dynamic_writeback_info=0x7f07008a;
+ public static final int dynamic_writeback_suspend_title=0x7f07008e;
+ public static final int emp_desc=0x7f070013;
+ public static final int emp_title=0x7f070012;
+ public static final int fast_charge_notification_message=0x7f070055;
+ public static final int fast_charge_notification_title=0x7f070054;
+ public static final int fast_charge_warning=0x7f070053;
+ public static final int filesstr=0x7f0700d9;
+ public static final int first_run_message=0x7f0700bb;
+ public static final int first_run_title=0x7f0700b8;
+ public static final int fix_perms_msg=0x7f0700e0;
+ public static final int fix_perms_title=0x7f0700df;
+ public static final int flash_info=0x7f0700d1;
+ public static final int free=0x7f0700e2;
+ public static final int freeze_msg=0x7f0700fa;
+ public static final int freq=0x7f0700a2;
+ /** Replace placeholder ID with your tracking ID
+ */
+ public static final int ga_trackingId=0x7f070000;
+ public static final int gift=0x7f070019;
+ public static final int gov_title=0x7f07002e;
+ public static final int governor=0x7f07003c;
+ public static final int gpu_category=0x7f07002f;
+ public static final int gpu_freq_desc=0x7f070031;
+ public static final int gpu_freq_title=0x7f070030;
+ /** Init.d
+ */
+ public static final int header_summary_init_d=0x7f070147;
+ public static final int hello_world=0x7f070007;
+ public static final int hex=0x7f07010a;
+ public static final int hex_hint=0x7f07010b;
+ public static final int home_allowed_irq_title=0x7f070082;
+ public static final int home_report_wait_title=0x7f070083;
+ public static final int ics_color=0x7f07010d;
+ public static final int init_d_title=0x7f070148;
+ public static final int io=0x7f07003d;
+ public static final int kernel_img_title=0x7f0700cb;
+ /** CPU info
+ */
+ public static final int kernel_info=0x7f0700b5;
+ public static final int ksm_adv_title=0x7f0700eb;
+ public static final int ksm_fullscans=0x7f0700ec;
+ public static final int ksm_pagshared=0x7f0700ed;
+ public static final int ksm_pagsharing=0x7f0700ee;
+ public static final int ksm_pagtoscan=0x7f0700f1;
+ public static final int ksm_pagunshared=0x7f0700ef;
+ public static final int ksm_pagvolatile=0x7f0700f0;
+ public static final int ksm_sleep=0x7f0700f2;
+ public static final int list_command_empty=0x7f070011;
+ public static final int mem_info=0x7f0700b7;
+ public static final int menu_add=0x7f07001d;
+ public static final int menu_boot=0x7f07001e;
+ public static final int menu_command=0x7f07001f;
+ public static final int menu_del=0x7f07001c;
+ public static final int menu_glossary=0x7f070032;
+ public static final int menu_less=0x7f070020;
+ public static final int menu_plus=0x7f070021;
+ public static final int menuback_first_err_wait_title=0x7f070087;
+ public static final int menuback_interrupt_checks_title=0x7f070086;
+ public static final int menuback_last_err_wait_title=0x7f070088;
+ public static final int min_free_title=0x7f0700ac;
+ public static final int mt_app_settings=0x7f070034;
+ public static final int mt_gov_ctrl=0x7f070100;
+ public static final int mt_minus25=0x7f070038;
+ public static final int mt_plus25=0x7f070037;
+ /** Menu
+ */
+ public static final int mt_refresh=0x7f070033;
+ public static final int mt_reset=0x7f070035;
+ public static final int mt_restore=0x7f070036;
+ public static final int mt_system_packs=0x7f0700f8;
+ public static final int mt_user_packs=0x7f0700f9;
+ public static final int navigation_drawer_close=0x7f070110;
+ public static final int navigation_drawer_open=0x7f07010f;
+ /** Drawer
+ */
+ public static final int navigation_drawer_toggle=0x7f07010e;
+ public static final int navigation_toggle_drawer=0x7f070111;
+ public static final int navigation_toggle_tabbed=0x7f070112;
+ public static final int no_proc=0x7f07006d;
+ public static final int no_residuals=0x7f0700da;
+ public static final int no_states_file_found=0x7f0700b3;
+ public static final int nonprop_cat_title=0x7f070119;
+ public static final int not_supported=0x7f0700a5;
+ public static final int ok=0x7f07003f;
+ public static final int optim_db_title=0x7f0700dc;
+ public static final int other_settings_header=0x7f070043;
+ public static final int overcommit_title=0x7f0700ad;
+ public static final int performance_settings_warning_header=0x7f070114;
+ /** Performance Settings | Warning dialog
+ */
+ public static final int performance_settings_warning_title=0x7f070113;
+ /** pfk
+ */
+ public static final int pfk_info=0x7f07007e;
+ public static final int pref_fast_up_alt_summary=0x7f070130;
+ public static final int pref_fast_up_summary=0x7f07012f;
+ public static final int pref_fast_up_title=0x7f07012e;
+ public static final int pref_g_speed_summary=0x7f070140;
+ public static final int pref_g_speed_title=0x7f07013f;
+ public static final int pref_gpu_summary=0x7f070142;
+ public static final int pref_gpu_title=0x7f070141;
+ public static final int pref_jit_summary=0x7f07013c;
+ public static final int pref_jit_title=0x7f07013b;
+ public static final int pref_lcd_alt_summary=0x7f070146;
+ public static final int pref_lcd_default=0x7f070145;
+ public static final int pref_lcd_summary=0x7f070144;
+ public static final int pref_lcd_title=0x7f070143;
+ public static final int pref_max_events_alt_summary=0x7f07011f;
+ public static final int pref_max_events_summary=0x7f07011e;
+ public static final int pref_max_events_title=0x7f07011d;
+ public static final int pref_mod_version_alt_summary=0x7f070136;
+ public static final int pref_mod_version_default=0x7f070137;
+ public static final int pref_mod_version_summary=0x7f070135;
+ public static final int pref_mod_version_title=0x7f070134;
+ public static final int pref_prox_delay_alt_summary=0x7f070133;
+ public static final int pref_prox_delay_summary=0x7f070132;
+ public static final int pref_prox_delay_title=0x7f070131;
+ public static final int pref_ring_delay_alt_summary=0x7f070122;
+ public static final int pref_ring_delay_summary=0x7f070121;
+ public static final int pref_ring_delay_title=0x7f070120;
+ public static final int pref_sleep_alt_summary=0x7f07013a;
+ public static final int pref_sleep_summary=0x7f070139;
+ public static final int pref_sleep_title=0x7f070138;
+ public static final int pref_tcp_stack_summary=0x7f07013e;
+ public static final int pref_tcp_stack_title=0x7f07013d;
+ public static final int pref_vm_heapsize_alt_summary=0x7f070125;
+ public static final int pref_vm_heapsize_summary=0x7f070124;
+ public static final int pref_vm_heapsize_title=0x7f070123;
+ public static final int pref_wifi_scan_alt_summary=0x7f07011c;
+ public static final int pref_wifi_scan_interval_summary=0x7f07011b;
+ public static final int pref_wifi_scan_interval_title=0x7f07011a;
+ /** bln
+ */
+ public static final int prefcat_bln=0x7f07006e;
+ /** bl_timeout
+ */
+ public static final int prefcat_bltimeout=0x7f070079;
+ /** bl_touch
+ */
+ public static final int prefcat_bltouch=0x7f07007c;
+ public static final int prefcat_blx=0x7f070071;
+ public static final int prefcat_dsync=0x7f070076;
+ public static final int prefcat_fix_perms=0x7f0700de;
+ public static final int prefcat_flash_img=0x7f0700ca;
+ /** Other settings
+ */
+ public static final int prefcat_free_memory=0x7f070046;
+ /** freezer
+ */
+ public static final int prefcat_freezer=0x7f0700f3;
+ /** 2.1.2
+ ksm
+ */
+ public static final int prefcat_ksm=0x7f0700e9;
+ public static final int prefcat_misc_short=0x7f070048;
+ /** minfree
+ */
+ public static final int prefcat_oom=0x7f070056;
+ public static final int prefcat_oom_predefines=0x7f07005d;
+ public static final int prefcat_optim_db=0x7f0700db;
+ public static final int prefcat_pfk=0x7f07007f;
+ public static final int prefcat_read_ahead=0x7f070049;
+ public static final int prefcat_residual_files=0x7f0700d5;
+ /** Tools
+ */
+ public static final int prefcat_sh=0x7f0700bf;
+ public static final int prefcat_sys_proc=0x7f070065;
+ public static final int prefcat_tweaks=0x7f070047;
+ /** do not kill proc
+ */
+ public static final int prefcat_user_proc=0x7f070064;
+ public static final int prefcat_vm_settings=0x7f07004a;
+ public static final int prefcat_wipe_cache=0x7f0700c6;
+ /** zRam
+ */
+ public static final int prefcat_zram=0x7f0700fc;
+ public static final int preflogg_fix_perms=0x7f0700e1;
+ public static final int press_color_to_apply=0x7f070107;
+ public static final int propmodder_switches=0x7f070116;
+ /** PropModder
+ */
+ public static final int propmodder_title=0x7f070115;
+ public static final int ps_battery=0x7f070166;
+ public static final int ps_bltimeout=0x7f07007a;
+ public static final int ps_blx_boot=0x7f070073;
+ public static final int ps_clear_data_cache=0x7f070153;
+ public static final int ps_dsync=0x7f070077;
+ public static final int ps_enable_cron=0x7f070155;
+ public static final int ps_enable_sysctl=0x7f07014f;
+ public static final int ps_fast_charge_boot=0x7f070052;
+ public static final int ps_file_system_speedups=0x7f070159;
+ public static final int ps_fix_permissions=0x7f07014d;
+ public static final int ps_free_mem=0x7f070151;
+ public static final int ps_free_memory=0x7f07004e;
+ public static final int ps_free_memory_boot=0x7f07004f;
+ public static final int ps_freeze=0x7f0700f6;
+ public static final int ps_gpurender=0x7f07016c;
+ public static final int ps_home_enabled=0x7f070081;
+ public static final int ps_init_d_credits=0x7f070180;
+ public static final int ps_iostats=0x7f070176;
+ public static final int ps_journalism=0x7f070170;
+ public static final int ps_kernel_img=0x7f0700cc;
+ public static final int ps_loopy_smoothness_tweak=0x7f07017e;
+ public static final int ps_menuback_enabled=0x7f070085;
+ public static final int ps_minfree=0x7f07016a;
+ public static final int ps_optim_db=0x7f0700dd;
+ public static final int ps_pfk_set_on_boot=0x7f070089;
+ public static final int ps_read_ahead=0x7f070051;
+ public static final int ps_recovery_img=0x7f0700ce;
+ public static final int ps_restore_boot=0x7f07006a;
+ public static final int ps_sd_boost=0x7f070157;
+ public static final int ps_setrenice=0x7f070178;
+ public static final int ps_sh=0x7f0700c1;
+ public static final int ps_sleepers=0x7f07016e;
+ public static final int ps_speedy_modified=0x7f07017c;
+ public static final int ps_sqlite3=0x7f070172;
+ public static final int ps_sys_proc=0x7f07006c;
+ public static final int ps_touch=0x7f070168;
+ public static final int ps_tweaks=0x7f07017a;
+ public static final int ps_unfreeze=0x7f0700f7;
+ public static final int ps_use_light_theme=0x7f070102;
+ public static final int ps_user_proc=0x7f07006b;
+ /** VM settings
+ */
+ public static final int ps_vm_set_on_boot=0x7f0700a6;
+ public static final int ps_volt_control=0x7f0700a0;
+ public static final int ps_volt_current_voltage=0x7f07009d;
+ public static final int ps_volt_mhz_voltage=0x7f07009b;
+ public static final int ps_volt_save=0x7f07009c;
+ public static final int ps_volt_setting_to_apply=0x7f07009e;
+ public static final int ps_wifisleep=0x7f070174;
+ public static final int ps_wipe_cache=0x7f0700c8;
+ public static final int ps_zipalign_apks=0x7f07014b;
+ /** 2.1.3
+ */
+ public static final int ps_zram=0x7f0700ff;
+ public static final int pt_aggressive=0x7f070062;
+ public static final int pt_backup_app_mem=0x7f07015f;
+ public static final int pt_battery=0x7f070165;
+ public static final int pt_bln=0x7f07006f;
+ public static final int pt_bltouch=0x7f07007d;
+ public static final int pt_blx_boot=0x7f070072;
+ public static final int pt_clear_data_cache=0x7f070152;
+ public static final int pt_dsync=0x7f070078;
+ public static final int pt_dynamic_write_back=0x7f07008c;
+ public static final int pt_empty_app_mem=0x7f070162;
+ public static final int pt_enable_cron=0x7f070154;
+ public static final int pt_enable_sysctl=0x7f07014e;
+ public static final int pt_file_system_speedups=0x7f070158;
+ public static final int pt_fix_permissions=0x7f07014c;
+ public static final int pt_foreground_app_mem=0x7f07015a;
+ public static final int pt_free_mem=0x7f070150;
+ public static final int pt_free_memory=0x7f07004d;
+ public static final int pt_freeze=0x7f0700f4;
+ public static final int pt_general=0x7f070149;
+ public static final int pt_gpurender=0x7f07016b;
+ public static final int pt_heavy_weight_app_mem=0x7f07015d;
+ public static final int pt_hidden_app_mem=0x7f070161;
+ public static final int pt_home_app_mem=0x7f070160;
+ public static final int pt_home_enabled=0x7f070080;
+ public static final int pt_init_d_credits=0x7f07017f;
+ public static final int pt_iostats=0x7f070175;
+ public static final int pt_journalism=0x7f07016f;
+ public static final int pt_light=0x7f070060;
+ public static final int pt_loopy_smoothness_tweak=0x7f07017d;
+ public static final int pt_medium=0x7f070061;
+ public static final int pt_menuback_enabled=0x7f070084;
+ public static final int pt_minfree=0x7f070169;
+ public static final int pt_minfree_values=0x7f070164;
+ public static final int pt_oom=0x7f07005e;
+ public static final int pt_perceptible_app_mem=0x7f07015c;
+ public static final int pt_read_ahead=0x7f070050;
+ public static final int pt_read_ahead_kb=0x7f070163;
+ public static final int pt_run_ksm=0x7f0700ea;
+ public static final int pt_run_zram=0x7f0700fd;
+ public static final int pt_sd_boost=0x7f070156;
+ public static final int pt_secondary_server_mem=0x7f07015e;
+ public static final int pt_setrenice=0x7f070177;
+ public static final int pt_sleepers=0x7f07016d;
+ public static final int pt_speedy_modified=0x7f07017b;
+ public static final int pt_sqlite3=0x7f070171;
+ public static final int pt_sys_names_proc=0x7f070069;
+ public static final int pt_sys_proc=0x7f070067;
+ public static final int pt_touch=0x7f070167;
+ public static final int pt_tweaks=0x7f070179;
+ public static final int pt_unfreeze=0x7f0700f5;
+ /** PC Settings
+ */
+ public static final int pt_use_light_theme=0x7f070101;
+ public static final int pt_user_names_proc=0x7f070068;
+ public static final int pt_user_proc=0x7f070066;
+ public static final int pt_ver=0x7f070105;
+ public static final int pt_veryaggressive=0x7f070063;
+ public static final int pt_verylight=0x7f07005f;
+ public static final int pt_visible_app_mem=0x7f07015b;
+ public static final int pt_volt_control=0x7f07009f;
+ public static final int pt_widget_bg_color=0x7f070103;
+ public static final int pt_widget_text_color=0x7f070104;
+ public static final int pt_wifisleep=0x7f070173;
+ public static final int pt_zipalign_apks=0x7f07014a;
+ public static final int rc_desc=0x7f070015;
+ public static final int rc_title=0x7f070014;
+ public static final int recovery_img_title=0x7f0700cd;
+ public static final int residual_files_title=0x7f0700d6;
+ public static final int saved=0x7f0700a4;
+ public static final int set=0x7f07010c;
+ public static final int sh_msg=0x7f0700c2;
+ public static final int sh_title=0x7f0700c0;
+ public static final int showbuild_dialog=0x7f070128;
+ public static final int showbuild_error=0x7f07012a;
+ public static final int showbuild_label=0x7f07012d;
+ public static final int showbuild_loading=0x7f070129;
+ public static final int showbuild_title=0x7f070126;
+ public static final int showbuild_unknown=0x7f07012b;
+ public static final int showbuild_version=0x7f07012c;
+ public static final int size_100_mb=0x7f070093;
+ public static final int size_1024_kb=0x7f070097;
+ public static final int size_128_kb=0x7f070094;
+ public static final int size_2048_kb=0x7f070098;
+ public static final int size_256_kb=0x7f070095;
+ /**
+ */
+ public static final int size_25_mb=0x7f07008f;
+ public static final int size_4096_kb=0x7f070099;
+ public static final int size_50_mb=0x7f070090;
+ public static final int size_512_kb=0x7f070096;
+ public static final int size_75_mb=0x7f070091;
+ public static final int size_80_mb=0x7f070092;
+ public static final int sob=0x7f07003e;
+ public static final int st_cat=0x7f070018;
+ public static final int su_cancel_message=0x7f0700bd;
+ public static final int su_failed_su_or_busybox=0x7f0700be;
+ public static final int su_failed_title=0x7f0700ba;
+ public static final int su_success_message=0x7f0700bc;
+ public static final int su_success_title=0x7f0700b9;
+ public static final int swappiness_title=0x7f0700ae;
+ /** Time in state
+ */
+ public static final int time_in_state=0x7f0700b0;
+ /** About
+ */
+ public static final int title_about=0x7f070008;
+ public static final int title_content_providers=0x7f07005b;
+ public static final int title_empty_app=0x7f07005c;
+ public static final int title_foreground_app=0x7f070057;
+ public static final int title_hidden_app=0x7f07005a;
+ public static final int title_secondary_server=0x7f070059;
+ public static final int title_visible_app=0x7f070058;
+ public static final int total_state_time=0x7f0700b2;
+ public static final int unfreeze_msg=0x7f0700fb;
+ public static final int unsupported_info=0x7f0700d0;
+ public static final int unused_cpu_states=0x7f0700b1;
+ public static final int used=0x7f0700e3;
+ public static final int uv_title=0x7f070022;
+ public static final int vdd_desc=0x7f07001b;
+ public static final int vdd_pref=0x7f07001a;
+ /** 2.1.0
+ */
+ public static final int verify=0x7f0700e4;
+ public static final int vfs_title=0x7f0700af;
+ /** Voltage control
+ */
+ public static final int volt_info=0x7f07009a;
+ public static final int wait=0x7f0700c5;
+ public static final int wipe_cache_msg=0x7f0700c9;
+ public static final int wipe_cache_title=0x7f0700c7;
+ public static final int yes=0x7f0700c4;
+ public static final int zram_set_title=0x7f0700fe;
+ }
+ public static final class style {
+ public static final int ActionBar_Style=0x7f0c0005;
+ /**
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+
+
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+
+
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+
+ API 11 theme customizations can go here.
+
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+
+ API 14 theme customizations can go here.
+ */
+ public static final int AppBaseTheme=0x7f0c0000;
+ public static final int AppLight=0x7f0c0009;
+ public static final int AppTheme=0x7f0c0008;
+ public static final int EditTextAppTheme=0x7f0c0002;
+ public static final int LightListViewStyle=0x7f0c0007;
+ public static final int RadioButtonAppTheme=0x7f0c0003;
+ public static final int SeekBarAppTheme=0x7f0c0004;
+ public static final int TitleTextStyle=0x7f0c0006;
+ /** Application theme.
+ */
+ public static final int dialog_animation=0x7f0c0001;
+ }
+ public static final class xml {
+ public static final int infos=0x7f050000;
+ public static final int init_d=0x7f050001;
+ public static final int pc_settings=0x7f050002;
+ public static final int pref_sccreen_uv=0x7f050003;
+ public static final int pref_screen_cpu=0x7f050004;
+ public static final int pref_screen_governor=0x7f050005;
+ public static final int pref_screen_gpu=0x7f050006;
+ public static final int pref_screen_kernel=0x7f050007;
+ public static final int pref_screen_minfree=0x7f050008;
+ public static final int pref_screen_review=0x7f050009;
+ public static final int pref_screen_scheduler=0x7f05000a;
+ public static final int pref_settings=0x7f05000b;
+ public static final int propmodder=0x7f05000c;
+ public static final int vm=0x7f05000d;
+ public static final int vm_settings=0x7f05000e;
+ public static final int wallpaper=0x7f05000f;
+ }
+ public static final class styleable {
+ /** Attributes that can be used with a CircleAnimatedCheckBox.
+ <p>Includes the following attributes:</p>
+ <table>
+ <colgroup align="left" />
+ <colgroup align="left" />
+ <tr><th>Attribute</th><th>Description</th></tr>
+ <tr><td><code>{@link #CircleAnimatedCheckBox_cb_color com.dsht.kerneltweaker:cb_color}</code></td><td></td></tr>
+ <tr><td><code>{@link #CircleAnimatedCheckBox_cb_pressed_ring_width com.dsht.kerneltweaker:cb_pressed_ring_width}</code></td><td></td></tr>
+ </table>
+ @see #CircleAnimatedCheckBox_cb_color
+ @see #CircleAnimatedCheckBox_cb_pressed_ring_width
+ */
+ public static final int[] CircleAnimatedCheckBox = {
+ 0x7f01000e, 0x7f01000f
+ };
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#cb_color}
+ attribute's value can be found in the {@link #CircleAnimatedCheckBox} array.
+
+
+ <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:cb_color
+ */
+ public static final int CircleAnimatedCheckBox_cb_color = 0;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#cb_pressed_ring_width}
+ attribute's value can be found in the {@link #CircleAnimatedCheckBox} array.
+
+
+ <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:cb_pressed_ring_width
+ */
+ public static final int CircleAnimatedCheckBox_cb_pressed_ring_width = 1;
+ /** Attributes that can be used with a ColorPickerPreference.
+ <p>Includes the following attributes:</p>
+ <table>
+ <colgroup align="left" />
+ <colgroup align="left" />
+ <tr><th>Attribute</th><th>Description</th></tr>
+ <tr><td><code>{@link #ColorPickerPreference_cal_choices com.dsht.kerneltweaker:cal_choices}</code></td><td></td></tr>
+ <tr><td><code>{@link #ColorPickerPreference_cal_itemLayout com.dsht.kerneltweaker:cal_itemLayout}</code></td><td></td></tr>
+ <tr><td><code>{@link #ColorPickerPreference_cal_numColumns com.dsht.kerneltweaker:cal_numColumns}</code></td><td></td></tr>
+ </table>
+ @see #ColorPickerPreference_cal_choices
+ @see #ColorPickerPreference_cal_itemLayout
+ @see #ColorPickerPreference_cal_numColumns
+ */
+ public static final int[] ColorPickerPreference = {
+ 0x7f010010, 0x7f010011, 0x7f010012
+ };
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#cal_choices}
+ attribute's value can be found in the {@link #ColorPickerPreference} array.
+
+
+ <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ @attr name com.dsht.kerneltweaker:cal_choices
+ */
+ public static final int ColorPickerPreference_cal_choices = 1;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#cal_itemLayout}
+ attribute's value can be found in the {@link #ColorPickerPreference} array.
+
+
+ <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ @attr name com.dsht.kerneltweaker:cal_itemLayout
+ */
+ public static final int ColorPickerPreference_cal_itemLayout = 0;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#cal_numColumns}
+ attribute's value can be found in the {@link #ColorPickerPreference} array.
+
+
+ <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:cal_numColumns
+ */
+ public static final int ColorPickerPreference_cal_numColumns = 2;
+ /** Attributes that can be used with a DragSortListView.
+ <p>Includes the following attributes:</p>
+ <table>
+ <colgroup align="left" />
+ <colgroup align="left" />
+ <tr><th>Attribute</th><th>Description</th></tr>
+ <tr><td><code>{@link #DragSortListView_click_remove_id com.dsht.kerneltweaker:click_remove_id}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_collapsed_height com.dsht.kerneltweaker:collapsed_height}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_drag_enabled com.dsht.kerneltweaker:drag_enabled}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_drag_handle_id com.dsht.kerneltweaker:drag_handle_id}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_drag_scroll_start com.dsht.kerneltweaker:drag_scroll_start}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_drag_start_mode com.dsht.kerneltweaker:drag_start_mode}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_drop_animation_duration com.dsht.kerneltweaker:drop_animation_duration}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_fling_handle_id com.dsht.kerneltweaker:fling_handle_id}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_float_alpha com.dsht.kerneltweaker:float_alpha}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_float_background_color com.dsht.kerneltweaker:float_background_color}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_max_drag_scroll_speed com.dsht.kerneltweaker:max_drag_scroll_speed}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_remove_animation_duration com.dsht.kerneltweaker:remove_animation_duration}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_remove_enabled com.dsht.kerneltweaker:remove_enabled}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_remove_mode com.dsht.kerneltweaker:remove_mode}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_slide_shuffle_speed com.dsht.kerneltweaker:slide_shuffle_speed}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_sort_enabled com.dsht.kerneltweaker:sort_enabled}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_track_drag_sort com.dsht.kerneltweaker:track_drag_sort}</code></td><td></td></tr>
+ <tr><td><code>{@link #DragSortListView_use_default_controller com.dsht.kerneltweaker:use_default_controller}</code></td><td></td></tr>
+ </table>
+ @see #DragSortListView_click_remove_id
+ @see #DragSortListView_collapsed_height
+ @see #DragSortListView_drag_enabled
+ @see #DragSortListView_drag_handle_id
+ @see #DragSortListView_drag_scroll_start
+ @see #DragSortListView_drag_start_mode
+ @see #DragSortListView_drop_animation_duration
+ @see #DragSortListView_fling_handle_id
+ @see #DragSortListView_float_alpha
+ @see #DragSortListView_float_background_color
+ @see #DragSortListView_max_drag_scroll_speed
+ @see #DragSortListView_remove_animation_duration
+ @see #DragSortListView_remove_enabled
+ @see #DragSortListView_remove_mode
+ @see #DragSortListView_slide_shuffle_speed
+ @see #DragSortListView_sort_enabled
+ @see #DragSortListView_track_drag_sort
+ @see #DragSortListView_use_default_controller
+ */
+ public static final int[] DragSortListView = {
+ 0x7f010013, 0x7f010014, 0x7f010015, 0x7f010016,
+ 0x7f010017, 0x7f010018, 0x7f010019, 0x7f01001a,
+ 0x7f01001b, 0x7f01001c, 0x7f01001d, 0x7f01001e,
+ 0x7f01001f, 0x7f010020, 0x7f010021, 0x7f010022,
+ 0x7f010023, 0x7f010024
+ };
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#click_remove_id}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:click_remove_id
+ */
+ public static final int DragSortListView_click_remove_id = 16;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#collapsed_height}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:collapsed_height
+ */
+ public static final int DragSortListView_collapsed_height = 0;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#drag_enabled}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:drag_enabled
+ */
+ public static final int DragSortListView_drag_enabled = 10;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#drag_handle_id}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:drag_handle_id
+ */
+ public static final int DragSortListView_drag_handle_id = 14;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#drag_scroll_start}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:drag_scroll_start
+ */
+ public static final int DragSortListView_drag_scroll_start = 1;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#drag_start_mode}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be one of the following constant values.</p>
+<table>
+<colgroup align="left" />
+<colgroup align="left" />
+<colgroup align="left" />
+<tr><th>Constant</th><th>Value</th><th>Description</th></tr>
+<tr><td><code>onDown</code></td><td>0</td><td></td></tr>
+<tr><td><code>onMove</code></td><td>1</td><td></td></tr>
+<tr><td><code>onLongPress</code></td><td>2</td><td></td></tr>
+</table>
+ @attr name com.dsht.kerneltweaker:drag_start_mode
+ */
+ public static final int DragSortListView_drag_start_mode = 13;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#drop_animation_duration}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:drop_animation_duration
+ */
+ public static final int DragSortListView_drop_animation_duration = 9;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#fling_handle_id}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:fling_handle_id
+ */
+ public static final int DragSortListView_fling_handle_id = 15;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#float_alpha}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:float_alpha
+ */
+ public static final int DragSortListView_float_alpha = 6;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#float_background_color}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:float_background_color
+ */
+ public static final int DragSortListView_float_background_color = 3;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#max_drag_scroll_speed}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:max_drag_scroll_speed
+ */
+ public static final int DragSortListView_max_drag_scroll_speed = 2;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#remove_animation_duration}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be an integer value, such as "<code>100</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:remove_animation_duration
+ */
+ public static final int DragSortListView_remove_animation_duration = 8;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#remove_enabled}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:remove_enabled
+ */
+ public static final int DragSortListView_remove_enabled = 12;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#remove_mode}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be one of the following constant values.</p>
+<table>
+<colgroup align="left" />
+<colgroup align="left" />
+<colgroup align="left" />
+<tr><th>Constant</th><th>Value</th><th>Description</th></tr>
+<tr><td><code>clickRemove</code></td><td>0</td><td></td></tr>
+<tr><td><code>flingRemove</code></td><td>1</td><td></td></tr>
+</table>
+ @attr name com.dsht.kerneltweaker:remove_mode
+ */
+ public static final int DragSortListView_remove_mode = 4;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#slide_shuffle_speed}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:slide_shuffle_speed
+ */
+ public static final int DragSortListView_slide_shuffle_speed = 7;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#sort_enabled}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:sort_enabled
+ */
+ public static final int DragSortListView_sort_enabled = 11;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#track_drag_sort}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:track_drag_sort
+ */
+ public static final int DragSortListView_track_drag_sort = 5;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#use_default_controller}
+ attribute's value can be found in the {@link #DragSortListView} array.
+
+
+ <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:use_default_controller
+ */
+ public static final int DragSortListView_use_default_controller = 17;
+ /** Attributes that can be used with a SlidingMenu.
+ <p>Includes the following attributes:</p>
+ <table>
+ <colgroup align="left" />
+ <colgroup align="left" />
+ <tr><th>Attribute</th><th>Description</th></tr>
+ <tr><td><code>{@link #SlidingMenu_behindOffset com.dsht.kerneltweaker:behindOffset}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_behindScrollScale com.dsht.kerneltweaker:behindScrollScale}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_behindWidth com.dsht.kerneltweaker:behindWidth}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_fadeDegree com.dsht.kerneltweaker:fadeDegree}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_fadeEnabled com.dsht.kerneltweaker:fadeEnabled}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_mode com.dsht.kerneltweaker:mode}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_selectorDrawable com.dsht.kerneltweaker:selectorDrawable}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_selectorEnabled com.dsht.kerneltweaker:selectorEnabled}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_shadowDrawable com.dsht.kerneltweaker:shadowDrawable}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_shadowWidth com.dsht.kerneltweaker:shadowWidth}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_touchModeAbove com.dsht.kerneltweaker:touchModeAbove}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_touchModeBehind com.dsht.kerneltweaker:touchModeBehind}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_viewAbove com.dsht.kerneltweaker:viewAbove}</code></td><td></td></tr>
+ <tr><td><code>{@link #SlidingMenu_viewBehind com.dsht.kerneltweaker:viewBehind}</code></td><td></td></tr>
+ </table>
+ @see #SlidingMenu_behindOffset
+ @see #SlidingMenu_behindScrollScale
+ @see #SlidingMenu_behindWidth
+ @see #SlidingMenu_fadeDegree
+ @see #SlidingMenu_fadeEnabled
+ @see #SlidingMenu_mode
+ @see #SlidingMenu_selectorDrawable
+ @see #SlidingMenu_selectorEnabled
+ @see #SlidingMenu_shadowDrawable
+ @see #SlidingMenu_shadowWidth
+ @see #SlidingMenu_touchModeAbove
+ @see #SlidingMenu_touchModeBehind
+ @see #SlidingMenu_viewAbove
+ @see #SlidingMenu_viewBehind
+ */
+ public static final int[] SlidingMenu = {
+ 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003,
+ 0x7f010004, 0x7f010005, 0x7f010006, 0x7f010007,
+ 0x7f010008, 0x7f010009, 0x7f01000a, 0x7f01000b,
+ 0x7f01000c, 0x7f01000d
+ };
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#behindOffset}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:behindOffset
+ */
+ public static final int SlidingMenu_behindOffset = 3;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#behindScrollScale}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:behindScrollScale
+ */
+ public static final int SlidingMenu_behindScrollScale = 5;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#behindWidth}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:behindWidth
+ */
+ public static final int SlidingMenu_behindWidth = 4;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#fadeDegree}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a floating point value, such as "<code>1.2</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:fadeDegree
+ */
+ public static final int SlidingMenu_fadeDegree = 11;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#fadeEnabled}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:fadeEnabled
+ */
+ public static final int SlidingMenu_fadeEnabled = 10;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#mode}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be one of the following constant values.</p>
+<table>
+<colgroup align="left" />
+<colgroup align="left" />
+<colgroup align="left" />
+<tr><th>Constant</th><th>Value</th><th>Description</th></tr>
+<tr><td><code>left</code></td><td>0</td><td></td></tr>
+<tr><td><code>right</code></td><td>1</td><td></td></tr>
+</table>
+ @attr name com.dsht.kerneltweaker:mode
+ */
+ public static final int SlidingMenu_mode = 0;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#selectorDrawable}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ @attr name com.dsht.kerneltweaker:selectorDrawable
+ */
+ public static final int SlidingMenu_selectorDrawable = 13;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#selectorEnabled}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a boolean value, either "<code>true</code>" or "<code>false</code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:selectorEnabled
+ */
+ public static final int SlidingMenu_selectorEnabled = 12;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#shadowDrawable}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ @attr name com.dsht.kerneltweaker:shadowDrawable
+ */
+ public static final int SlidingMenu_shadowDrawable = 8;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#shadowWidth}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+ @attr name com.dsht.kerneltweaker:shadowWidth
+ */
+ public static final int SlidingMenu_shadowWidth = 9;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#touchModeAbove}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be one of the following constant values.</p>
+<table>
+<colgroup align="left" />
+<colgroup align="left" />
+<colgroup align="left" />
+<tr><th>Constant</th><th>Value</th><th>Description</th></tr>
+<tr><td><code>margin</code></td><td>0</td><td></td></tr>
+<tr><td><code>fullscreen</code></td><td>1</td><td></td></tr>
+</table>
+ @attr name com.dsht.kerneltweaker:touchModeAbove
+ */
+ public static final int SlidingMenu_touchModeAbove = 6;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#touchModeBehind}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be one of the following constant values.</p>
+<table>
+<colgroup align="left" />
+<colgroup align="left" />
+<colgroup align="left" />
+<tr><th>Constant</th><th>Value</th><th>Description</th></tr>
+<tr><td><code>margin</code></td><td>0</td><td></td></tr>
+<tr><td><code>fullscreen</code></td><td>1</td><td></td></tr>
+</table>
+ @attr name com.dsht.kerneltweaker:touchModeBehind
+ */
+ public static final int SlidingMenu_touchModeBehind = 7;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#viewAbove}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ @attr name com.dsht.kerneltweaker:viewAbove
+ */
+ public static final int SlidingMenu_viewAbove = 1;
+ /**
+ <p>This symbol is the offset where the {@link com.dsht.kerneltweaker.R.attr#viewBehind}
+ attribute's value can be found in the {@link #SlidingMenu} array.
+
+
+ <p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+ @attr name com.dsht.kerneltweaker:viewBehind
+ */
+ public static final int SlidingMenu_viewBehind = 2;
+ };
+}
diff --git a/gen/com/jeremyfeinstein/slidingmenu/lib/R.java b/gen/com/jeremyfeinstein/slidingmenu/lib/R.java
new file mode 100644
index 0000000..64e3ac0
--- /dev/null
+++ b/gen/com/jeremyfeinstein/slidingmenu/lib/R.java
@@ -0,0 +1,54 @@
+/* AUTO-GENERATED FILE. DO NOT MODIFY.
+ *
+ * This class was automatically generated by the
+ * aapt tool from the resource data it found. It
+ * should not be modified by hand.
+ */
+package com.jeremyfeinstein.slidingmenu.lib;
+
+public final class R {
+ public static final class attr {
+ public static final int behindOffset = 0x7f010003;
+ public static final int behindScrollScale = 0x7f010005;
+ public static final int behindWidth = 0x7f010004;
+ public static final int fadeDegree = 0x7f01000b;
+ public static final int fadeEnabled = 0x7f01000a;
+ public static final int mode = 0x7f010000;
+ public static final int selectorDrawable = 0x7f01000d;
+ public static final int selectorEnabled = 0x7f01000c;
+ public static final int shadowDrawable = 0x7f010008;
+ public static final int shadowWidth = 0x7f010009;
+ public static final int touchModeAbove = 0x7f010006;
+ public static final int touchModeBehind = 0x7f010007;
+ public static final int viewAbove = 0x7f010001;
+ public static final int viewBehind = 0x7f010002;
+ }
+ public static final class id {
+ public static final int fullscreen = 0x7f060003;
+ public static final int left = 0x7f060000;
+ public static final int margin = 0x7f060002;
+ public static final int right = 0x7f060001;
+ public static final int selected_view = 0x7f060004;
+ public static final int slidingmenumain = 0x7f06004b;
+ }
+ public static final class layout {
+ public static final int slidingmenumain = 0x7f030020;
+ }
+ public static final class styleable {
+ public static final int[] SlidingMenu = { 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, 0x7f010004, 0x7f010005, 0x7f010006, 0x7f010007, 0x7f010008, 0x7f010009, 0x7f01000a, 0x7f01000b, 0x7f01000c, 0x7f01000d };
+ public static final int SlidingMenu_behindOffset = 3;
+ public static final int SlidingMenu_behindScrollScale = 5;
+ public static final int SlidingMenu_behindWidth = 4;
+ public static final int SlidingMenu_fadeDegree = 11;
+ public static final int SlidingMenu_fadeEnabled = 10;
+ public static final int SlidingMenu_mode = 0;
+ public static final int SlidingMenu_selectorDrawable = 13;
+ public static final int SlidingMenu_selectorEnabled = 12;
+ public static final int SlidingMenu_shadowDrawable = 8;
+ public static final int SlidingMenu_shadowWidth = 9;
+ public static final int SlidingMenu_touchModeAbove = 6;
+ public static final int SlidingMenu_touchModeBehind = 7;
+ public static final int SlidingMenu_viewAbove = 1;
+ public static final int SlidingMenu_viewBehind = 2;
+ }
+}
diff --git a/ic_launcher-web.png b/ic_launcher-web.png
new file mode 100644
index 0000000..075fec4
--- /dev/null
+++ b/ic_launcher-web.png
Binary files differ
diff --git a/proguard-project.txt b/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/project.properties b/project.properties
new file mode 100644
index 0000000..166641c
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-19
+android.library.reference.1=../library-SlidingMenu
diff --git a/res/anim/card_flip_left_in.xml b/res/anim/card_flip_left_in.xml
new file mode 100644
index 0000000..cbb471c
--- /dev/null
+++ b/res/anim/card_flip_left_in.xml
@@ -0,0 +1,19 @@
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <scale
+ android:duration="100"
+ android:fillAfter="false"
+ android:fromXScale="0.0"
+ android:fromYScale="1.0"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:startOffset="200"
+ android:toXScale="1.0"
+ android:toYScale="1.0" />
+
+ <translate
+ android:duration="100"
+ android:fromXDelta="50%"
+ android:startOffset="200"
+ android:toXDelta="0" />
+
+</set> \ No newline at end of file
diff --git a/res/anim/card_flip_right_out.xml b/res/anim/card_flip_right_out.xml
new file mode 100644
index 0000000..12468b1
--- /dev/null
+++ b/res/anim/card_flip_right_out.xml
@@ -0,0 +1,17 @@
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <scale
+ android:duration="100"
+ android:fillAfter="false"
+ android:fromXScale="1.0"
+ android:fromYScale="1.0"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:toXScale="0.0"
+ android:toYScale="1.0" />
+
+ <translate
+ android:duration="100"
+ android:fromXDelta="0"
+ android:toXDelta="50%" />
+
+</set> \ No newline at end of file
diff --git a/res/anim/push_right_in.xml b/res/anim/push_right_in.xml
new file mode 100755
index 0000000..30f008e
--- /dev/null
+++ b/res/anim/push_right_in.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate
+ android:fromXDelta="-100%p"
+ android:toXDelta="0"
+ android:duration="300" />
+ <alpha
+ android:fromAlpha="0.0"
+ android:toAlpha="1.0"
+ android:duration="300" />
+</set>
diff --git a/res/anim/push_right_out.xml b/res/anim/push_right_out.xml
new file mode 100755
index 0000000..779c200
--- /dev/null
+++ b/res/anim/push_right_out.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate
+ android:fromXDelta="0"
+ android:toXDelta="100%p"
+ android:duration="300" />
+ <alpha
+ android:fromAlpha="1.0"
+ android:toAlpha="0.0"
+ android:duration="300" />
+</set>
diff --git a/res/drawable-hdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png b/res/drawable-hdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..00ede43
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_btn_radio_off_disabled_holo_dark.png b/res/drawable-hdpi/apptheme_btn_radio_off_disabled_holo_dark.png
new file mode 100644
index 0000000..eb58648
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_btn_radio_off_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_btn_radio_off_focused_holo_dark.png b/res/drawable-hdpi/apptheme_btn_radio_off_focused_holo_dark.png
new file mode 100644
index 0000000..41260fb
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_btn_radio_off_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_btn_radio_off_holo_dark.png b/res/drawable-hdpi/apptheme_btn_radio_off_holo_dark.png
new file mode 100644
index 0000000..a4a2fc2
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_btn_radio_off_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_btn_radio_off_pressed_holo_dark.png b/res/drawable-hdpi/apptheme_btn_radio_off_pressed_holo_dark.png
new file mode 100644
index 0000000..05b150f
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_btn_radio_off_pressed_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png b/res/drawable-hdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..61346ca
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_btn_radio_on_disabled_holo_dark.png b/res/drawable-hdpi/apptheme_btn_radio_on_disabled_holo_dark.png
new file mode 100644
index 0000000..6ebb184
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_btn_radio_on_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_btn_radio_on_focused_holo_dark.png b/res/drawable-hdpi/apptheme_btn_radio_on_focused_holo_dark.png
new file mode 100644
index 0000000..bfd9dbe
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_btn_radio_on_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_btn_radio_on_holo_dark.png b/res/drawable-hdpi/apptheme_btn_radio_on_holo_dark.png
new file mode 100644
index 0000000..ecc2e95
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_btn_radio_on_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_btn_radio_on_pressed_holo_dark.png b/res/drawable-hdpi/apptheme_btn_radio_on_pressed_holo_dark.png
new file mode 100644
index 0000000..196fb3b
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_btn_radio_on_pressed_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_fastscroll_thumb_default_holo.png b/res/drawable-hdpi/apptheme_fastscroll_thumb_default_holo.png
new file mode 100644
index 0000000..1d05faa
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_fastscroll_thumb_default_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_fastscroll_thumb_pressed_holo.png b/res/drawable-hdpi/apptheme_fastscroll_thumb_pressed_holo.png
new file mode 100644
index 0000000..d129a00
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_fastscroll_thumb_pressed_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_scrubber_control_disabled_holo.png b/res/drawable-hdpi/apptheme_scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..a8128b1
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_scrubber_control_disabled_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_scrubber_control_focused_holo.png b/res/drawable-hdpi/apptheme_scrubber_control_focused_holo.png
new file mode 100644
index 0000000..6f411a5
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_scrubber_control_focused_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_scrubber_control_normal_holo.png b/res/drawable-hdpi/apptheme_scrubber_control_normal_holo.png
new file mode 100644
index 0000000..a113ac2
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_scrubber_control_normal_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_scrubber_control_pressed_holo.png b/res/drawable-hdpi/apptheme_scrubber_control_pressed_holo.png
new file mode 100644
index 0000000..0a22fa0
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_scrubber_control_pressed_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_scrubber_primary_holo.9.png b/res/drawable-hdpi/apptheme_scrubber_primary_holo.9.png
new file mode 100644
index 0000000..b03156f
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_scrubber_primary_holo.9.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_scrubber_secondary_holo.9.png b/res/drawable-hdpi/apptheme_scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..220b801
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_scrubber_secondary_holo.9.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_scrubber_track_holo_dark.9.png b/res/drawable-hdpi/apptheme_scrubber_track_holo_dark.9.png
new file mode 100644
index 0000000..0c0ccda
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_scrubber_track_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_textfield_activated_holo_dark.9.png b/res/drawable-hdpi/apptheme_textfield_activated_holo_dark.9.png
new file mode 100644
index 0000000..58c77c9
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_textfield_activated_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_textfield_default_holo_dark.9.png b/res/drawable-hdpi/apptheme_textfield_default_holo_dark.9.png
new file mode 100644
index 0000000..1073e3f
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_textfield_default_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_textfield_disabled_focused_holo_dark.9.png b/res/drawable-hdpi/apptheme_textfield_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..29e33e3
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_textfield_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_textfield_disabled_holo_dark.9.png b/res/drawable-hdpi/apptheme_textfield_disabled_holo_dark.9.png
new file mode 100644
index 0000000..73ec37c
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_textfield_disabled_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/apptheme_textfield_focused_holo_dark.9.png b/res/drawable-hdpi/apptheme_textfield_focused_holo_dark.9.png
new file mode 100644
index 0000000..50dd046
--- /dev/null
+++ b/res/drawable-hdpi/apptheme_textfield_focused_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_radio_off_pressed_holo_light.png b/res/drawable-hdpi/btn_radio_off_pressed_holo_light.png
new file mode 100644
index 0000000..0d88e1b
--- /dev/null
+++ b/res/drawable-hdpi/btn_radio_off_pressed_holo_light.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_radio_on_pressed_holo_light.png b/res/drawable-hdpi/btn_radio_on_pressed_holo_light.png
new file mode 100644
index 0000000..7a4e106
--- /dev/null
+++ b/res/drawable-hdpi/btn_radio_on_pressed_holo_light.png
Binary files differ
diff --git a/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png b/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png
new file mode 100644
index 0000000..60e2cb2
--- /dev/null
+++ b/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png
Binary files differ
diff --git a/res/drawable-hdpi/divider_horizontal_holo_dark.9.png b/res/drawable-hdpi/divider_horizontal_holo_dark.9.png
new file mode 100644
index 0000000..3dfe6c2
--- /dev/null
+++ b/res/drawable-hdpi/divider_horizontal_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/divider_horizontal_holo_light.9.png b/res/drawable-hdpi/divider_horizontal_holo_light.9.png
new file mode 100644
index 0000000..ea38ebb
--- /dev/null
+++ b/res/drawable-hdpi/divider_horizontal_holo_light.9.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_add.png b/res/drawable-hdpi/ic_add.png
new file mode 100644
index 0000000..37e8490
--- /dev/null
+++ b/res/drawable-hdpi/ic_add.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_boot.png b/res/drawable-hdpi/ic_boot.png
new file mode 100644
index 0000000..4a7605d
--- /dev/null
+++ b/res/drawable-hdpi/ic_boot.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_checkbox__on.png b/res/drawable-hdpi/ic_checkbox__on.png
new file mode 100644
index 0000000..84e7a12
--- /dev/null
+++ b/res/drawable-hdpi/ic_checkbox__on.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_checkbox_off.png b/res/drawable-hdpi/ic_checkbox_off.png
new file mode 100644
index 0000000..2b945a5
--- /dev/null
+++ b/res/drawable-hdpi/ic_checkbox_off.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_colorpicker_swatch_selected.png b/res/drawable-hdpi/ic_colorpicker_swatch_selected.png
new file mode 100755
index 0000000..3cbfe1a
--- /dev/null
+++ b/res/drawable-hdpi/ic_colorpicker_swatch_selected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_delete.png b/res/drawable-hdpi/ic_delete.png
new file mode 100644
index 0000000..878b378
--- /dev/null
+++ b/res/drawable-hdpi/ic_delete.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_dots.png b/res/drawable-hdpi/ic_dots.png
new file mode 100644
index 0000000..a074c10
--- /dev/null
+++ b/res/drawable-hdpi/ic_dots.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_favcheck.png b/res/drawable-hdpi/ic_favcheck.png
new file mode 100644
index 0000000..d4129a8
--- /dev/null
+++ b/res/drawable-hdpi/ic_favcheck.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_favuncheck.png b/res/drawable-hdpi/ic_favuncheck.png
new file mode 100644
index 0000000..6fd48bb
--- /dev/null
+++ b/res/drawable-hdpi/ic_favuncheck.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_file.png b/res/drawable-hdpi/ic_file.png
new file mode 100644
index 0000000..66e9cc2
--- /dev/null
+++ b/res/drawable-hdpi/ic_file.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_folder.png b/res/drawable-hdpi/ic_folder.png
new file mode 100644
index 0000000..aa13e80
--- /dev/null
+++ b/res/drawable-hdpi/ic_folder.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_help.png b/res/drawable-hdpi/ic_help.png
new file mode 100644
index 0000000..f59faac
--- /dev/null
+++ b/res/drawable-hdpi/ic_help.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..e5c5738
--- /dev/null
+++ b/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_refresh.png b/res/drawable-hdpi/ic_menu_refresh.png
new file mode 100755
index 0000000..ecaa789
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_refresh.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_plus.png b/res/drawable-hdpi/ic_plus.png
new file mode 100644
index 0000000..81d535d
--- /dev/null
+++ b/res/drawable-hdpi/ic_plus.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_sdcard.png b/res/drawable-hdpi/ic_sdcard.png
new file mode 100644
index 0000000..5dc2219
--- /dev/null
+++ b/res/drawable-hdpi/ic_sdcard.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png b/res/drawable-mdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..d8fa616
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_btn_radio_off_disabled_holo_dark.png b/res/drawable-mdpi/apptheme_btn_radio_off_disabled_holo_dark.png
new file mode 100644
index 0000000..20d3d77
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_btn_radio_off_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_btn_radio_off_focused_holo_dark.png b/res/drawable-mdpi/apptheme_btn_radio_off_focused_holo_dark.png
new file mode 100644
index 0000000..de93d7a
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_btn_radio_off_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_btn_radio_off_holo_dark.png b/res/drawable-mdpi/apptheme_btn_radio_off_holo_dark.png
new file mode 100644
index 0000000..c7970a6
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_btn_radio_off_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_btn_radio_off_pressed_holo_dark.png b/res/drawable-mdpi/apptheme_btn_radio_off_pressed_holo_dark.png
new file mode 100644
index 0000000..1f48886
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_btn_radio_off_pressed_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png b/res/drawable-mdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..36cea0e
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_btn_radio_on_disabled_holo_dark.png b/res/drawable-mdpi/apptheme_btn_radio_on_disabled_holo_dark.png
new file mode 100644
index 0000000..605af76
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_btn_radio_on_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_btn_radio_on_focused_holo_dark.png b/res/drawable-mdpi/apptheme_btn_radio_on_focused_holo_dark.png
new file mode 100644
index 0000000..6f60b8e
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_btn_radio_on_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_btn_radio_on_holo_dark.png b/res/drawable-mdpi/apptheme_btn_radio_on_holo_dark.png
new file mode 100644
index 0000000..036b27d
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_btn_radio_on_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_btn_radio_on_pressed_holo_dark.png b/res/drawable-mdpi/apptheme_btn_radio_on_pressed_holo_dark.png
new file mode 100644
index 0000000..5f36790
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_btn_radio_on_pressed_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_fastscroll_thumb_default_holo.png b/res/drawable-mdpi/apptheme_fastscroll_thumb_default_holo.png
new file mode 100644
index 0000000..9959bdb
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_fastscroll_thumb_default_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_fastscroll_thumb_pressed_holo.png b/res/drawable-mdpi/apptheme_fastscroll_thumb_pressed_holo.png
new file mode 100644
index 0000000..d69a89f
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_fastscroll_thumb_pressed_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_scrubber_control_disabled_holo.png b/res/drawable-mdpi/apptheme_scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..aff60fc
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_scrubber_control_disabled_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_scrubber_control_focused_holo.png b/res/drawable-mdpi/apptheme_scrubber_control_focused_holo.png
new file mode 100644
index 0000000..72ce67e
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_scrubber_control_focused_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_scrubber_control_normal_holo.png b/res/drawable-mdpi/apptheme_scrubber_control_normal_holo.png
new file mode 100644
index 0000000..7f184e1
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_scrubber_control_normal_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_scrubber_control_pressed_holo.png b/res/drawable-mdpi/apptheme_scrubber_control_pressed_holo.png
new file mode 100644
index 0000000..d0c1244
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_scrubber_control_pressed_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_scrubber_primary_holo.9.png b/res/drawable-mdpi/apptheme_scrubber_primary_holo.9.png
new file mode 100644
index 0000000..dad6d2e
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_scrubber_primary_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_scrubber_secondary_holo.9.png b/res/drawable-mdpi/apptheme_scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..d7d1a8e
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_scrubber_secondary_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_scrubber_track_holo_dark.9.png b/res/drawable-mdpi/apptheme_scrubber_track_holo_dark.9.png
new file mode 100644
index 0000000..b91a4ee
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_scrubber_track_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_textfield_activated_holo_dark.9.png b/res/drawable-mdpi/apptheme_textfield_activated_holo_dark.9.png
new file mode 100644
index 0000000..06ac625
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_textfield_activated_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_textfield_default_holo_dark.9.png b/res/drawable-mdpi/apptheme_textfield_default_holo_dark.9.png
new file mode 100644
index 0000000..2e2ed1e
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_textfield_default_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_textfield_disabled_focused_holo_dark.9.png b/res/drawable-mdpi/apptheme_textfield_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..24bdf71
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_textfield_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_textfield_disabled_holo_dark.9.png b/res/drawable-mdpi/apptheme_textfield_disabled_holo_dark.9.png
new file mode 100644
index 0000000..709f5ef
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_textfield_disabled_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/apptheme_textfield_focused_holo_dark.9.png b/res/drawable-mdpi/apptheme_textfield_focused_holo_dark.9.png
new file mode 100644
index 0000000..8624869
--- /dev/null
+++ b/res/drawable-mdpi/apptheme_textfield_focused_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_radio_off_pressed_holo_light.png b/res/drawable-mdpi/btn_radio_off_pressed_holo_light.png
new file mode 100644
index 0000000..e86da2a
--- /dev/null
+++ b/res/drawable-mdpi/btn_radio_off_pressed_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_radio_on_pressed_holo_light.png b/res/drawable-mdpi/btn_radio_on_pressed_holo_light.png
new file mode 100644
index 0000000..51b274a
--- /dev/null
+++ b/res/drawable-mdpi/btn_radio_on_pressed_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/divider_horizontal_dark_opaque.9.png b/res/drawable-mdpi/divider_horizontal_dark_opaque.9.png
new file mode 100644
index 0000000..60e2cb2
--- /dev/null
+++ b/res/drawable-mdpi/divider_horizontal_dark_opaque.9.png
Binary files differ
diff --git a/res/drawable-mdpi/divider_horizontal_holo_dark.9.png b/res/drawable-mdpi/divider_horizontal_holo_dark.9.png
new file mode 100644
index 0000000..d6548c6
--- /dev/null
+++ b/res/drawable-mdpi/divider_horizontal_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/divider_horizontal_holo_light.9.png b/res/drawable-mdpi/divider_horizontal_holo_light.9.png
new file mode 100644
index 0000000..9a42dd2
--- /dev/null
+++ b/res/drawable-mdpi/divider_horizontal_holo_light.9.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_add.png b/res/drawable-mdpi/ic_add.png
new file mode 100644
index 0000000..ae17f17
--- /dev/null
+++ b/res/drawable-mdpi/ic_add.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_boot.png b/res/drawable-mdpi/ic_boot.png
new file mode 100644
index 0000000..a741661
--- /dev/null
+++ b/res/drawable-mdpi/ic_boot.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_checkbox__on.png b/res/drawable-mdpi/ic_checkbox__on.png
new file mode 100644
index 0000000..b6c5142
--- /dev/null
+++ b/res/drawable-mdpi/ic_checkbox__on.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_checkbox_off.png b/res/drawable-mdpi/ic_checkbox_off.png
new file mode 100644
index 0000000..54c77a6
--- /dev/null
+++ b/res/drawable-mdpi/ic_checkbox_off.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_colorpicker_swatch_selected.png b/res/drawable-mdpi/ic_colorpicker_swatch_selected.png
new file mode 100755
index 0000000..acbdeca
--- /dev/null
+++ b/res/drawable-mdpi/ic_colorpicker_swatch_selected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_delete.png b/res/drawable-mdpi/ic_delete.png
new file mode 100644
index 0000000..5ba2454
--- /dev/null
+++ b/res/drawable-mdpi/ic_delete.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_dots.png b/res/drawable-mdpi/ic_dots.png
new file mode 100644
index 0000000..b6d614f
--- /dev/null
+++ b/res/drawable-mdpi/ic_dots.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_favcheck.png b/res/drawable-mdpi/ic_favcheck.png
new file mode 100644
index 0000000..9d79d3a
--- /dev/null
+++ b/res/drawable-mdpi/ic_favcheck.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_favuncheck.png b/res/drawable-mdpi/ic_favuncheck.png
new file mode 100644
index 0000000..8919df5
--- /dev/null
+++ b/res/drawable-mdpi/ic_favuncheck.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_file.png b/res/drawable-mdpi/ic_file.png
new file mode 100644
index 0000000..69f1c18
--- /dev/null
+++ b/res/drawable-mdpi/ic_file.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_folder.png b/res/drawable-mdpi/ic_folder.png
new file mode 100644
index 0000000..8014bf1
--- /dev/null
+++ b/res/drawable-mdpi/ic_folder.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_help.png b/res/drawable-mdpi/ic_help.png
new file mode 100644
index 0000000..8057106
--- /dev/null
+++ b/res/drawable-mdpi/ic_help.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..8984665
--- /dev/null
+++ b/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_refresh.png b/res/drawable-mdpi/ic_menu_refresh.png
new file mode 100755
index 0000000..43cf797
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_refresh.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_plus.png b/res/drawable-mdpi/ic_plus.png
new file mode 100644
index 0000000..a4c84f0
--- /dev/null
+++ b/res/drawable-mdpi/ic_plus.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_sdcard.png b/res/drawable-mdpi/ic_sdcard.png
new file mode 100644
index 0000000..b207dcb
--- /dev/null
+++ b/res/drawable-mdpi/ic_sdcard.png
Binary files differ
diff --git a/res/drawable-nodpi/aokp.png b/res/drawable-nodpi/aokp.png
new file mode 100644
index 0000000..dfb1572
--- /dev/null
+++ b/res/drawable-nodpi/aokp.png
Binary files differ
diff --git a/res/drawable-nodpi/backup.png b/res/drawable-nodpi/backup.png
new file mode 100644
index 0000000..7f6012b
--- /dev/null
+++ b/res/drawable-nodpi/backup.png
Binary files differ
diff --git a/res/drawable-nodpi/bar_chart.png b/res/drawable-nodpi/bar_chart.png
new file mode 100644
index 0000000..f474bf7
--- /dev/null
+++ b/res/drawable-nodpi/bar_chart.png
Binary files differ
diff --git a/res/drawable-nodpi/battery_med.png b/res/drawable-nodpi/battery_med.png
new file mode 100644
index 0000000..edb4a2e
--- /dev/null
+++ b/res/drawable-nodpi/battery_med.png
Binary files differ
diff --git a/res/drawable-nodpi/beaker.png b/res/drawable-nodpi/beaker.png
new file mode 100644
index 0000000..1929e3d
--- /dev/null
+++ b/res/drawable-nodpi/beaker.png
Binary files differ
diff --git a/res/drawable-nodpi/cesco.png b/res/drawable-nodpi/cesco.png
new file mode 100644
index 0000000..4cffcbe
--- /dev/null
+++ b/res/drawable-nodpi/cesco.png
Binary files differ
diff --git a/res/drawable-nodpi/command.png b/res/drawable-nodpi/command.png
new file mode 100644
index 0000000..f022f07
--- /dev/null
+++ b/res/drawable-nodpi/command.png
Binary files differ
diff --git a/res/drawable-nodpi/doc.png b/res/drawable-nodpi/doc.png
new file mode 100644
index 0000000..6cacf9a
--- /dev/null
+++ b/res/drawable-nodpi/doc.png
Binary files differ
diff --git a/res/drawable-nodpi/doc_zip.png b/res/drawable-nodpi/doc_zip.png
new file mode 100644
index 0000000..6ccd250
--- /dev/null
+++ b/res/drawable-nodpi/doc_zip.png
Binary files differ
diff --git a/res/drawable-nodpi/dsht_logo.png b/res/drawable-nodpi/dsht_logo.png
new file mode 100644
index 0000000..adb1d7a
--- /dev/null
+++ b/res/drawable-nodpi/dsht_logo.png
Binary files differ
diff --git a/res/drawable-nodpi/du.png b/res/drawable-nodpi/du.png
new file mode 100644
index 0000000..3ef0f96
--- /dev/null
+++ b/res/drawable-nodpi/du.png
Binary files differ
diff --git a/res/drawable-nodpi/eye.png b/res/drawable-nodpi/eye.png
new file mode 100644
index 0000000..490069f
--- /dev/null
+++ b/res/drawable-nodpi/eye.png
Binary files differ
diff --git a/res/drawable-nodpi/flash_on.png b/res/drawable-nodpi/flash_on.png
new file mode 100644
index 0000000..35da126
--- /dev/null
+++ b/res/drawable-nodpi/flash_on.png
Binary files differ
diff --git a/res/drawable-nodpi/folder.png b/res/drawable-nodpi/folder.png
new file mode 100644
index 0000000..457e5de
--- /dev/null
+++ b/res/drawable-nodpi/folder.png
Binary files differ
diff --git a/res/drawable-nodpi/github.png b/res/drawable-nodpi/github.png
new file mode 100644
index 0000000..971af96
--- /dev/null
+++ b/res/drawable-nodpi/github.png
Binary files differ
diff --git a/res/drawable-nodpi/heart.png b/res/drawable-nodpi/heart.png
new file mode 100644
index 0000000..5c3a56b
--- /dev/null
+++ b/res/drawable-nodpi/heart.png
Binary files differ
diff --git a/res/drawable-nodpi/info.png b/res/drawable-nodpi/info.png
new file mode 100644
index 0000000..5b4eff3
--- /dev/null
+++ b/res/drawable-nodpi/info.png
Binary files differ
diff --git a/res/drawable-nodpi/lcd.png b/res/drawable-nodpi/lcd.png
new file mode 100644
index 0000000..4cc4aa1
--- /dev/null
+++ b/res/drawable-nodpi/lcd.png
Binary files differ
diff --git a/res/drawable-nodpi/life_guard.png b/res/drawable-nodpi/life_guard.png
new file mode 100644
index 0000000..71807e6
--- /dev/null
+++ b/res/drawable-nodpi/life_guard.png
Binary files differ
diff --git a/res/drawable-nodpi/magic_wand.png b/res/drawable-nodpi/magic_wand.png
new file mode 100644
index 0000000..e7a44d8
--- /dev/null
+++ b/res/drawable-nodpi/magic_wand.png
Binary files differ
diff --git a/res/drawable-nodpi/meter.png b/res/drawable-nodpi/meter.png
new file mode 100644
index 0000000..ba7dbfa
--- /dev/null
+++ b/res/drawable-nodpi/meter.png
Binary files differ
diff --git a/res/drawable-nodpi/omni.png b/res/drawable-nodpi/omni.png
new file mode 100644
index 0000000..2ecf49c
--- /dev/null
+++ b/res/drawable-nodpi/omni.png
Binary files differ
diff --git a/res/drawable-nodpi/plus_minus.png b/res/drawable-nodpi/plus_minus.png
new file mode 100644
index 0000000..1ce40b8
--- /dev/null
+++ b/res/drawable-nodpi/plus_minus.png
Binary files differ
diff --git a/res/drawable-nodpi/radiation.png b/res/drawable-nodpi/radiation.png
new file mode 100644
index 0000000..a288f76
--- /dev/null
+++ b/res/drawable-nodpi/radiation.png
Binary files differ
diff --git a/res/drawable-nodpi/settings_one.png b/res/drawable-nodpi/settings_one.png
new file mode 100644
index 0000000..6f94af2
--- /dev/null
+++ b/res/drawable-nodpi/settings_one.png
Binary files differ
diff --git a/res/drawable-nodpi/settings_two.png b/res/drawable-nodpi/settings_two.png
new file mode 100644
index 0000000..da74c32
--- /dev/null
+++ b/res/drawable-nodpi/settings_two.png
Binary files differ
diff --git a/res/drawable-nodpi/sollyx_google.png b/res/drawable-nodpi/sollyx_google.png
new file mode 100644
index 0000000..a4c8fdb
--- /dev/null
+++ b/res/drawable-nodpi/sollyx_google.png
Binary files differ
diff --git a/res/drawable-nodpi/veil.png b/res/drawable-nodpi/veil.png
new file mode 100644
index 0000000..f69f941
--- /dev/null
+++ b/res/drawable-nodpi/veil.png
Binary files differ
diff --git a/res/drawable-xhdpi/ab_texture_tile.png b/res/drawable-xhdpi/ab_texture_tile.png
new file mode 100644
index 0000000..b2f9906
--- /dev/null
+++ b/res/drawable-xhdpi/ab_texture_tile.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png b/res/drawable-xhdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..8790d22
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_btn_radio_off_disabled_holo_dark.png b/res/drawable-xhdpi/apptheme_btn_radio_off_disabled_holo_dark.png
new file mode 100644
index 0000000..aa5f830
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_btn_radio_off_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_btn_radio_off_focused_holo_dark.png b/res/drawable-xhdpi/apptheme_btn_radio_off_focused_holo_dark.png
new file mode 100644
index 0000000..6436e47
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_btn_radio_off_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_btn_radio_off_holo_dark.png b/res/drawable-xhdpi/apptheme_btn_radio_off_holo_dark.png
new file mode 100644
index 0000000..f02cf03
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_btn_radio_off_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_btn_radio_off_pressed_holo_dark.png b/res/drawable-xhdpi/apptheme_btn_radio_off_pressed_holo_dark.png
new file mode 100644
index 0000000..f37b9e8
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_btn_radio_off_pressed_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png b/res/drawable-xhdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..273266f
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_btn_radio_on_disabled_holo_dark.png b/res/drawable-xhdpi/apptheme_btn_radio_on_disabled_holo_dark.png
new file mode 100644
index 0000000..346909d
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_btn_radio_on_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_btn_radio_on_focused_holo_dark.png b/res/drawable-xhdpi/apptheme_btn_radio_on_focused_holo_dark.png
new file mode 100644
index 0000000..a4a201e
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_btn_radio_on_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_btn_radio_on_holo_dark.png b/res/drawable-xhdpi/apptheme_btn_radio_on_holo_dark.png
new file mode 100644
index 0000000..921d09c
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_btn_radio_on_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_btn_radio_on_pressed_holo_dark.png b/res/drawable-xhdpi/apptheme_btn_radio_on_pressed_holo_dark.png
new file mode 100644
index 0000000..4d85a31
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_btn_radio_on_pressed_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_fastscroll_thumb_default_holo.png b/res/drawable-xhdpi/apptheme_fastscroll_thumb_default_holo.png
new file mode 100644
index 0000000..a245f8b
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_fastscroll_thumb_default_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_fastscroll_thumb_pressed_holo.png b/res/drawable-xhdpi/apptheme_fastscroll_thumb_pressed_holo.png
new file mode 100644
index 0000000..cdc9d05
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_fastscroll_thumb_pressed_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_scrubber_control_disabled_holo.png b/res/drawable-xhdpi/apptheme_scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..8c0a2ae
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_scrubber_control_disabled_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_scrubber_control_focused_holo.png b/res/drawable-xhdpi/apptheme_scrubber_control_focused_holo.png
new file mode 100644
index 0000000..7c22e4f
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_scrubber_control_focused_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_scrubber_control_normal_holo.png b/res/drawable-xhdpi/apptheme_scrubber_control_normal_holo.png
new file mode 100644
index 0000000..d9071ff
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_scrubber_control_normal_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_scrubber_control_pressed_holo.png b/res/drawable-xhdpi/apptheme_scrubber_control_pressed_holo.png
new file mode 100644
index 0000000..9db85c4
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_scrubber_control_pressed_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_scrubber_primary_holo.9.png b/res/drawable-xhdpi/apptheme_scrubber_primary_holo.9.png
new file mode 100644
index 0000000..085c7de
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_scrubber_primary_holo.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_scrubber_secondary_holo.9.png b/res/drawable-xhdpi/apptheme_scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..8b4b6c6
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_scrubber_secondary_holo.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_scrubber_track_holo_dark.9.png b/res/drawable-xhdpi/apptheme_scrubber_track_holo_dark.9.png
new file mode 100644
index 0000000..bfb2048
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_scrubber_track_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_textfield_activated_holo_dark.9.png b/res/drawable-xhdpi/apptheme_textfield_activated_holo_dark.9.png
new file mode 100644
index 0000000..aa5e6e4
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_textfield_activated_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_textfield_default_holo_dark.9.png b/res/drawable-xhdpi/apptheme_textfield_default_holo_dark.9.png
new file mode 100644
index 0000000..ca1aab7
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_textfield_default_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_textfield_disabled_focused_holo_dark.9.png b/res/drawable-xhdpi/apptheme_textfield_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..a9767fc
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_textfield_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_textfield_disabled_holo_dark.9.png b/res/drawable-xhdpi/apptheme_textfield_disabled_holo_dark.9.png
new file mode 100644
index 0000000..d78b10d
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_textfield_disabled_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/apptheme_textfield_focused_holo_dark.9.png b/res/drawable-xhdpi/apptheme_textfield_focused_holo_dark.9.png
new file mode 100644
index 0000000..5cd1baa
--- /dev/null
+++ b/res/drawable-xhdpi/apptheme_textfield_focused_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/bg_stripes_dark.png b/res/drawable-xhdpi/bg_stripes_dark.png
new file mode 100644
index 0000000..76aab7c
--- /dev/null
+++ b/res/drawable-xhdpi/bg_stripes_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/bg_stripes_dark_light.png b/res/drawable-xhdpi/bg_stripes_dark_light.png
new file mode 100644
index 0000000..ad44cf2
--- /dev/null
+++ b/res/drawable-xhdpi/bg_stripes_dark_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_radio_off_pressed_holo_light.png b/res/drawable-xhdpi/btn_radio_off_pressed_holo_light.png
new file mode 100644
index 0000000..f5582be
--- /dev/null
+++ b/res/drawable-xhdpi/btn_radio_off_pressed_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_radio_on_pressed_holo_light.png b/res/drawable-xhdpi/btn_radio_on_pressed_holo_light.png
new file mode 100644
index 0000000..d4f7ce9
--- /dev/null
+++ b/res/drawable-xhdpi/btn_radio_on_pressed_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/divider_horizontal_dark_opaque.9.png b/res/drawable-xhdpi/divider_horizontal_dark_opaque.9.png
new file mode 100644
index 0000000..60e2cb2
--- /dev/null
+++ b/res/drawable-xhdpi/divider_horizontal_dark_opaque.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/divider_horizontal_holo_dark.9.png b/res/drawable-xhdpi/divider_horizontal_holo_dark.9.png
new file mode 100644
index 0000000..48a88b8
--- /dev/null
+++ b/res/drawable-xhdpi/divider_horizontal_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/divider_horizontal_holo_light.9.png b/res/drawable-xhdpi/divider_horizontal_holo_light.9.png
new file mode 100644
index 0000000..712aef2
--- /dev/null
+++ b/res/drawable-xhdpi/divider_horizontal_holo_light.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_add.png b/res/drawable-xhdpi/ic_add.png
new file mode 100644
index 0000000..849e3eb
--- /dev/null
+++ b/res/drawable-xhdpi/ic_add.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_boot.png b/res/drawable-xhdpi/ic_boot.png
new file mode 100644
index 0000000..707ba7c
--- /dev/null
+++ b/res/drawable-xhdpi/ic_boot.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_checkbox__on.png b/res/drawable-xhdpi/ic_checkbox__on.png
new file mode 100644
index 0000000..f0645d2
--- /dev/null
+++ b/res/drawable-xhdpi/ic_checkbox__on.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_checkbox_off.png b/res/drawable-xhdpi/ic_checkbox_off.png
new file mode 100644
index 0000000..8fd3569
--- /dev/null
+++ b/res/drawable-xhdpi/ic_checkbox_off.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_colorpicker_swatch_selected.png b/res/drawable-xhdpi/ic_colorpicker_swatch_selected.png
new file mode 100755
index 0000000..812ff2c
--- /dev/null
+++ b/res/drawable-xhdpi/ic_colorpicker_swatch_selected.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_delete.png b/res/drawable-xhdpi/ic_delete.png
new file mode 100644
index 0000000..09ce75e
--- /dev/null
+++ b/res/drawable-xhdpi/ic_delete.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dots.png b/res/drawable-xhdpi/ic_dots.png
new file mode 100644
index 0000000..7be3c2a
--- /dev/null
+++ b/res/drawable-xhdpi/ic_dots.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_favcheck.png b/res/drawable-xhdpi/ic_favcheck.png
new file mode 100644
index 0000000..7e4a82b
--- /dev/null
+++ b/res/drawable-xhdpi/ic_favcheck.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_favuncheck.png b/res/drawable-xhdpi/ic_favuncheck.png
new file mode 100644
index 0000000..4f1122c
--- /dev/null
+++ b/res/drawable-xhdpi/ic_favuncheck.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_file.png b/res/drawable-xhdpi/ic_file.png
new file mode 100644
index 0000000..a40712f
--- /dev/null
+++ b/res/drawable-xhdpi/ic_file.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_folder.png b/res/drawable-xhdpi/ic_folder.png
new file mode 100644
index 0000000..a343e97
--- /dev/null
+++ b/res/drawable-xhdpi/ic_folder.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_help.png b/res/drawable-xhdpi/ic_help.png
new file mode 100644
index 0000000..afde75b
--- /dev/null
+++ b/res/drawable-xhdpi/ic_help.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher.png b/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..15aa62a
--- /dev/null
+++ b/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_refresh.png b/res/drawable-xhdpi/ic_menu_refresh.png
new file mode 100755
index 0000000..166f3a3
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_refresh.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_plus.png b/res/drawable-xhdpi/ic_plus.png
new file mode 100644
index 0000000..93eae7c
--- /dev/null
+++ b/res/drawable-xhdpi/ic_plus.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sdcard.png b/res/drawable-xhdpi/ic_sdcard.png
new file mode 100644
index 0000000..45dd125
--- /dev/null
+++ b/res/drawable-xhdpi/ic_sdcard.png
Binary files differ
diff --git a/res/drawable-xhdpi/view_pager_background_texture.png b/res/drawable-xhdpi/view_pager_background_texture.png
new file mode 100644
index 0000000..8b85814
--- /dev/null
+++ b/res/drawable-xhdpi/view_pager_background_texture.png
Binary files differ
diff --git a/res/drawable-xhdpi/view_pager_background_texture_light.png b/res/drawable-xhdpi/view_pager_background_texture_light.png
new file mode 100644
index 0000000..c5023a3
--- /dev/null
+++ b/res/drawable-xhdpi/view_pager_background_texture_light.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png b/res/drawable-xxhdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..fc44d18
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_btn_radio_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_btn_radio_off_disabled_holo_dark.png b/res/drawable-xxhdpi/apptheme_btn_radio_off_disabled_holo_dark.png
new file mode 100644
index 0000000..946936e
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_btn_radio_off_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_btn_radio_off_focused_holo_dark.png b/res/drawable-xxhdpi/apptheme_btn_radio_off_focused_holo_dark.png
new file mode 100644
index 0000000..eee7a8b
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_btn_radio_off_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_btn_radio_off_holo_dark.png b/res/drawable-xxhdpi/apptheme_btn_radio_off_holo_dark.png
new file mode 100644
index 0000000..a6e8700
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_btn_radio_off_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_btn_radio_off_pressed_holo_dark.png b/res/drawable-xxhdpi/apptheme_btn_radio_off_pressed_holo_dark.png
new file mode 100644
index 0000000..37b50b0
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_btn_radio_off_pressed_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png b/res/drawable-xxhdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..eef5996
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_btn_radio_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_btn_radio_on_disabled_holo_dark.png b/res/drawable-xxhdpi/apptheme_btn_radio_on_disabled_holo_dark.png
new file mode 100644
index 0000000..66b833d
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_btn_radio_on_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_btn_radio_on_focused_holo_dark.png b/res/drawable-xxhdpi/apptheme_btn_radio_on_focused_holo_dark.png
new file mode 100644
index 0000000..d70fb29
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_btn_radio_on_focused_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_btn_radio_on_holo_dark.png b/res/drawable-xxhdpi/apptheme_btn_radio_on_holo_dark.png
new file mode 100644
index 0000000..034be02
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_btn_radio_on_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_btn_radio_on_pressed_holo_dark.png b/res/drawable-xxhdpi/apptheme_btn_radio_on_pressed_holo_dark.png
new file mode 100644
index 0000000..7a8fbd5
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_btn_radio_on_pressed_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_fastscroll_thumb_default_holo.png b/res/drawable-xxhdpi/apptheme_fastscroll_thumb_default_holo.png
new file mode 100644
index 0000000..a0669dc
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_fastscroll_thumb_default_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_fastscroll_thumb_pressed_holo.png b/res/drawable-xxhdpi/apptheme_fastscroll_thumb_pressed_holo.png
new file mode 100644
index 0000000..b1fcb2e
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_fastscroll_thumb_pressed_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_scrubber_control_disabled_holo.png b/res/drawable-xxhdpi/apptheme_scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..05b8644
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_scrubber_control_disabled_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_scrubber_control_focused_holo.png b/res/drawable-xxhdpi/apptheme_scrubber_control_focused_holo.png
new file mode 100644
index 0000000..7aa3799
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_scrubber_control_focused_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_scrubber_control_normal_holo.png b/res/drawable-xxhdpi/apptheme_scrubber_control_normal_holo.png
new file mode 100644
index 0000000..dc2766d
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_scrubber_control_normal_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_scrubber_control_pressed_holo.png b/res/drawable-xxhdpi/apptheme_scrubber_control_pressed_holo.png
new file mode 100644
index 0000000..af8da6f
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_scrubber_control_pressed_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_scrubber_primary_holo.9.png b/res/drawable-xxhdpi/apptheme_scrubber_primary_holo.9.png
new file mode 100644
index 0000000..28043aa
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_scrubber_primary_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_scrubber_secondary_holo.9.png b/res/drawable-xxhdpi/apptheme_scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..29d93f6
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_scrubber_secondary_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_scrubber_track_holo_dark.9.png b/res/drawable-xxhdpi/apptheme_scrubber_track_holo_dark.9.png
new file mode 100644
index 0000000..4014860
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_scrubber_track_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_textfield_activated_holo_dark.9.png b/res/drawable-xxhdpi/apptheme_textfield_activated_holo_dark.9.png
new file mode 100644
index 0000000..c1e6e58
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_textfield_activated_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_textfield_default_holo_dark.9.png b/res/drawable-xxhdpi/apptheme_textfield_default_holo_dark.9.png
new file mode 100644
index 0000000..d5dbae1
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_textfield_default_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_textfield_disabled_focused_holo_dark.9.png b/res/drawable-xxhdpi/apptheme_textfield_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..bd775bb
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_textfield_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_textfield_disabled_holo_dark.9.png b/res/drawable-xxhdpi/apptheme_textfield_disabled_holo_dark.9.png
new file mode 100644
index 0000000..598eed1
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_textfield_disabled_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apptheme_textfield_focused_holo_dark.9.png b/res/drawable-xxhdpi/apptheme_textfield_focused_holo_dark.9.png
new file mode 100644
index 0000000..42ea8a2
--- /dev/null
+++ b/res/drawable-xxhdpi/apptheme_textfield_focused_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_radio_off_pressed_holo_light.png b/res/drawable-xxhdpi/btn_radio_off_pressed_holo_light.png
new file mode 100644
index 0000000..f5f406f
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_radio_off_pressed_holo_light.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_radio_on_pressed_holo_light.png b/res/drawable-xxhdpi/btn_radio_on_pressed_holo_light.png
new file mode 100644
index 0000000..ac2aee9
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_radio_on_pressed_holo_light.png
Binary files differ
diff --git a/res/drawable-xxhdpi/divider_horizontal_dark_opaque.9.png b/res/drawable-xxhdpi/divider_horizontal_dark_opaque.9.png
new file mode 100644
index 0000000..60e2cb2
--- /dev/null
+++ b/res/drawable-xxhdpi/divider_horizontal_dark_opaque.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_add.png b/res/drawable-xxhdpi/ic_add.png
new file mode 100644
index 0000000..972bdc4
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_add.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_boot.png b/res/drawable-xxhdpi/ic_boot.png
new file mode 100644
index 0000000..5e5d007
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_boot.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_checkbox__on.png b/res/drawable-xxhdpi/ic_checkbox__on.png
new file mode 100644
index 0000000..c8955d7
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_checkbox__on.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_checkbox_off.png b/res/drawable-xxhdpi/ic_checkbox_off.png
new file mode 100644
index 0000000..dddf44a
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_checkbox_off.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_delete.png b/res/drawable-xxhdpi/ic_delete.png
new file mode 100644
index 0000000..d5952ea
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_delete.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_dots.png b/res/drawable-xxhdpi/ic_dots.png
new file mode 100644
index 0000000..a0cb8a4
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_dots.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_favcheck.png b/res/drawable-xxhdpi/ic_favcheck.png
new file mode 100644
index 0000000..da69c7f
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_favcheck.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_favuncheck.png b/res/drawable-xxhdpi/ic_favuncheck.png
new file mode 100644
index 0000000..3c173ae
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_favuncheck.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_file.png b/res/drawable-xxhdpi/ic_file.png
new file mode 100644
index 0000000..7a31a10
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_file.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_folder.png b/res/drawable-xxhdpi/ic_folder.png
new file mode 100644
index 0000000..54b46c7
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_folder.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_help.png b/res/drawable-xxhdpi/ic_help.png
new file mode 100644
index 0000000..7259a00
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_help.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_launcher.png b/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..38d3d43
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_plus.png b/res/drawable-xxhdpi/ic_plus.png
new file mode 100644
index 0000000..7049567
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_plus.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_sdcard.png b/res/drawable-xxhdpi/ic_sdcard.png
new file mode 100644
index 0000000..612d418
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_sdcard.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_boot.png b/res/drawable-xxxhdpi/ic_boot.png
new file mode 100644
index 0000000..f6479cd
--- /dev/null
+++ b/res/drawable-xxxhdpi/ic_boot.png
Binary files differ
diff --git a/res/drawable/apptheme_btn_radio_holo_dark.xml b/res/drawable/apptheme_btn_radio_holo_dark.xml
new file mode 100644
index 0000000..f06d56e
--- /dev/null
+++ b/res/drawable/apptheme_btn_radio_holo_dark.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_checked="true" android:state_window_focused="false"
+ android:state_enabled="true"
+ android:drawable="@drawable/apptheme_btn_radio_on_holo_dark" />
+ <item android:state_checked="false" android:state_window_focused="false"
+ android:state_enabled="true"
+ android:drawable="@drawable/apptheme_btn_radio_off_holo_dark" />
+
+ <item android:state_checked="true" android:state_pressed="true"
+ android:state_enabled="true"
+ android:drawable="@drawable/apptheme_btn_radio_on_pressed_holo_dark" />
+ <item android:state_checked="false" android:state_pressed="true"
+ android:state_enabled="true"
+ android:drawable="@drawable/apptheme_btn_radio_off_pressed_holo_dark" />
+
+ <item android:state_checked="true" android:state_focused="true"
+ android:state_enabled="true"
+ android:drawable="@drawable/apptheme_btn_radio_on_focused_holo_dark" />
+ <item android:state_checked="false" android:state_focused="true"
+ android:state_enabled="true"
+ android:drawable="@drawable/apptheme_btn_radio_off_focused_holo_dark" />
+
+ <item android:state_checked="false" android:state_enabled="true"
+ android:drawable="@drawable/apptheme_btn_radio_off_holo_dark" />
+ <item android:state_checked="true" android:state_enabled="true"
+ android:drawable="@drawable/apptheme_btn_radio_on_holo_dark" />
+
+ <!-- Disabled states -->
+
+ <item android:state_checked="true" android:state_window_focused="false"
+ android:drawable="@drawable/apptheme_btn_radio_on_disabled_holo_dark" />
+ <item android:state_checked="false" android:state_window_focused="false"
+ android:drawable="@drawable/apptheme_btn_radio_off_disabled_holo_dark" />
+
+ <item android:state_checked="true" android:state_focused="true"
+ android:drawable="@drawable/apptheme_btn_radio_on_disabled_focused_holo_dark" />
+ <item android:state_checked="false" android:state_focused="true"
+ android:drawable="@drawable/apptheme_btn_radio_off_disabled_focused_holo_dark" />
+
+ <item android:state_checked="false" android:drawable="@drawable/apptheme_btn_radio_off_disabled_holo_dark" />
+ <item android:state_checked="true" android:drawable="@drawable/apptheme_btn_radio_on_disabled_holo_dark" />
+
+</selector>
diff --git a/res/drawable/apptheme_edit_text_holo_dark.xml b/res/drawable/apptheme_edit_text_holo_dark.xml
new file mode 100644
index 0000000..208e148
--- /dev/null
+++ b/res/drawable/apptheme_edit_text_holo_dark.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/apptheme_textfield_default_holo_dark" />
+ <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/apptheme_textfield_disabled_holo_dark" />
+ <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/apptheme_textfield_activated_holo_dark" />
+ <item android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/apptheme_textfield_focused_holo_dark" />
+ <item android:state_enabled="true" android:drawable="@drawable/apptheme_textfield_default_holo_dark" />
+ <item android:state_focused="true" android:drawable="@drawable/apptheme_textfield_disabled_focused_holo_dark" />
+ <item android:drawable="@drawable/apptheme_textfield_disabled_holo_dark" />
+</selector> \ No newline at end of file
diff --git a/res/drawable/apptheme_fastscroll_thumb_holo.xml b/res/drawable/apptheme_fastscroll_thumb_holo.xml
new file mode 100644
index 0000000..e7121f0
--- /dev/null
+++ b/res/drawable/apptheme_fastscroll_thumb_holo.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/apptheme_fastscroll_thumb_pressed_holo" />
+ <item android:drawable="@drawable/apptheme_fastscroll_thumb_default_holo" />
+</selector>
diff --git a/res/drawable/apptheme_scrubber_control_selector_holo_dark.xml b/res/drawable/apptheme_scrubber_control_selector_holo_dark.xml
new file mode 100644
index 0000000..4eb5c24
--- /dev/null
+++ b/res/drawable/apptheme_scrubber_control_selector_holo_dark.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:drawable="@drawable/apptheme_scrubber_control_disabled_holo" />
+ <item android:state_pressed="true" android:drawable="@drawable/apptheme_scrubber_control_pressed_holo" />
+ <item android:state_selected="true" android:drawable="@drawable/apptheme_scrubber_control_focused_holo" />
+ <item android:drawable="@drawable/apptheme_scrubber_control_normal_holo" />
+</selector>
diff --git a/res/drawable/apptheme_scrubber_progress_horizontal_holo_dark.xml b/res/drawable/apptheme_scrubber_progress_horizontal_holo_dark.xml
new file mode 100644
index 0000000..369624d
--- /dev/null
+++ b/res/drawable/apptheme_scrubber_progress_horizontal_holo_dark.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@android:id/background"
+ android:drawable="@drawable/apptheme_scrubber_track_holo_dark" />
+ <item android:id="@android:id/secondaryProgress">
+ <scale android:scaleWidth="100%"
+ android:drawable="@drawable/apptheme_scrubber_secondary_holo" />
+ </item>
+ <item android:id="@android:id/progress">
+ <scale android:scaleWidth="100%"
+ android:drawable="@drawable/apptheme_scrubber_primary_holo" />
+ </item>
+</layer-list>
diff --git a/res/drawable/background_holo_dark.xml b/res/drawable/background_holo_dark.xml
new file mode 100644
index 0000000..a925580
--- /dev/null
+++ b/res/drawable/background_holo_dark.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <gradient
+ android:startColor="#ff000000"
+ android:endColor="#ff272d33"
+ android:angle="270" />
+</shape> \ No newline at end of file
diff --git a/res/drawable/background_holo_light.xml b/res/drawable/background_holo_light.xml
new file mode 100644
index 0000000..6a8af8b
--- /dev/null
+++ b/res/drawable/background_holo_light.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <gradient
+ android:startColor="#ffe8e8e8"
+ android:endColor="#ffffffff"
+ android:angle="270" />
+</shape> \ No newline at end of file
diff --git a/res/drawable/bg_dark.xml b/res/drawable/bg_dark.xml
new file mode 100644
index 0000000..206f06c
--- /dev/null
+++ b/res/drawable/bg_dark.xml
@@ -0,0 +1,3 @@
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/view_pager_background_texture"
+ android:tileMode="repeat" /> \ No newline at end of file
diff --git a/res/drawable/bg_light.xml b/res/drawable/bg_light.xml
new file mode 100644
index 0000000..ef41c9c
--- /dev/null
+++ b/res/drawable/bg_light.xml
@@ -0,0 +1,3 @@
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/view_pager_background_texture_light"
+ android:tileMode="repeat" /> \ No newline at end of file
diff --git a/res/drawable/bg_menu_dark.xml b/res/drawable/bg_menu_dark.xml
new file mode 100644
index 0000000..79f8d7c
--- /dev/null
+++ b/res/drawable/bg_menu_dark.xml
@@ -0,0 +1,3 @@
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/bg_stripes_dark"
+ android:tileMode="repeat" /> \ No newline at end of file
diff --git a/res/drawable/bg_menu_light.xml b/res/drawable/bg_menu_light.xml
new file mode 100644
index 0000000..934f3b8
--- /dev/null
+++ b/res/drawable/bg_menu_light.xml
@@ -0,0 +1,3 @@
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/bg_stripes_dark_light"
+ android:tileMode="repeat" /> \ No newline at end of file
diff --git a/res/drawable/bottombutton.xml b/res/drawable/bottombutton.xml
new file mode 100644
index 0000000..79c9324
--- /dev/null
+++ b/res/drawable/bottombutton.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:drawable="@color/mca__list_item_bg_pressed" android:state_pressed="true"/>
+ <item android:drawable="@color/mca__list_item_bg_normal" android:state_selected="true"/>
+
+</selector> \ No newline at end of file
diff --git a/res/drawable/calendar_color_picker_swatch.xml b/res/drawable/calendar_color_picker_swatch.xml
new file mode 100755
index 0000000..db71091
--- /dev/null
+++ b/res/drawable/calendar_color_picker_swatch.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" /> \ No newline at end of file
diff --git a/res/drawable/calendar_color_square.xml b/res/drawable/calendar_color_square.xml
new file mode 100755
index 0000000..7be3333
--- /dev/null
+++ b/res/drawable/calendar_color_square.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" /> \ No newline at end of file
diff --git a/res/drawable/card_bg.xml b/res/drawable/card_bg.xml
new file mode 100644
index 0000000..a7fd70f
--- /dev/null
+++ b/res/drawable/card_bg.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="rectangle"
+ android:dither="true">
+
+ <corners android:radius="2dp"/>
+
+ <solid android:color="#101010" />
+
+ </shape>
+ </item>
+
+ <item android:bottom="2dp">
+ <shape android:shape="rectangle"
+ android:dither="true">
+
+ <corners android:radius="2dp" />
+
+ <solid android:color="#878787" />
+
+ <padding android:bottom="8dp"
+ android:left="8dp"
+ android:right="8dp"
+ android:top="8dp" />
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/res/drawable/checkbox_selector.xml b/res/drawable/checkbox_selector.xml
new file mode 100644
index 0000000..e9f4b30
--- /dev/null
+++ b/res/drawable/checkbox_selector.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:drawable="@drawable/ic_favcheck" android:state_checked="true"/>
+ <item android:drawable="@drawable/ic_favuncheck" android:state_checked="false"/>
+
+</selector> \ No newline at end of file
diff --git a/res/drawable/checkbox_selector_light.xml b/res/drawable/checkbox_selector_light.xml
new file mode 100644
index 0000000..5acb365
--- /dev/null
+++ b/res/drawable/checkbox_selector_light.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:drawable="@drawable/btn_radio_on_pressed_holo_light" android:state_checked="true"/>
+ <item android:drawable="@drawable/btn_radio_off_pressed_holo_light" android:state_checked="false"/>
+
+</selector> \ No newline at end of file
diff --git a/res/drawable/screen_background_selector_dark.xml b/res/drawable/screen_background_selector_dark.xml
new file mode 100644
index 0000000..8868a42
--- /dev/null
+++ b/res/drawable/screen_background_selector_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_accelerated="false"
+ android:drawable="@android:drawable/screen_background_dark" />
+ <item android:drawable="@drawable/background_holo_dark" />
+</selector> \ No newline at end of file
diff --git a/res/drawable/screen_background_selector_light.xml b/res/drawable/screen_background_selector_light.xml
new file mode 100644
index 0000000..65b67f0
--- /dev/null
+++ b/res/drawable/screen_background_selector_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_accelerated="false"
+ android:drawable="@android:drawable/screen_background_light" />
+ <item android:drawable="@drawable/background_holo_light" />
+</selector> \ No newline at end of file
diff --git a/res/drawable/selector.xml b/res/drawable/selector.xml
new file mode 100644
index 0000000..cbd8716
--- /dev/null
+++ b/res/drawable/selector.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:drawable="@color/mca__list_item_bg_pressed" android:state_pressed="true"/>
+ <item android:drawable="@color/mca__list_item_bg_checked" android:state_activated="true"/>
+ <item android:drawable="@color/mca__list_item_bg_normal" android:state_selected="true"/>
+
+</selector> \ No newline at end of file
diff --git a/res/drawable/shadow.xml b/res/drawable/shadow.xml
new file mode 100644
index 0000000..67bb1c5
--- /dev/null
+++ b/res/drawable/shadow.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <gradient
+ android:endColor="#33000000"
+ android:centerColor="#11000000"
+ android:startColor="#00000000" />
+
+</shape> \ No newline at end of file
diff --git a/res/drawable/shadow_right.xml b/res/drawable/shadow_right.xml
new file mode 100644
index 0000000..15e2fc5
--- /dev/null
+++ b/res/drawable/shadow_right.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <gradient
+ android:centerColor="#11000000"
+ android:endColor="#00000000"
+ android:startColor="#33000000" />
+
+</shape> \ No newline at end of file
diff --git a/res/drawable/top_shadow.xml b/res/drawable/top_shadow.xml
new file mode 100644
index 0000000..bccb91f
--- /dev/null
+++ b/res/drawable/top_shadow.xml
@@ -0,0 +1,9 @@
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle" >
+
+ <gradient
+ android:angle="270"
+ android:endColor="@android:color/transparent"
+ android:startColor="@android:color/black" />
+
+</shape> \ No newline at end of file
diff --git a/res/layout/activity_main.xml b/res/layout/activity_main.xml
new file mode 100644
index 0000000..b1d462b
--- /dev/null
+++ b/res/layout/activity_main.xml
@@ -0,0 +1,19 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:context=".MainActivity"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <com.astuetz.viewpager.extensions.PagerSlidingTabStrip
+ android:id="@+id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="48dp" />
+
+ <android.support.v4.view.ViewPager
+ android:id="@+id/pager"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+ </android.support.v4.view.ViewPager>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/activity_main_container.xml b/res/layout/activity_main_container.xml
new file mode 100644
index 0000000..0af5bdc
--- /dev/null
+++ b/res/layout/activity_main_container.xml
@@ -0,0 +1,6 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/activity_container"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+</FrameLayout> \ No newline at end of file
diff --git a/res/layout/backup_dialog_layout.xml b/res/layout/backup_dialog_layout.xml
new file mode 100644
index 0000000..ef82fe3
--- /dev/null
+++ b/res/layout/backup_dialog_layout.xml
@@ -0,0 +1,91 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_margin="10dp" >
+
+ <CheckBox
+ android:id="@+id/cb_system"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:text="System" />
+
+ <CheckBox
+ android:id="@+id/cb_data"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Data" />
+
+ <CheckBox
+ android:id="@+id/cb_secure"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Android Secure" />
+
+ <CheckBox
+ android:id="@+id/cb_boot"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Boot" />
+
+ <CheckBox
+ android:id="@+id/cb_cache"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Cache" />
+
+ <CheckBox
+ android:id="@+id/cb_recovery"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Recovery" />
+
+ <CheckBox
+ android:id="@+id/cb_compression"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:text="@string/bk_comp" />
+
+ <CheckBox
+ android:id="@+id/cb_md5"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:text="@string/bk_md5" />
+
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="10dp"
+ android:layout_marginTop="5dp"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Backup Name"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <EditText
+ android:id="@+id/et_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:layout_marginTop="3dp"
+ android:hint="backup name..."
+ android:ems="10"
+ android:fontFamily="sans-serif-condensed" />
+
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/backup_list.xml b/res/layout/backup_list.xml
new file mode 100644
index 0000000..f15aa30
--- /dev/null
+++ b/res/layout/backup_list.xml
@@ -0,0 +1,182 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:id="@+id/backup_boot"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:background="@drawable/selector" >
+
+ <ImageView
+ android:id="@+id/image"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_gravity="center"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_sdcard" />
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="4dp" >
+
+ <TextView
+ android:id="@+id/titleboot"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="3dp"
+ android:layout_marginRight="3dp"
+ android:layout_marginTop="3dp"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:fontFamily="sans-serif-condensed"
+ android:singleLine="true"
+ android:text="@string/bk_boot"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/summaryboot"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignStart="@android:id/title"
+ android:layout_marginLeft="3dp"
+ android:layout_marginRight="3dp"
+ android:fontFamily="sans-serif-light"
+ android:maxLines="4"
+ android:text="@string/bk_boot_desc"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <View
+ android:id="@+id/view1"
+ android:layout_width="fill_parent"
+ android:layout_height="1px"
+ android:layout_marginBottom="3dp"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:layout_marginTop="3dp"
+ android:background="#FFFFFF" />
+
+ <LinearLayout
+ android:id="@+id/backup_recovery"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ android:layout_marginBottom="3dp"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:background="@drawable/selector"
+ android:orientation="horizontal" >
+
+ <ImageView
+ android:id="@+id/image2"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_gravity="center"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_sdcard" />
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="4dp" >
+
+ <TextView
+ android:id="@+id/titlerecovery"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="3dp"
+ android:layout_marginRight="3dp"
+ android:layout_marginTop="3dp"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:fontFamily="sans-serif-condensed"
+ android:singleLine="true"
+ android:text="@string/bk_recovery"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/summaryrecovery"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="3dp"
+ android:layout_marginRight="3dp"
+ android:fontFamily="sans-serif-light"
+ android:maxLines="4"
+ android:text="@string/bk_recovery_desc"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <View
+ android:id="@+id/View2"
+ android:layout_width="fill_parent"
+ android:layout_height="1px"
+ android:layout_marginBottom="3dp"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:layout_marginTop="3dp"
+ android:background="#FFFFFF" />
+
+ <ListView
+ android:id="@+id/navbarlist"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+ </ListView>
+
+ <LinearLayout
+ android:id="@+id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="3dp"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:background="@drawable/selector"
+ android:clickable="true"
+ android:orientation="horizontal" >
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="4dp" >
+
+ <TextView
+ android:id="@+id/TextView02"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="3dp"
+ android:layout_marginRight="3dp"
+ android:layout_marginTop="3dp"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:fontFamily="sans-serif-condensed"
+ android:singleLine="true"
+ android:text="No Backups found"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/TextView01"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="3dp"
+ android:layout_marginRight="3dp"
+ android:fontFamily="sans-serif-thin"
+ android:maxLines="4"
+ android:text="The backups you make will be displayed here "
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary" />
+ </LinearLayout>
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/backup_list_item.xml b/res/layout/backup_list_item.xml
new file mode 100644
index 0000000..2ae3995
--- /dev/null
+++ b/res/layout/backup_list_item.xml
@@ -0,0 +1,24 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+
+ <ImageView
+ android:id="@+id/image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_margin="5dp"
+ android:src="@drawable/ic_dots" />
+
+ <TextView
+ android:id="@+id/filename"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="5dp"
+ android:ellipsize="marquee"
+ android:fontFamily="sans-serif-condensed"
+ android:layout_gravity="center"
+ android:text="Medium Text"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/boot_dialog_layout.xml b/res/layout/boot_dialog_layout.xml
new file mode 100644
index 0000000..483787b
--- /dev/null
+++ b/res/layout/boot_dialog_layout.xml
@@ -0,0 +1,25 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/tv_boot"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dp"
+ android:layout_marginRight="20dp"
+ android:layout_marginTop="20dp"
+ android:gravity="center_horizontal"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <CheckBox
+ android:id="@+id/cb_boot"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_margin="20dp"
+ android:text="Set on Boot" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/calendar_color_picker_dialog.xml b/res/layout/calendar_color_picker_dialog.xml
new file mode 100755
index 0000000..e0ff8bd
--- /dev/null
+++ b/res/layout/calendar_color_picker_dialog.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center" >
+
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center"
+ android:padding="10dp" >
+
+ <ProgressBar
+ android:id="@android:id/progress"
+ style="?android:attr/progressBarStyleLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center" />
+
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPalette
+ android:id="@+id/color_picker"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:visibility="gone" />
+ </FrameLayout>
+</ScrollView> \ No newline at end of file
diff --git a/res/layout/calendar_color_picker_swatch.xml b/res/layout/calendar_color_picker_swatch.xml
new file mode 100755
index 0000000..1495820
--- /dev/null
+++ b/res/layout/calendar_color_picker_swatch.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+ <ImageView
+ android:id="@+id/color_picker_swatch"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ <ImageView
+ android:id="@+id/color_picker_checkmark"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_colorpicker_swatch_selected"
+ android:scaleType="fitXY"
+ android:visibility="gone" />
+</merge> \ No newline at end of file
diff --git a/res/layout/calendar_grid_item_color.xml b/res/layout/calendar_grid_item_color.xml
new file mode 100755
index 0000000..2cc155e
--- /dev/null
+++ b/res/layout/calendar_grid_item_color.xml
@@ -0,0 +1,28 @@
+<!--
+ Copyright 2013 Google Inc.
+
+ 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.
+ -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="8dp">
+
+ <ImageView
+ android:id="@+id/calendar_color_view"
+ android:layout_width="40dp"
+ android:layout_height="40dp"
+ android:layout_gravity="center"
+ android:scaleType="fitXY" />
+</FrameLayout> \ No newline at end of file
diff --git a/res/layout/cpu_info.xml b/res/layout/cpu_info.xml
new file mode 100755
index 0000000..db6ede7
--- /dev/null
+++ b/res/layout/cpu_info.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingRight="10dp"
+ android:paddingLeft="10dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:fontFamily="sans-serif-condensed"
+ android:textColor="@android:color/holo_blue_dark"
+ android:text="@string/kernel_info" />
+
+ <TextView
+ android:id="@+id/kernel_info"
+ android:layout_width="match_parent"
+ android:fontFamily="sans-serif-light"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:fontFamily="sans-serif-condensed"
+ android:textColor="@android:color/holo_blue_dark"
+ android:text="@string/cpu_info" />
+
+ <TextView
+ android:id="@+id/cpu_info"
+ android:layout_width="match_parent"
+ android:fontFamily="sans-serif-light"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:fontFamily="sans-serif-condensed"
+ android:textColor="@android:color/holo_blue_dark"
+ android:text="@string/mem_info" />
+
+ <TextView
+ android:id="@+id/mem_info"
+ android:layout_width="match_parent"
+ android:fontFamily="sans-serif-light"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+
+</ScrollView>
diff --git a/res/layout/cpu_info_item.xml b/res/layout/cpu_info_item.xml
new file mode 100755
index 0000000..9c01ab7
--- /dev/null
+++ b/res/layout/cpu_info_item.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@+id/cpu_info_core"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:focusable="false" />
+
+ <TextView
+ android:id="@+id/cpu_info_freq"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right"
+ android:fontFamily="sans-serif-condensed"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:focusable="false" />
+
+</LinearLayout>
diff --git a/res/layout/dialog_about.xml b/res/layout/dialog_about.xml
new file mode 100755
index 0000000..c2c5c1d
--- /dev/null
+++ b/res/layout/dialog_about.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="16dp"
+ android:textSize="14sp"
+ android:background="@android:color/white"
+ android:textColor="@android:color/black" /> \ No newline at end of file
diff --git a/res/layout/dialog_layout.xml b/res/layout/dialog_layout.xml
new file mode 100644
index 0000000..f559f11
--- /dev/null
+++ b/res/layout/dialog_layout.xml
@@ -0,0 +1,16 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <EditText
+ android:id="@+id/et"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="20dp"
+ android:ems="10" >
+
+ <requestFocus />
+ </EditText>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/dragsort_list.xml b/res/layout/dragsort_list.xml
new file mode 100644
index 0000000..4077280
--- /dev/null
+++ b/res/layout/dragsort_list.xml
@@ -0,0 +1,81 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res/com.dsht.kerneltweaker"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <com.mobeta.android.dslv.DragSortListView
+ android:id="@+id/dslist"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ app:drag_start_mode="onDown"
+ app:float_alpha="0.2"
+ app:float_background_color="#FFFFFFFF"
+ app:slide_shuffle_speed="0.3"
+ app:sort_enabled="true"
+ app:use_default_controller="false" />
+
+ <TextView
+ android:id="@+id/empty"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_gravity="center"
+ android:fontFamily="sans-serif-condensed"
+ android:gravity="center"
+ android:padding="10dp"
+ android:text="@string/list_command_empty"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textColor="#ff4444" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"
+ android:orientation="vertical" >
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:id="@+id/cancel"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:fontFamily="sans-serif-condensed"
+ android:background="@drawable/bottombutton"
+ android:text="Cancel" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingBottom="10dp"
+ android:paddingTop="10dp" >
+
+ <LinearLayout
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@android:color/darker_gray" >
+ </LinearLayout>
+ </LinearLayout>
+
+ <Button
+ android:id="@+id/reboot"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:background="@drawable/bottombutton"
+ android:fontFamily="sans-serif-condensed"
+ android:layout_weight="1"
+ android:text="Reboot" />
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/dragsort_list_item.xml b/res/layout/dragsort_list_item.xml
new file mode 100644
index 0000000..39c1ed2
--- /dev/null
+++ b/res/layout/dragsort_list_item.xml
@@ -0,0 +1,49 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/item_container"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="match_parent" >
+
+ <ImageView
+ android:id="@+id/image"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:layout_gravity="center"
+ android:layout_margin="2dp"
+ android:src="@drawable/ic_dots" />
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_margin="3dp"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/name"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_margin="5dp"
+ android:ellipsize="marquee"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Medium Text"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/value"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_margin="5dp"
+ android:ellipsize="marquee"
+ android:fontFamily="sans-serif-light"
+ android:text="Medium Text"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </LinearLayout>
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/empty_test.xml b/res/layout/empty_test.xml
new file mode 100644
index 0000000..3032f89
--- /dev/null
+++ b/res/layout/empty_test.xml
@@ -0,0 +1,18 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/empty"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_gravity="center"
+ android:fontFamily="sans-serif-condensed"
+ android:gravity="center"
+ android:padding="10dp"
+ android:text="Commands list is empty.\n Tap the plus button to add a command"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textColor="#ff4444" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/file_list_item.xml b/res/layout/file_list_item.xml
new file mode 100644
index 0000000..6c14afd
--- /dev/null
+++ b/res/layout/file_list_item.xml
@@ -0,0 +1,40 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center"
+ android:layout_margin="8dp"
+ android:scaleType="fitCenter" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:ellipsize="end"
+ android:fontFamily="sans-serif-condensed"
+ android:maxLines="1"
+ android:text="qqq"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/info"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:fontFamily="sans-serif-light" />
+
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/header.xml b/res/layout/header.xml
new file mode 100644
index 0000000..14413e1
--- /dev/null
+++ b/res/layout/header.xml
@@ -0,0 +1,21 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_margin="5dp" >
+
+ <ImageView
+ android:id="@+id/imageView1"
+ android:layout_width="match_parent"
+ android:layout_height="150dp"
+ android:scaleType="centerInside"
+ android:src="@drawable/dsht_logo" />
+
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/layout_list.xml b/res/layout/layout_list.xml
new file mode 100644
index 0000000..b266815
--- /dev/null
+++ b/res/layout/layout_list.xml
@@ -0,0 +1,61 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:animateLayoutChanges="true" >
+
+ <ListView
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/btn_layout"
+ android:paddingLeft="15dp"
+ android:paddingRight="15dp"
+ android:scrollbarStyle="outsideOverlay"
+ android:smoothScrollbar="true" >
+
+ </ListView>
+
+ <LinearLayout
+ android:id="@+id/btn_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="#242424"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:visibility="gone" >
+
+ <Button
+ android:id="@+id/btn_apply"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:background="@drawable/bottombutton"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Apply" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingBottom="10dp"
+ android:paddingTop="10dp" >
+
+ <LinearLayout
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@android:color/darker_gray" >
+ </LinearLayout>
+ </LinearLayout>
+
+ <Button
+ android:id="@+id/btn_cancel"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:background="@drawable/bottombutton"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Cancel" />
+
+ </LinearLayout>
+
+</RelativeLayout> \ No newline at end of file
diff --git a/res/layout/layout_list_file.xml b/res/layout/layout_list_file.xml
new file mode 100644
index 0000000..4069f7f
--- /dev/null
+++ b/res/layout/layout_list_file.xml
@@ -0,0 +1,23 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <ListView
+ android:id="@+id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+ </ListView>
+
+ <TextView
+ android:id="@+id/empty"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_gravity="center"
+ android:fontFamily="sans-serif-condensed"
+ android:gravity="center"
+ android:text="This folder is empty!"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="#ff4444" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/list_item.xml b/res/layout/list_item.xml
new file mode 100644
index 0000000..e53254f
--- /dev/null
+++ b/res/layout/list_item.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2006 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.
+-->
+
+
+<!--
+ Layout for a Preference in a PreferenceActivity. The
+ Preference is able to place a specific widget for its particular
+ type in the "widget_frame" layout.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/item_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="4dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:gravity="center_vertical"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:paddingEnd="?android:attr/scrollbarSize" >
+
+ <TextView
+ android:id="@+android:id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:layout_marginLeft="3dp"
+ android:layout_marginRight ="3dp"
+ android:layout_marginTop="3dp"
+ android:fadingEdge="horizontal"
+ android:text="title"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+ <TextView
+ android:id="@+android:id/text2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="summary"
+ android:layout_weight="1"
+ android:fontFamily="sans-serif-light"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/lmk_footer.xml b/res/layout/lmk_footer.xml
new file mode 100644
index 0000000..d0e7c7c
--- /dev/null
+++ b/res/layout/lmk_footer.xml
@@ -0,0 +1,14 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/preset_layout"
+ android:layout_width="fill_parent"
+ android:layout_height="400dp"
+ android:orientation="vertical" >
+
+ <TextView
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:fontFamily="sans-serif-condensed"
+ android:text="PRESETS"
+ android:layout_marginTop="15dp"
+ android:textColor="@android:color/holo_blue_dark" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/lmk_layout.xml b/res/layout/lmk_layout.xml
new file mode 100644
index 0000000..972cfea
--- /dev/null
+++ b/res/layout/lmk_layout.xml
@@ -0,0 +1,12 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <ListView
+ android:id="@+id/list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+ </ListView>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/log_dialog.xml b/res/layout/log_dialog.xml
new file mode 100644
index 0000000..823f16d
--- /dev/null
+++ b/res/layout/log_dialog.xml
@@ -0,0 +1,23 @@
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/scrollView1"
+ android:layout_width="match_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:color/white"
+ android:text="TextView"
+ android:textColor="@android:color/black"
+ android:typeface="monospace" />
+
+ </LinearLayout>
+
+</ScrollView> \ No newline at end of file
diff --git a/res/layout/menu_glossary.xml b/res/layout/menu_glossary.xml
new file mode 100644
index 0000000..0acc913
--- /dev/null
+++ b/res/layout/menu_glossary.xml
@@ -0,0 +1,18 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:fontFamily="sans-serif-condensed"
+ android:text="@string/menu_glossary"
+ android:textColor="@android:color/holo_blue_dark" />
+
+ <FrameLayout
+ android:id="@+id/menu_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+ </FrameLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/menu_header.xml b/res/layout/menu_header.xml
new file mode 100644
index 0000000..b6161e2
--- /dev/null
+++ b/res/layout/menu_header.xml
@@ -0,0 +1,14 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/menu_header"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:fontFamily="sans-serif-condensed"
+ android:layout_marginTop="10dp"
+ android:text=""
+ android:textColor="@android:color/holo_blue_dark" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/menu_list.xml b/res/layout/menu_list.xml
new file mode 100644
index 0000000..b49c099
--- /dev/null
+++ b/res/layout/menu_list.xml
@@ -0,0 +1,16 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <ListView
+ android:id="@+id/navbarlist"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="5dp"
+ android:layout_marginRight="5dp"
+ android:layout_height="match_parent"
+ android:scrollbarStyle="outsideOverlay"
+ android:smoothScrollbar="true" >
+ </ListView>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/menu_list_item.xml b/res/layout/menu_list_item.xml
new file mode 100644
index 0000000..1138fd6
--- /dev/null
+++ b/res/layout/menu_list_item.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/item_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+android:id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="3dp"
+ android:layout_marginTop="3dp"
+ android:layout_marginRight="3dp"
+ android:fontFamily="sans-serif-condensed"
+ android:text="title"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+android:id/text2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="3dp"
+ android:layout_marginLeft="3dp"
+ android:fontFamily="sans-serif-light"
+ android:text="summaryggg"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/menu_main_list_item.xml b/res/layout/menu_main_list_item.xml
new file mode 100644
index 0000000..7782b26
--- /dev/null
+++ b/res/layout/menu_main_list_item.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/item_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+
+ <ImageView
+ android:id="@+id/image"
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center"
+ android:layout_margin="10dp"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ab_texture_tile" />
+
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginBottom="10dp"
+ android:layout_marginRight="10dp"
+ android:layout_marginTop="10dp"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Medium Text"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textStyle="bold" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/preference.xml b/res/layout/preference.xml
new file mode 100644
index 0000000..bb86168
--- /dev/null
+++ b/res/layout/preference.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2006 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.
+-->
+
+
+<!--
+ Layout for a Preference in a PreferenceActivity. The
+ Preference is able to place a specific widget for its particular
+ type in the "widget_frame" layout.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?android:attr/selectableItemBackground"
+ android:gravity="center_vertical"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:paddingRight="?android:attr/scrollbarSize" >
+
+ <ImageView
+ android:id="@+android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center" />
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="6dip"
+ android:layout_marginLeft="15dip"
+ android:layout_marginRight="6dip"
+ android:layout_marginTop="6dip"
+ android:layout_weight="1" >
+
+ <TextView
+ android:id="@+android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@android:id/title"
+ android:layout_below="@android:id/title"
+ android:maxLines="4"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary" />
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+
+ <LinearLayout
+ android:id="@+android:id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:orientation="vertical" />
+
+ <View
+ android:id="@+id/separator"
+ android:layout_width="1dp"
+ android:layout_height="fill_parent"
+ android:layout_margin="5dp"
+ android:background="@android:color/darker_gray" />
+
+ <com.dsht.kerneltweaker.CircleAnimatedCheckBox
+ android:id="@+id/cb"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="5dp"
+ android:layout_marginRight="5dp"
+ android:button="@drawable/checkbox_selector_light"
+ android:focusable="false"
+ android:scaleX="1.20"
+ android:scaleY="1.20"
+ app:cb_color="#CC33b5e5"
+ app:cb_pressed_ring_width="2dp"/>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/preference_widget_seekbar.xml b/res/layout/preference_widget_seekbar.xml
new file mode 100644
index 0000000..e5c6968
--- /dev/null
+++ b/res/layout/preference_widget_seekbar.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Layout for a Preference in a PreferenceActivity. The
+ Preference is able to place a specific widget for its particular
+ type in the "widget_frame" layout. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingEnd="?android:attr/scrollbarSize">
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="4dp" >
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:ellipsize="marquee"
+ android:layout_marginLeft="3dp"
+ android:layout_marginRight ="3dp"
+ android:layout_marginTop="3dp"
+ android:fadingEdge="horizontal"
+ android:singleLine="true"
+ android:text="title"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-thin"
+ android:layout_marginLeft="3dp"
+ android:layout_marginRight ="3dp"
+ android:layout_alignStart="@android:id/title"
+ android:maxLines="4"
+ android:text="summary"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <SeekBar
+ android:id="@+id/seekbar"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_margin="3dp"
+ android:layout_toEndOf="@android:id/widget_frame"
+ android:layout_weight="1" />
+
+ <TextView
+ android:id="@+id/currvalue"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-thin"
+ android:layout_gravity="center"
+ android:text="100 Mb" />
+
+ </LinearLayout>
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/seekbar_dialog.xml b/res/layout/seekbar_dialog.xml
new file mode 100755
index 0000000..6f113d2
--- /dev/null
+++ b/res/layout/seekbar_dialog.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+Performance Control - An Android CPU Control application
+Copyright (C) 2012 James Roberts
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/seekbar_dialog"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:orientation="horizontal"
+ android:paddingLeft="5dp"
+ android:paddingRight="5dp">
+
+ <SeekBar
+ android:id="@+id/seek_bar"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dip"
+ android:layout_weight="1"
+ android:layout_marginTop="10dip" />
+
+ <EditText
+ android:id="@+id/setting_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:inputType="number"
+ android:textSize="20sp" >
+
+ <requestFocus />
+ </EditText>
+
+</LinearLayout>
diff --git a/res/layout/state_row.xml b/res/layout/state_row.xml
new file mode 100755
index 0000000..e34f4dd
--- /dev/null
+++ b/res/layout/state_row.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+Performance Control - An Android CPU Control application
+Copyright (C) Brandon Valosek, 2011 <bvalosek@gmail.com>
+Copyright (C) 2012 James Roberts
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/ui_state_row"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/ui_freq_text"
+ android:layout_width="80dp"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:layout_marginRight="5dp"
+ android:textSize="17sp" />
+
+ <TextView
+ android:id="@+id/ui_percentage_text"
+ android:layout_width="70dp"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:layout_marginRight="5dp"
+ android:layout_weight="0"
+ android:gravity="right" />
+
+ <TextView
+ android:id="@+id/ui_duration_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:layout_marginRight="5dp"
+ android:layout_weight="1"
+ android:gravity="right" />
+ </LinearLayout>
+
+ <ProgressBar
+ android:id="@+id/ui_bar"
+ style="?android:attr/progressBarStyleHorizontal"
+ android:layout_width="match_parent"
+ android:layout_height="10dp"
+ android:max="100" />
+</LinearLayout>
diff --git a/res/layout/time_in_state.xml b/res/layout/time_in_state.xml
new file mode 100755
index 0000000..fbdf19c
--- /dev/null
+++ b/res/layout/time_in_state.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:id="@+id/speed"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:gravity="center_horizontal"
+ android:orientation="vertical" >
+
+ <TextView
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:fontFamily="sans-serif-condensed"
+ android:text="@string/cpu_info_list_header"
+ android:textColor="@android:color/holo_blue_dark" />
+
+ <ListView
+ android:id="@+id/cpu_info_list"
+ android:layout_width="match_parent"
+ android:layout_height="110dp"
+ android:divider="@null"
+ android:paddingLeft="10dp" />
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/ui_header_total_state_time"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:text="@string/total_state_time"
+ android:textColor="@android:color/holo_blue_dark" />
+
+ <TextView
+ android:id="@+id/ui_total_state_time"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:gravity="center_horizontal"
+ android:padding="7dp"
+ android:textColor="@android:color/holo_orange_dark"
+ android:textSize="25sp" />
+
+ <TextView
+ android:id="@+id/ui_header_additional_states"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:fontFamily="sans-serif-condensed"
+ android:text="@string/unused_cpu_states"
+ android:textColor="@android:color/holo_blue_dark"
+ android:visibility="gone" />
+
+ <TextView
+ android:id="@+id/ui_additional_states"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="6dp"
+ android:visibility="gone" />
+
+ <TextView
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:fontFamily="sans-serif-condensed"
+ android:text="@string/time_in_state"
+ android:textColor="@android:color/holo_blue_dark" />
+
+ <LinearLayout
+ android:id="@+id/ui_states_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingBottom="10dp" />
+
+ <TextView
+ android:id="@+id/ui_states_warning"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="#551111"
+ android:fontFamily="sans-serif-condensed"
+ android:padding="15dp"
+ android:text="@string/no_states_file_found"
+ android:textColor="@android:color/holo_blue_dark"
+ android:textSize="20sp"
+ android:visibility="gone" />
+ </LinearLayout>
+
+</ScrollView> \ No newline at end of file
diff --git a/res/layout/wallpaper_effects.xml b/res/layout/wallpaper_effects.xml
new file mode 100644
index 0000000..d512df5
--- /dev/null
+++ b/res/layout/wallpaper_effects.xml
@@ -0,0 +1,71 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:layout_weight="1"
+ android:orientation="vertical" >
+
+ <ImageView
+ android:id="@+id/wall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_margin="5dp"
+ android:maxHeight="160dp"
+ android:maxWidth="240dp"
+ android:src="@drawable/ab_texture_tile" />
+ </LinearLayout>
+
+ <ScrollView
+ android:id="@+id/scrollView1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/textView1"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Blur Radius"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <SeekBar
+ android:id="@+id/sb_blur"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp" />
+
+ </LinearLayout>
+ </ScrollView>
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1px"
+ android:background="#ffffff"/>
+
+ <LinearLayout
+ android:id="@+id/btn_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:id="@+id/btn_apply"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:background="@drawable/bottombutton"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Apply" />
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/menu/cpu_info_menu.xml b/res/menu/cpu_info_menu.xml
new file mode 100755
index 0000000..44da2c6
--- /dev/null
+++ b/res/menu/cpu_info_menu.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/refresh"
+ android:icon="@drawable/ic_menu_refresh"
+ android:showAsAction="never"
+ android:title="@string/mt_refresh" />
+</menu>
diff --git a/res/menu/main.xml b/res/menu/main.xml
new file mode 100644
index 0000000..8265a87
--- /dev/null
+++ b/res/menu/main.xml
@@ -0,0 +1,16 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/action_delete"
+ android:orderInCategory="100"
+ android:showAsAction="always"
+ android:icon="@drawable/ic_delete"
+ android:title="@string/menu_del"/>
+ <item
+ android:id="@+id/action_add"
+ android:orderInCategory="100"
+ android:showAsAction="always"
+ android:icon="@drawable/ic_add"
+ android:title="@string/menu_add"/>
+
+</menu>
diff --git a/res/menu/menu_lmk.xml b/res/menu/menu_lmk.xml
new file mode 100644
index 0000000..b900846
--- /dev/null
+++ b/res/menu/menu_lmk.xml
@@ -0,0 +1,10 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/action_boot"
+ android:checkable="true"
+ android:showAsAction="never"
+ android:title="@string/menu_boot">
+ </item>
+
+</menu> \ No newline at end of file
diff --git a/res/menu/menu_main_container.xml b/res/menu/menu_main_container.xml
new file mode 100644
index 0000000..829d70c
--- /dev/null
+++ b/res/menu/menu_main_container.xml
@@ -0,0 +1,4 @@
+
+ <menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/help" android:showAsAction="always" android:icon="@drawable/ic_help" android:title="Help"></item>
+ </menu>
diff --git a/res/menu/menu_recovery.xml b/res/menu/menu_recovery.xml
new file mode 100644
index 0000000..c9ac764
--- /dev/null
+++ b/res/menu/menu_recovery.xml
@@ -0,0 +1,10 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/action_plus"
+ android:icon="@drawable/ic_plus"
+ android:showAsAction="always"
+ android:title="@string/menu_command">
+ </item>
+
+</menu> \ No newline at end of file
diff --git a/res/menu/menu_review.xml b/res/menu/menu_review.xml
new file mode 100644
index 0000000..95e5e3c
--- /dev/null
+++ b/res/menu/menu_review.xml
@@ -0,0 +1,9 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/action_edit"
+ android:checkable="true"
+ android:title="Edit Mode">
+ </item>
+
+</menu> \ No newline at end of file
diff --git a/res/menu/menu_uv.xml b/res/menu/menu_uv.xml
new file mode 100644
index 0000000..dc26442
--- /dev/null
+++ b/res/menu/menu_uv.xml
@@ -0,0 +1,20 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/action_plus"
+ android:showAsAction="always"
+ android:title="@string/menu_plus">
+ </item>
+ <item
+ android:id="@+id/action_minus"
+ android:showAsAction="always"
+ android:title="@string/menu_less">
+ </item>
+ <item
+ android:id="@+id/action_boot"
+ android:checkable="true"
+ android:showAsAction="ifRoom"
+ android:title="@string/menu_boot">
+ </item>
+
+</menu> \ No newline at end of file
diff --git a/res/menu/time_in_state_menu.xml b/res/menu/time_in_state_menu.xml
new file mode 100755
index 0000000..42c8c18
--- /dev/null
+++ b/res/menu/time_in_state_menu.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/refresh"
+ android:icon="@drawable/ic_menu_refresh"
+ android:showAsAction="never"
+ android:title="@string/mt_refresh" />
+ <item
+ android:id="@+id/reset"
+ android:showAsAction="never"
+ android:title="@string/mt_reset" />
+ <item
+ android:id="@+id/restore"
+ android:showAsAction="never"
+ android:title="@string/mt_restore" />
+</menu>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
new file mode 100644
index 0000000..44f01db
--- /dev/null
+++ b/res/values-sw600dp/dimens.xml
@@ -0,0 +1,8 @@
+<resources>
+
+ <!--
+ Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw600dp devices (e.g. 7" tablets) here.
+ -->
+
+</resources>
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..61e3fa8
--- /dev/null
+++ b/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,9 @@
+<resources>
+
+ <!--
+ Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
+ -->
+ <dimen name="activity_horizontal_margin">128dp</dimen>
+
+</resources>
diff --git a/res/values-v11/styles.xml b/res/values-v11/styles.xml
new file mode 100644
index 0000000..3c02242
--- /dev/null
+++ b/res/values-v11/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+
+ <!--
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+ <!-- API 11 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/res/values-v14/styles.xml b/res/values-v14/styles.xml
new file mode 100644
index 0000000..a91fd03
--- /dev/null
+++ b/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+<resources>
+
+ <!--
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+ <!-- API 14 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/res/values/analytics.xml b/res/values/analytics.xml
new file mode 100644
index 0000000..d63ae86
--- /dev/null
+++ b/res/values/analytics.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+
+<resources>
+ <!--Replace placeholder ID with your tracking ID-->
+ <string name="ga_trackingId">UA-46398799-1</string>
+
+ <!--Enable automatic activity tracking-->
+ <bool name="ga_autoActivityTracking">true</bool>
+
+ <!--Enable automatic exception tracking-->
+ <bool name="ga_reportUncaughtExceptions">true</bool>
+</resources> \ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
new file mode 100644
index 0000000..13a7875
--- /dev/null
+++ b/res/values/attrs.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <declare-styleable name="CircleAnimatedCheckBox">
+ <attr name="cb_color" format="color" />
+ <attr name="cb_pressed_ring_width" format="dimension" />
+ </declare-styleable>
+</resources> \ No newline at end of file
diff --git a/res/values/calendar_attrs.xml b/res/values/calendar_attrs.xml
new file mode 100755
index 0000000..ef7e396
--- /dev/null
+++ b/res/values/calendar_attrs.xml
@@ -0,0 +1,9 @@
+<resources>
+
+ <declare-styleable name="ColorPickerPreference">
+ <attr name="cal_itemLayout" format="reference" />
+ <attr name="cal_choices" format="reference" />
+ <attr name="cal_numColumns" format="integer" />
+ </declare-styleable>
+
+</resources> \ No newline at end of file
diff --git a/res/values/calendar_dimens.xml b/res/values/calendar_dimens.xml
new file mode 100755
index 0000000..fc78f2f
--- /dev/null
+++ b/res/values/calendar_dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<resources>
+ <dimen name="color_swatch_large">64dip</dimen>
+ <dimen name="color_swatch_small">48dip</dimen>
+ <dimen name="color_swatch_margins_large">8dip</dimen>
+ <dimen name="color_swatch_margins_small">4dip</dimen>
+</resources> \ No newline at end of file
diff --git a/res/values/calendar_strings.xml b/res/values/calendar_strings.xml
new file mode 100755
index 0000000..f2e969a
--- /dev/null
+++ b/res/values/calendar_strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+ <string name="color_picker_default_title">Select a Color</string>
+ <!-- Content description for a color square. -->
+ <string name="color_swatch_description">Color <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
+ <!-- Content description for a selected color square. -->
+ <string name="color_swatch_description_selected">Color <xliff:g id="color_index" example="14">%1$d</xliff:g> selected</string>
+ <string name="defcolor">#ffffff</string>
+ <string-array name="default_color_choice_values" translatable="false">
+ <item>#33b5e5</item>
+ <item>#aa66cc</item>
+ <item>#99cc00</item>
+ <item>#ffbb33</item>
+ <item>#ff4444</item>
+ <item>#0099cc</item>
+ <item>#9933cc</item>
+ <item>#669900</item>
+ <item>#ff8800</item>
+ <item>#cc0000</item>
+ <item>#ffffff</item>
+ <item>#eeeeee</item>
+ <item>#cccccc</item>
+ <item>#888888</item>
+ <item>#000000</item>
+ </string-array>
+
+ <string-array name="homescreen_color_choice_values" translatable="false">
+ <item>#ffffff</item>
+ <item>#000000</item>
+ </string-array>
+
+</resources> \ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
new file mode 100644
index 0000000..ecedaf7
--- /dev/null
+++ b/res/values/colors.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <color name="pressed_customapptheme">#CC00C36D</color>
+ <color name="mca__holo_blue_light">#3333b5e5</color>
+ <color name="mca__holo_blue_light_transparent">#7f33b5e5</color>
+ <color name="holo_white_normal">#33ffffff</color>
+ <color name="mca__list_item_bg_normal">@android:color/transparent</color>
+ <color name="mca__list_item_bg_checked">@color/mca__holo_blue_light</color>
+ <color name="mca__list_item_bg_pressed">@color/holo_white_normal</color>
+</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
new file mode 100755
index 0000000..803855d
--- /dev/null
+++ b/res/values/config.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2013 The OmniROM Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+
+<resources>
+
+ <!-- Whether or not the app is meant to be run as a system app,
+ bypassing the need of busybox/su -->
+ <bool name="config_isSystemApp">false</bool>
+
+ <!-- Whether or not to only show performance-related options -->
+ <bool name="config_showPerformanceOnly">false</bool>
+
+ <!-- If true, menu_tabbed view is used, else it uses the menu_drawer mode -->
+ <bool name="config_use_tabbed">false</bool>
+
+ <!-- If false, user can't switch between menu_tabbed and menu_drawer mode -->
+ <bool name="config_allow_toggle_tabbed">true</bool>
+
+</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
new file mode 100644
index 0000000..18229a2
--- /dev/null
+++ b/res/values/dimens.xml
@@ -0,0 +1,11 @@
+<resources>
+
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+ <dimen name="slidingmenu_offset">200dp</dimen>
+ <dimen name="list_padding">10dp</dimen>
+ <dimen name="shadow_width">15dp</dimen>
+ <dimen name="dessert_case_cell_size">192dp</dimen>
+
+</resources>
diff --git a/res/values/dslv_attrs.xml b/res/values/dslv_attrs.xml
new file mode 100755
index 0000000..8c779c9
--- /dev/null
+++ b/res/values/dslv_attrs.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<resources>
+ <declare-styleable name="DragSortListView">
+ <attr name="collapsed_height" format="dimension" />
+ <attr name="drag_scroll_start" format="float" />
+ <attr name="max_drag_scroll_speed" format="float" />
+ <attr name="float_background_color" format="color" />
+ <attr name="remove_mode">
+ <enum name="clickRemove" value="0" />
+ <enum name="flingRemove" value="1" />
+ </attr>
+ <attr name="track_drag_sort" format="boolean"/>
+ <attr name="float_alpha" format="float"/>
+ <attr name="slide_shuffle_speed" format="float"/>
+ <attr name="remove_animation_duration" format="integer"/>
+ <attr name="drop_animation_duration" format="integer"/>
+ <attr name="drag_enabled" format="boolean" />
+ <attr name="sort_enabled" format="boolean" />
+ <attr name="remove_enabled" format="boolean" />
+ <attr name="drag_start_mode">
+ <enum name="onDown" value="0" />
+ <enum name="onMove" value="1" />
+ <enum name="onLongPress" value="2"/>
+ </attr>
+ <attr name="drag_handle_id" format="integer" />
+ <attr name="fling_handle_id" format="integer" />
+ <attr name="click_remove_id" format="integer" />
+ <attr name="use_default_controller" format="boolean" />
+ </declare-styleable>
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..34c551e
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,1167 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">Kernel Tweaker</string>
+ <string name="action_settings">Settings</string>
+ <string name="hello_world">Hello world!</string>
+
+ <!-- About -->
+ <string name="title_about">About</string>
+ <string name="about_ok">OK</string>
+ <string name="about_body">
+<![CDATA[
+ <b>Colorpickercollection Library & Demo</b><br>
+ Version %s<br><br>
+ <a href="https://github.com/gabrielemariotti/colorpickercollection">Source</a><br><br>
+ <a href="https://plus.google.com/114432517923423045208">By Gabriele Mariotti</a><br><br>
+
+ ]]>
+ </string>
+
+ <string-array name="menu_entries">
+ <item>--Device Info</item>
+ <item>Cpu Stats</item>
+ <item>Cpu Info</item>
+ <item>--SoC Params</item>
+ <item>Cpu Parameters</item>
+ <item>Gpu Parameters</item>
+ <item>UV Table</item>
+ <item>--Kernel Params</item>
+ <item>Kernel</item>
+ <item>Low Memory Killer</item>
+ <item>Virtual Machine</item>
+ <item>--Set on boot</item>
+ <item>Review Items</item>
+ <item>--Utilities</item>
+ <item>File Manager</item>
+ <item>Backup</item>
+ <item>Recovery actions</item>
+ <item>--Extra</item>
+ <item>Build.prop mods</item>
+ <item>Init.d tweaks</item>
+ <item>WP Blur</item>
+ <item>--App Settings/infos</item>
+ <item>Settings</item>
+ <item>Informations</item>
+ </string-array>
+ <string-array name="menu_descs">
+ <item>Frequencies time in state</item>
+ <item>Informations about CPU</item>
+ <item>Tweak CPU Parameters</item>
+ <item>Tweak GPU Parameters</item>
+ <item>Manage CPU Voltage</item>
+ <item>Tweak Kernel Parameters</item>
+ <item>Tweak native task killer</item>
+ <item>VM Settings</item>
+ <item>Review values set at boot</item>
+ <item>Manage some file types</item>
+ <item>Backup current kernel/recovery</item>
+ <item>Execute recovery stuff</item>
+ <item>App Settings</item>
+ <item>Informations and credits</item>
+ </string-array>
+ <string-array name="menu_colors">
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ <item>#ff0099cc</item>
+ </string-array>
+ <string-array name="flash_dialog">
+ <item>Flash Package</item>
+ </string-array>
+ <string-array name="install_image_dialog">
+ <item>Install Boot.img</item>
+ <item>Install Recovery.img</item>
+ </string-array>
+
+ <string name="bk_recovery">Backup Recovery.img</string>
+ <string name="bk_boot">Backup Boot.img</string>
+ <string name="bk_boot_desc">Make a backup of current Boot.img on external storage</string>
+ <string name="bk_recovery_desc">Make a backup of current Recovery.img on external storage</string>
+ <string name="bk_comp">Use Compression</string>
+ <string name="bk_md5">Skip MD5 creation</string>
+ <string name="list_command_empty">Commands list is empty.\n Tap the plus button to add a command</string>
+ <string name="emp_title">EMPTY</string>
+ <string name="emp_desc">No Values set at boot</string>
+ <string name="rc_title">Root not found</string>
+ <string name="rc_desc">Seems your device doesn\'t have root privileges! Please install SuperSU before use this app</string>
+ <string name="bb_title">BusyBox not found</string>
+ <string name="bb_desc">Your device doesn\'t have BusyBox installed, please install it through PlayStore or XDA before use this app</string>
+ <string name="st_cat">Kernel Tweaker settings</string>
+ <string name="gift">Just a gift ;)</string>
+
+ <string-array name="lmk_titles">
+ <item>FOREGROUND_APP</item>
+ <item>VISIBLE_APP</item>
+ <item>SECONDARY_SERVER</item>
+ <item>HIDDEN_APP</item>
+ <item>CONTENT_PROVIDER</item>
+ <item>EMPTY_APP</item>
+ </string-array>
+ <string-array name="lmk_descs">
+ <item>The application currently on the screen and running</item>
+ <item>The application that is open and running in background</item>
+ <item>This is a service an application needs that is alive and ready</item>
+ <item>An idle process that wakes up on application request</item>
+ <item>Apps that provide data (content) to the system, like Facebook sync</item>
+ <item>Apps closed by the users but ready to run</item>
+ </string-array>
+
+ <string name="vdd_pref">UV VDD Table</string>
+ <string name="vdd_desc">The values you have set inside UV Table page will be applied at boot.\nIf you want to edit these values go to UV Table page.</string>
+ <string name="menu_del">Delete</string>
+ <string name="menu_add">Add</string>
+ <string name="menu_boot">Set on boot</string>
+ <string name="menu_command">Add command</string>
+ <string name="menu_less">-25mV</string>
+ <string name="menu_plus">+25mV</string>
+ <string name="uv_title">UV Table Values</string>
+ <string name="cpu_max">CPU Max Frequency</string>
+ <string name="cpu_min">CPU Min Frequency</string>
+ <string name="cpu_governor">Governor</string>
+ <string name="cpu_hotplug">Hotplug</string>
+ <string name="cpu_cpuquiet_title">Cpuquiet Governor</string>
+ <string name="cpu_cpuquiet_desc">This governor controls which of the CPU cores are available and when.</string>
+ <string name="cpu_advanced">Advanced Options</string>
+ <string name="cpu_adv_gov_title">Governor Tuning</string>
+ <string name="cpu_adv_gov_desc">Fine tune governor parameters</string>
+ <string name="cpu_adv_quiet_title">Cpuquiet Governor Tuning</string>
+ <string name="cpu_adv_quiet_desc">Fine tune cpuquiet governor parameters</string>
+ <string name="gov_title">Tweakable Governor Values</string>
+ <string name="gpu_category">GPU parameters</string>
+ <string name="gpu_freq_title">GPU Max Frequency</string>
+ <string name="gpu_freq_desc">Set GPU maximum frequency</string>
+ <string name="menu_glossary">GLOSSARY</string>
+
+ <string-array name="glo_cpu_titles">
+ <item>Max Frequency</item>
+ <item>Min Frequency</item>
+ <item>Governor</item>
+ <item>Cores_on_touch</item>
+ <item>First_level</item>
+ </string-array>
+ <string-array name="glo_cpu_descs">
+ <item>The maximum frequency the CPU will use. You can lower it to increase battery life, or increase it for performance</item>
+ <item>The minimum frequency the CPU will use. You can increase it for better performance or lower it for battery life</item>
+ <item>This controls the scaling of the CPU frequencies depending on CPU load\n(Click to show governors explanations)</item>
+ <item>How many cores goes online when you touch the screen</item>
+ <item>The threshold that controls when a core will be woked up. Higher the value, harder for CPU core to become online</item>
+ </string-array>
+ <string-array name="glo_gov_titles">
+ <item>Performance</item>
+ <item>Powersave</item>
+ <item>Userspace</item>
+ <item>Ondemand</item>
+ <item>Conservative</item>
+ <item>Interactive</item>
+ <item>Smartass</item>
+ </string-array>
+ <string-array name="glo_gov_descs">
+ <item>The CPUfreq governor performance sets the CPU statically to the
+highest frequency within the borders of scaling_min_freq and
+scaling_max_freq.</item>
+ <item>The CPUfreq governor powersave sets the CPU statically to the
+lowest frequency within the borders of scaling_min_freq and
+scaling_max_freq.</item>
+ <item>The CPUfreq governor userspace allows the user, or any userspace
+program running with UID root, to set the CPU to a specific frequency
+by making a sysfs file scaling_setspeed available in the CPU-device
+directory.</item>
+ <item>The CPUfreq governor ondemand sets the CPU depending on the
+current usage. To do this the CPU must have the capability to
+switch the frequency very quickly.</item>
+ <item>The CPUfreq governor conservative, much like the ondemand
+governor, sets the CPU depending on the current usage. It differs in
+behaviour in that it gracefully increases and decreases the CPU speed
+rather than jumping to max speed the moment there is any load on the
+CPU. This behaviour more suitable in a battery powered environment.</item>
+ <item>The CPUfreq governor interactive is designed for latency-sensitive,
+interactive workloads. This governor sets the CPU speed depending on
+usage, similar to ondemand and conservative governors. However,
+the governor is more aggressive about scaling the CPU speed up in
+response to CPU-intensive activity.
+
+Sampling the CPU load every X ms can lead to under-powering the CPU
+for X ms, leading to dropped frames, stuttering UI, etc. Instead of
+sampling the cpu at a specified rate, the interactive governor will
+check whether to scale the cpu frequency up soon after coming out of
+idle. When the cpu comes out of idle, a timer is configured to fire
+within 1-2 ticks. If the cpu is very busy between exiting idle and
+when the timer fires then we assume the cpu is underpowered and ramp
+to MAX speed.
+
+If the cpu was not sufficiently busy to immediately ramp to MAX speed,
+then governor evaluates the cpu load since the last speed adjustment,
+choosing the highest value between that longer-term load or the
+short-term load since idle exit to determine the cpu speed to ramp to.</item>
+ <item>Result of Erasmux rewriting the complete code of interactive governor.
+ Main goal is to optimize battery life without comprising performance.
+ Still, not as battery friendly as smartassV2 since screen-on minimum frequency is greater than frequencies used during screen-off. Smartass would jump up to highest frequency too often as well.</item>
+ </string-array>
+ <string-array name="glo_ondemand_titles">
+ <item>sampling_rate</item>
+ <item>up_threshold</item>
+ <item>powersave_bias</item>
+ <item>sampling_down_factor</item>
+ <item>down_differential</item>
+ <item>freq_step</item>
+ </string-array>
+ <string-array name="glo_ondemand_descs">
+ <item>Measured in uS , this is how often the kernel look at the CPU usage and make decisions on what to do about the frequency. Higher values means CPU polls less often. For lower frequencies, this could be considered an advantage since it might not jump to next frequency very often, but for higher frequencies, the scale-down time will be increased.</item>
+ <item>Measured in percentage from 1 to 100, When CPU load reaches this point, governor will scale CPU up. Higher value means less responsiveness and lower values corresponds to more responsiveness at the cost of battery. </item>
+ <item>Default value is 0. Setting a higher value will bias the governor towards lower frequency steps. Use this if you want CPU to spend less time on higher frequencies. A better alternative would be to underclock to a lower frequency than using powersave bias.</item>
+ <item>In the simplest form, sampling_down_factor determines how often CPU should stay at higher frequencies when truly busy. Default behavior is fast switching to lower frequencies (1). Having sampling_down_factor set to 1 makes no changes from existing behavior (for the non-modified ondemand), but having sampling_down_factor set to a value greater than 1 causes it to act as a multiplier for the scheduling interval for re-evaluating the load when the CPU is at its highest clock frequency (which is scaling_max_freq) due to high load. This improves performance by reducing the overhead of load evaluation and helping the CPU stay at its highest clock frequency when it is truly busy, rather than shifting back and forth in speed. This tunable has no effect on behavior at lower frequencies/lower CPU loads.</item>
+ <item>This factor indirectly calculate the down-threshold of Ondemand.
+ After completing sampling-down-factor*sampling-rate at max frequency because of high load,
+ governor samples the load again to calculate an estimate of the new target frequency in a
+ way that the lowest frequency will be chosen that would not trigger up_threshold in the
+ next sample. Because triggering up-threshold will again cause CPU to scale up to max frequency.
+ During this choice down_differential is taken into account as a breathing room value.
+ Target frequency is calculated as max_load_freq / (up_threshold - down_differential). The obtained value might be a non-existent value in the freq_table and CPU driver will round it off to a value in freq_table. max_load_freq is the theoretical frequency at which CPU can handle 100% workload.
+ It is usually a value below scaling_max_freq.</item>
+ <item>Whenever up-scaling logic is triggered the governor instructs the CPU to raise its frequency by freq_step percentage of max allowed frequency.</item>
+ </string-array>
+ <string-array name="glo_interactive_titles">
+ <item>hispeed_freq</item>
+ <item>go_hispeed_load</item>
+ <item>min_sample_time</item>
+ <item>timer_rate</item>
+ <item>above_hispeed_delay</item>
+ <item>input_boost</item>
+ <item>boost</item>
+ <item>boostpulse</item>
+ </string-array>
+ <string-array name="glo_interactive_descs">
+ <item>An intermediate hi speed at which to initially ramp
+when CPU load hits the value specified in go_hispeed_load. If load
+stays high for the amount of time specified in above_hispeed_delay,
+then speed may be bumped higher. Default is maximum speed.</item>
+ <item>The CPU load at which to ramp to the intermediate hi
+speed. Default is 85%.</item>
+ <item>The minimum amount of time to spend at the current
+frequency before ramping down. This is to ensure that the governor has
+seen enough historic cpu load data to determine the appropriate
+workload. Default is 80000 uS.</item>
+ <item>Sample rate for reevaluating cpu load when the system is
+not idle. Default is 20000 uS.</item>
+ <item>Once speed is set to hispeed_freq, wait for this
+long before bumping speed higher in response to continued high load.
+Default is 20000 uS.</item>
+ <item>Once speed is set to hispeed_freq, wait for this
+long before bumping speed higher in response to continued high load.
+Default is 20000 uS.</item>
+ <item>If non-zero, boost speed of all CPUs to hispeed_freq on
+touchscreen activity. Default is 0.</item>
+ <item>If non-zero, immediately boost speed of all CPUs to at least
+hispeed_freq until zero is written to this attribute. If zero, allow
+CPU speeds to drop below hispeed_freq according to load as usual.</item>
+ <item>Immediately boost speed of all CPUs to hispeed_freq for
+min_sample_time, after which speeds are allowed to drop below
+hispeed_freq according to load as usual.</item>
+ </string-array>
+ <string-array name="glo_conservative_titles">
+ <item>freq_step</item>
+ <item>down_threshold</item>
+ </string-array>
+ <string-array name="glo_conservative_descs">
+ <item>this describes what percentage steps the cpu freq should be
+increased and decreased smoothly by. By default the cpu frequency will
+increase in 5% chunks of your maximum cpu frequency. You can change this
+value to anywhere between 0 and 100 where 0 will effectively lock your
+CPU at a speed regardless of its load whilst 100 will, in theory, make
+it behave identically to the ondemand governor.</item>
+ <item>same as the up_threshold found for the ondemand
+governor but for the opposite direction. For example when set to its
+default value of 20 it means that if the CPU usage needs to be below
+20% between samples to have the frequency decreased.</item>
+ </string-array>
+ <string-array name="glo_gpu_titles">
+ <item>GPU Max Frequency</item>
+ <item>up_threshold</item>
+ <item>down_threshold</item>
+ <item>sample_time_ms</item>
+ </string-array>
+ <string-array name="glo_gpu_descs">
+ <item>The maximum clock that the GPU can use. Reduce this frequency for better battery life at cost of performance</item>
+ <item>When the GPU load is equal or above this value the GPU governor will increase the frequency</item>
+ <item>When the GPU load is equal or above this value the GPU governor will decrease the frequency</item>
+ <item>This is how often the governor polls for the GPU load. Increase for battery life, decrease for performance. 1000 equals 1 second.</item>
+ </string-array>
+ <string-array name="glo_uv_titles">
+ <item>UnderVolting</item>
+ </string-array>
+ <string-array name="glo_uv_descs">
+ <item>UnderVolt table allows you to change the voltage parameter of every frequency. This means that you can set, for every frequency, how much current the CPU
+ must use. Lowering voltages means some battery saving, but you are warned! Lowering frequencies too much can make your device crash or freeze, so, proceed with little steps
+ until you find your ideal spot. Hit the \"Set on boot\" option ONLY after some tests or your device will freeze/crash on next reboot!</item>
+ </string-array>
+ <string-array name="glo_kernel_titles">
+ <item>I/O Scheduler</item>
+ <item>Read ahead size</item>
+ <item>TCP Congestion control</item>
+ <item>Fsync</item>
+ <item>Fast Charge</item>
+ <item>Vibration Intensity</item>
+ <item>Temp_threshold</item>
+ <item>Headset_boost</item>
+ <item>Mic_boost</item>
+ <item>Speaker_boost</item>
+ <item>Volume_boost</item>
+ </string-array>
+ <string-array name="pie_colors">
+ <item>#ffffff</item>
+ <item>#9c35d0</item>
+ <item>#33b5e5</item>
+ <item>#fb8600</item>
+ <item>#cc0101</item>
+ <item>#ffbc37</item>
+ <item>#009cd0</item>
+ <item>#689c00</item>
+ <item>#ff4646</item>
+ <item>#9ed201</item>
+ <item>#ac68ce</item>
+ <item>#ffffff</item>
+ <item>#9c35d0</item>
+ <item>#33b5e5</item>
+ <item>#fb8600</item>
+ <item>#cc0101</item>
+ <item>#ffbc37</item>
+ <item>#009cd0</item>
+ <item>#689c00</item>
+ <item>#ff4646</item>
+ <item>#9ed201</item>
+ <item>#ac68ce</item>
+ </string-array>
+ <string-array name="glo_kernel_descs">
+ <item>Is the method that computer operating systems use to decide which order block I/O operations will be submitted to storage volumes. I/O Scheduling is sometimes called disk scheduling.\n\n(click for Sheduler types explanation)</item>
+ <item>It is a system call that loads a file\'s contents into the page cache. When a file is subsequently accessed, its contents are read from physical memory rather than from disk, which is much faster.</item>
+ <item>(click to show algorithms explanation)\n\nTo avoid congestion collapse, TCP uses a multi-faceted congestion-control strategy.
+ For each connection, TCP maintains a congestion window,
+ limiting the total number of unacknowledged packets that may be in transit end-to-end.
+ This is somewhat analogous to TCP\'s sliding window used for flow control.
+ TCP uses a mechanism called slow start to increase the congestion window after a connection is initialized and after a timeout.
+ It starts with a window of two times the maximum segment size (MSS).
+ Although the initial rate is low, the rate of increase is very rapid:
+ for every packet acknowledged, the congestion window increases by 1 MSS
+ so that the congestion window effectively doubles for every round-trip time (RTT).
+ When the congestion window exceeds a threshold ssthresh the algorithm enters a new state,
+ called congestion avoidance. In some implementations (e.g., Linux), the initial ssthresh is large,
+ and so the first slow start usually ends after a loss.
+ However, ssthresh is updated at the end of each slow start,
+ and will often affect subsequent slow starts triggered by timeouts.</item>
+ <item>Fsync transfers (\"flushes\") all modified in-core data of (i.e.,
+ modified buffer cache pages for) the file referred to by the file
+ descriptor to the disk device (or other permanent storage device)
+ so that all changed information can be retrieved even after the
+ system crashed or was rebooted. This includes writing through or
+ flushing a disk cache if present. The call blocks until the device
+ reports that the transfer has completed. It also flushes metadata
+ information associated with the file </item>
+ <item>Fast Charge function will drain more current from PC or Notebook when your device is plugged, so your device will charge faster.
+ Fast Charge will not damage your device and will not damage your laptop.</item>
+ <item>This parameter will change the vibration strength. Increasing this value means a stronger vibration feedback. Minimum values is 0, maximum 100</item>
+ <item>Maximum CPU temperature before the CPU gets throttled down to become cooler. Values are in °C</item>
+ <item>Increase or decrease headsets gain. Values from -20 to 20</item>
+ <item>Increase or decrease microphone gain. Values from -20 to 20</item>
+ <item>Increase or decrease speaker gain. Values from -20 to 20</item>
+ <item>Increase or decrease volume gain. Values from -20 to 20</item>
+ </string-array>
+ <string-array name="glo_sched_titles">
+ <item>Noop</item>
+ <item>Deadline</item>
+ <item>CFQ</item>
+ <item>BFQ</item>
+ <item>SIO</item>
+ <item>V(R)</item>
+ </string-array>
+ <string-array name="glo_sched_descs">
+ <item>Inserts all the incoming I/O requests to a First In First Out queue and implements request merging. Best used with storage devices that does not depend on mechanical movement to access data (yes, like our flash drives). Advantage here is that flash drives does not require reordering of multiple I/O requests unlike in normal hard drives.</item>
+ <item>Goal is to minimize I/O latency or starvation of a request. The same is achieved by round robin policy to be fair among multiple I/O requests. Five queues are aggressively used to reorder incoming requests.</item>
+ <item>Completely Fair Queuing scheduler maintains a scalable per-process I/O queue and attempts to distribute the available I/O bandwidth equally among all I/O requests. Each per-process queue contains synchronous requests from processes. Time slice allocated for each queue depends on the priority of the parent process. V2 of CFQ has some fixes which solves process\' i/o starvation and some small backward seeks in the hope of improving responsiveness.</item>
+ <item>Instead of time slices allocation by CFQ, BFQ assigns budgets. Disk is granted to an active process until it\'s budget (number of sectors) expires. BFQ assigns high budgets to non-read tasks. Budget assigned to a process varies over time as a function of it\'s behavior.</item>
+ <item>Simple I/O scheduler aims to keep minimum overhead to achieve low latency to serve I/O requests. No priority quesues concepts, but only basic merging. Sio is a mix between noop and deadline. No reordering or sorting of requests.</item>
+ <item>Unlike other schedulers, synchronous and asynchronous requests are not treated separately, instead a deadline is imposed for fairness. The next request to be served is based on it\'s distance from last request.</item>
+ </string-array>
+ <string-array name="glo_tcp_titles">
+ <item>Tahoe</item>
+ <item>Reno</item>
+ <item>Vegas</item>
+ <item>New Reno</item>
+ <item>Hybla</item>
+ <item>BIC</item>
+ <item>CUBIC</item>
+ <item>westwood</item>
+ <item>scalable</item>
+ <item>HTCP</item>
+ </string-array>
+ <string-array name="glo_tcp_descs">
+ <item>Triple duplicate ACKS are treated the same as a timeout. Tahoe will perform \"fast retransmit\", set the slow start threshold to half the current congestion window, reduce congestion window to 1 MSS, and reset to slow-start state.</item>
+ <item>If three duplicate ACKs are received (i.e., four ACKs acknowledging the same packet, which are not piggybacked on data, and do not change the receiver\'s advertised window), Reno will halve the congestion window (instead of setting it to 1 MSS like Tahoe), set the slow start threshold equal to the congestion window, perform a fast retransmit, and enter a phase called Fast Recovery.
+ If an ACK times out, slow start is used as it is with Tahoe.</item>
+ <item>Until the mid-1990s, all of TCP\'s set timeouts and measured round-trip delays were based upon only the last transmitted packet in the transmit buffer. University of Arizona researchers Larry Peterson and Lawrence Brakmo introduced TCP Vegas, named after the largest Nevada city, in which timeouts were set and round-trip delays were measured for every packet in the transmit buffer. In addition, TCP Vegas uses additive increases in the congestion window. This variant was not widely deployed outside Peterson\'s laboratory. In a comparison study of various TCP congestion control algorithms, TCP Vegas appeared to be the smoothest followed by TCP CUBIC.</item>
+ <item>TCP New Reno, defined by RFC 6582 (which obsoletes previous definitions in RFC 3782 and RFC 2582), improves retransmission during the fast-recovery phase of TCP Reno. During fast recovery, for every duplicate ACK that is returned to TCP New Reno, a new unsent packet from the end of the congestion window is sent, to keep the transmit window full. For every ACK that makes partial progress in the sequence space, the sender assumes that the ACK points to a new hole, and the next packet beyond the ACKed sequence number is sent.
+Because the timeout timer is reset whenever there is progress in the transmit buffer, this allows New Reno to fill large holes, or multiple holes, in the sequence space – much like TCP SACK. Because New Reno can send new packets at the end of the congestion window during fast recovery, high throughput is maintained during the hole-filling process, even when there are multiple holes, of multiple packets each. When TCP enters fast recovery it records the highest outstanding unacknowledged packet sequence number. When this sequence number is acknowledged, TCP returns to the congestion avoidance state.
+A problem occurs with New Reno when there are no packet losses but instead, packets are reordered by more than 3 packet sequence numbers. When this happens, New Reno mistakenly enters fast recovery, but when the reordered packet is delivered, ACK sequence-number progress occurs and from there until the end of fast recovery, every bit of sequence-number progress produces a duplicate and needless retransmission that is immediately ACKed.
+New Reno performs as well as SACK at low packet error rates, and substantially outperforms Reno at high error rates.</item>
+ <item>TCP Hybla aims to eliminate penalization of TCP connections that incorporate a high-latency terrestrial or satellite radio link, due to their longer round trip times. It stems from an analytical evaluation of the congestion window dynamics, which suggests the necessary modifications to remove the performance dependence on RTT.</item>
+ <item>Binary Increase Congestion control is an implementation of TCP with an optimized congestion control algorithm for high speed networks with high latency (called LFN, long fat networks, in RFC 1072). BIC is used by default in Linux kernels 2.6.8 through 2.6.18.</item>
+ <item>CUBIC is a less aggressive and more systematic derivative of BIC, in which the window is a cubic function of time since the last congestion event, with the inflection point set to the window prior to the event. CUBIC is used by default in Linux kernels since version 2.6.19.</item>
+ <item>TCP Westwood (TCPW) is a sender-side-only modification to TCP New Reno that is intended to better handle large bandwidth-delay product paths (large pipes), with potential packet loss due to transmission or other errors (leaky pipes), and with dynamic load (dynamic pipes).
+TCP Westwood relies on mining the ACK stream for information to help it better set the congestion control parameters: Slow Start Threshold (ssthresh), and Congestion Window (cwin). In TCP Westwood, an \"Eligible Rate\" is estimated and used by the sender to update ssthresh and cwin upon loss indication, or during its \"Agile Probing\" phase, a proposed modification to the well-known Slow Start phase. In addition, a scheme called Persistent Non Congestion Detection (PNCD) has been devised to detect persistent lack of congestion and induce an Agile Probing phase to expeditiously utilize large dynamic bandwidth.</item>
+ <item>Scalable TCP modifies the congestion control algorithm. Instead of halving the congestion window size, each packet loss decreases the congestion window by a small fraction (a factor of 1/8 instead of Standard TCP\'s 1/2) until packet loss stops. When packet loss stops, the rate is ramped up at a slow fixed rate (one packet is added for every one hundred successful acknowledgements) instead of the Standard TCP rate that\'s the inverse of the congestion window size (thus very large windows take a long time to recover). This helps reduce the recovery time on 10 Gbit links from 4+ hours (using Standard TCP) to less than 15 seconds when the round trip time is 200 milliseconds.</item>
+ <item>H-TCP is a loss-based algorithm, using additive-increase/multiplicative-decrease (AIMD) to control TCP\'s congestion window. It is one of many TCP congestion avoidance algorithms which seeks to increase the aggressiveness of TCP on high bandwidth-delay product (BDP) paths, while maintaining \"TCP friendliness\" for small BDP paths. H-TCP increases its aggressiveness (in particular, the rate of additive increase) as the time since the previous loss increases. This avoids the problem encountered by HSTCP and BIC TCP of making flows more aggressive if their windows are already large. Thus, new flows can be expected to converge to fairness faster under HTCP than HSTCP and BIC TCP.</item>
+ </string-array>
+ <string-array name="glo_vm_titles">
+ <item>Dirty Ratio</item>
+ <item>Dirty Background Ratio</item>
+ <item>Dirty Expire Centisecs</item>
+ <item>Dirty Writeback centisecs</item>
+ <item>Overcommit Ratio</item>
+ <item>Swappiness</item>
+ <item>VFS Cache Pressure</item>
+ </string-array>
+ <string-array name="glo_vm_descs">
+ <item>Contains, as a percentage of total available memory that contains free pages
+and reclaimable pages, the number of pages at which a process which is
+generating disk writes will itself start writing out dirty data.
+The total avaiable memory is not equal to total system memory.</item>
+ <item>Contains, as a percentage of total available memory that contains free pages
+and reclaimable pages, the number of pages at which the background kernel
+flusher threads will start writing out dirty data.
+The total avaiable memory is not equal to total system memory.</item>
+ <item>This tunable is used to define when dirty data is old enough to be eligible
+for writeout by the kernel flusher threads. It is expressed in 100\'ths
+of a second. Data which has been dirty in-memory for longer than this
+interval will be written out next time a flusher thread wakes up.</item>
+ <item>The kernel flusher threads will periodically wake up and write `old\' data
+out to disk. This tunable expresses the interval between those wakeups, in
+100\'ths of a second.</item>
+ <item>The kernel flusher threads will periodically wake up and write `old\' data
+out to disk. This tunable expresses the interval between those wakeups, in
+100\'ths of a second.</item>
+ <item>This control is used to define how aggressive the kernel will swap
+memory pages. Higher values will increase agressiveness, lower values
+decrease the amount of swap.
+The default value is 60.</item>
+ <item>Controls the tendency of the kernel to reclaim the memory which is used for
+caching of directory and inode objects.
+At the default value of vfs_cache_pressure=100 the kernel will attempt to
+reclaim dentries and inodes at a "fair" rate with respect to pagecache and
+swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer
+to retain dentry and inode caches. When vfs_cache_pressure=0, the kernel will
+never reclaim dentries and inodes due to memory pressure and this can easily
+lead to out-of-memory conditions. Increasing vfs_cache_pressure beyond 100
+causes the kernel to prefer to reclaim dentries and inodes.</item>
+ </string-array>
+ <string-array name="glo_lmk_titles">
+ <item>Low Memory Killer</item>
+ </string-array>
+ <string-array name="glo_lmk_descs">
+ <item>When your phone boots up, a file inside the boot image (init.rc) sets the system parameters. Things like the path to framework files, setting up your networks, and setting the limits at which programs are killed off to free RAM are done by this file. The killing parameters are knows as Low Memory Killer Parameters</item>
+ </string-array>
+
+ <!-- Menu -->
+ <string name="mt_refresh">Refresh</string>
+ <string name="mt_app_settings">"App Settings"</string>
+ <string name="mt_reset">Reset</string>
+ <string name="mt_restore">Restore</string>
+ <string name="mt_plus25">Increase by 25 mV</string>
+ <string name="mt_minus25">Decrease by 25 mV</string>
+ <!-- CPU settings -->
+ <string name="current_speed">Current Speed</string>
+ <string name="current_max">Maximum speed: </string>
+ <string name="current_min">Minimum speed: </string>
+ <string name="governor">Governor</string>
+ <string name="io">I/O Scheduler</string>
+ <string name="sob">Apply automatically on boot</string>
+ <string name="ok">OK</string>
+ <string name="cancel">Cancel</string>
+ <string name="cpu_info_list_header">Core Status</string>
+ <string name="cpu_speed_header">Core Limits</string>
+ <string name="other_settings_header">Other settings</string>
+ <string name="core_offline">Offline</string>
+ <string name="core">Core</string>
+
+ <!-- Other settings -->
+ <string name="prefcat_free_memory">FREE MEMORY</string>
+ <string name="prefcat_tweaks">FAST CHARGE</string>
+ <string name="prefcat_misc_short">MISC</string>
+ <string name="prefcat_read_ahead">SD READ AHEAD</string>
+ <string name="prefcat_vm_settings">DALVIK SETTINGS</string>
+ <string name="dt_free_memory">Minfree Taskkiller</string>
+ <string name="dt_read_ahead">SD Read Ahead</string>
+ <string name="pt_free_memory">Free memory</string>
+ <string name="ps_free_memory">Amount of RAM the minfree taskkiller will keep |
+ Current: %s</string>
+ <string name="ps_free_memory_boot">Apply the amount above at boot</string>
+ <string name="pt_read_ahead">Storage read ahead</string>
+ <string name="ps_read_ahead">Amount to read ahead on storage, in kb |
+ Current: %s</string>
+ <string name="ps_fast_charge_boot">Fast charge</string>
+ <string name="fast_charge_warning">YOU WILL NOT BE ABLE TO CONNECT TO YOUR PC AFTER
+ EACH REBOOT!\n\nWhile Fast Charge is ON, you can *only* charge your phone!</string>
+ <string name="fast_charge_notification_title">Fast Charge is ON!</string>
+ <string name="fast_charge_notification_message">Phone is in charge-only mode!</string>
+
+ <!-- minfree -->
+ <string name="prefcat_oom">MINIMUM FREE MEMORY</string>
+ <string name="title_foreground_app">Foreground applications</string>
+ <string name="title_visible_app">Visible Applications</string>
+ <string name="title_secondary_server">Secondary Server</string>
+ <string name="title_hidden_app">Hidden Applications</string>
+ <string name="title_content_providers">Content Providers</string>
+ <string name="title_empty_app">Empty Applications</string>
+ <string name="prefcat_oom_predefines">PRESETS</string>
+ <string name="pt_oom">Minfree Taskkiller Presets</string>
+ <string name="pt_verylight">Very Light (Kills rarely)</string>
+ <string name="pt_light">Light</string>
+ <string name="pt_medium">Medium</string>
+ <string name="pt_aggressive">Aggressive</string>
+ <string name="pt_veryaggressive">Very Aggressive (Kills often)</string>
+
+ <!-- do not kill proc -->
+ <string name="prefcat_user_proc">NOT KILLABLE USER PROCESSES</string>
+ <string name="prefcat_sys_proc">NOT KILLABLE SYSTEM PROCESSES</string>
+ <string name="pt_user_proc">Enable not killable user processes</string>
+ <string name="pt_sys_proc">Enable not killable system processes</string>
+ <string name="pt_user_names_proc">User Processes whitelist</string>
+ <string name="pt_sys_names_proc">System Processes whitelist</string>
+ <string name="ps_restore_boot">Restore above settings at boot</string>
+ <string name="ps_user_proc">The list of user process names (comma separated)</string>
+ <string name="ps_sys_proc">The list of system process names (comma separated)</string>
+ <string name="no_proc">No packages</string>
+ <!-- bln -->
+ <string name="prefcat_bln">BACKLIGHT NOTIFICATION</string>
+ <string name="pt_bln">Backlight Notification</string>
+ <!-- blx -->
+ <string name="blx_info">Battery Life eXtender feature\nAuthor Ezekeel</string>
+ <string name="prefcat_blx">BATTERY LIFE EXTENDER</string>
+ <string name="pt_blx_boot">Set on boot</string>
+ <string name="ps_blx_boot">Apply the amount above at boot</string>
+ <string name="blx_title">Charge limit:</string>
+ <!-- dsync -->
+ <string name="dsync_info">Dynamic FSync feature\nAuthor Paul Reioux (faux123)</string>
+ <string name="prefcat_dsync">DYNAMIC FSYNC</string>
+ <string name="ps_dsync">Setting will be restored on reboot</string>
+ <string name="pt_dsync">Dynamic Fsync</string>
+ <!-- bl_timeout -->
+ <string name="prefcat_bltimeout">BACKLIGHT TIMEOUT</string>
+ <string name="ps_bltimeout">%s ms</string>
+ <string name="bltimeout_title">Backlight timeout</string>
+ <!-- bl_touch -->
+ <string name="prefcat_bltouch">BACKLIGHT ON TOUCHSCREEN</string>
+ <string name="pt_bltouch">Backlight on touchscreen</string>
+ <!-- pfk -->
+ <string name="pfk_info">Phantom Key Presses Filter module ver. %s\nAuthor Cristoforo Cataldo (Christopher83)</string>
+ <string name="prefcat_pfk">PHANTOM KEY PRESSES FILTER</string>
+ <string name="pt_home_enabled">Home key filter</string>
+ <string name="ps_home_enabled">Ignored key pressed: %s</string>
+ <string name="home_allowed_irq_title">Max allowed interrupts</string>
+ <string name="home_report_wait_title">Report wait time</string>
+ <string name="pt_menuback_enabled">Menu/Back keys filter</string>
+ <string name="ps_menuback_enabled">Ignored key pressed: %s</string>
+ <string name="menuback_interrupt_checks_title">Interrupts checks</string>
+ <string name="menuback_first_err_wait_title">First error wait time</string>
+ <string name="menuback_last_err_wait_title">Last error wait time</string>
+ <string name="ps_pfk_set_on_boot">If enabled will restore all pkf settings on reboot</string>
+ <!-- dynamic write back -->
+ <string name="dynamic_writeback_info">Dynamic Dirty Page Writebacks feature\nAuthor Cristoforo Cataldo (Christopher83)</string>
+ <string name="dynamic_write_back_title">DYNAMIC DIRTY PAGE WRITEBACKS</string>
+ <string name="pt_dynamic_write_back">Dynamic Dirty Writeback</string>
+ <string name="dynamic_writeback_active_title">Dirty Writeback Active centisecs</string>
+ <string name="dynamic_writeback_suspend_title">Dirty Writeback Suspend centisecs</string>
+ <!-- -->
+ <string name="size_25_mb">25mb</string>
+ <string name="size_50_mb">50mb</string>
+ <string name="size_75_mb">75mb</string>
+ <string name="size_80_mb">80mb</string>
+ <string name="size_100_mb">100mb</string>
+ <string name="size_128_kb">128kb</string>
+ <string name="size_256_kb">256kb</string>
+ <string name="size_512_kb">512kb</string>
+ <string name="size_1024_kb">1024kb</string>
+ <string name="size_2048_kb">2048kb</string>
+ <string name="size_4096_kb">4096kb</string>
+ <!-- Voltage control -->
+ <string name="volt_info">ATTENTION!\nBefore activating Set on boot, make sure that the values ​​entered do not exceed limits or risk the phone to freeze.</string>
+ <string name="ps_volt_mhz_voltage">" Hz"</string>
+ <string name="ps_volt_save">"Save"</string>
+ <string name="ps_volt_current_voltage">"Current voltage: "</string>
+ <string name="ps_volt_setting_to_apply">"Setting to apply: "</string>
+ <string name="pt_volt_control">Voltage control</string>
+ <string name="ps_volt_control">Set voltages for each frequency</string>
+ <string name="apply_values">Apply values</string>
+ <string name="freq">Frequency</string>
+ <string name="current">mV current</string>
+ <string name="saved">mV saved</string>
+ <string name="not_supported">Your kernel does not support voltage control</string>
+ <!-- VM settings -->
+ <string name="ps_vm_set_on_boot">If enabled will restore all vm settings on reboot</string>
+ <string name="dirty_ratio_title">Dirty ratio</string>
+ <string name="dirty_ratio_summary">A higher ratio means lower CPU but slower app startups</string>
+ <string name="dirty_background_title">Dirty background ratio</string>
+ <string name="dirty_expire_title">Dirty expire centisecs</string>
+ <string name="dirty_writeback_title">Dirty writeback centisecs</string>
+ <string name="min_free_title">Minfree kbytes</string>
+ <string name="overcommit_title">Overcommit ratio</string>
+ <string name="swappiness_title">Swappiness</string>
+ <string name="vfs_title">VFS cache pressure</string>
+ <!-- Time in state -->
+ <string name="time_in_state">TIME IN STATE</string>
+ <string name="unused_cpu_states">UNUSED CPU STATES</string>
+ <string name="total_state_time">TOTAL STATE TIME</string>
+ <string name="no_states_file_found">No states file found. Are you sure your phone is
+ compatible?\n\nIf you are running a custom ROM or kernel, try
+ contacting its developer to inform him that the states file is not
+ readable.</string>
+ <string name="deep_sleep">"Deep Sleep"</string>
+ <!-- CPU info -->
+ <string name="kernel_info">LINUX KERNEL INFORMATION</string>
+ <string name="cpu_info">CPU INFORMATION</string>
+ <string name="mem_info">MEMORY INFORMATION</string>
+ <string name="first_run_title">First check for root</string>
+ <string name="su_success_title">Success!</string>
+ <string name="su_failed_title">Oops!</string>
+ <string name="first_run_message">The application needs to check for root access and
+ busybox. Press OK to continue. Cancel if you would not like to grant
+ root access.</string>
+ <string name="su_success_message">Performance Control was able to get root access and
+ find busybox. Ready to rock!</string>
+ <string name="su_cancel_message">You have chosen to not check for root and busybox.
+ Most options will not work without root access. Sorry!</string>
+ <string name="su_failed_su_or_busybox">Root access failed or busybox was not found. Most
+ options will not work without root access. Sorry!</string>
+
+ <!-- Tools -->
+ <string name="prefcat_sh">CUSTOM SHELL COMMAND</string>
+ <string name="sh_title">Edit shell command</string>
+ <string name="ps_sh">Command will be executed at boot.</string>
+ <string name="sh_msg">Leave blank for no operation.</string>
+ <string name="clear">Clear</string>
+ <string name="yes">Yes</string>
+ <string name="wait">Please wait…</string>
+ <string name="prefcat_wipe_cache">CACHE and DALVIK CACHE</string>
+ <string name="wipe_cache_title">Wipe cache and dalvik cache</string>
+ <string name="ps_wipe_cache">Cache partition: %s</string>
+ <string name="wipe_cache_msg">At the end, the system will reboot. Continue?</string>
+ <string name="prefcat_flash_img">FLASH IMG FILE</string>
+ <string name="kernel_img_title">Flash KERNEL</string>
+ <string name="ps_kernel_img">Flash boot.img files as kernel. Can choose individual boot.img file or any zip file that contains boot.img</string>
+ <string name="recovery_img_title">Flash RECOVERY</string>
+ <string name="ps_recovery_img">Flash recovery.img files as recovery. Can choose individual recovery.img file or any zip file that contains recovery.img</string>
+ <string name="btn_choose">Choose %s</string>
+ <string name="unsupported_info">Your device is not supported.</string>
+ <string name="flash_info">will be flashed on partition\n%s\n as</string>
+ <string name="dir_parent">&lt;Parent DIR&gt;</string>
+ <string name="dir">&lt;DIR&gt;</string>
+ <string name="bkexit">Press again to exit</string>
+ <string name="prefcat_residual_files">CLEAN RESIDUAL FILES</string>
+ <string name="residual_files_title">Clean residual files</string>
+ <string name="btncleanall">Clean all</string>
+ <string name="clean_files_msg">Residual files from %s will be deleted. Continue?</string>
+ <string name="filesstr">file(s)</string>
+ <string name="no_residuals">No residual files</string>
+ <string name="prefcat_optim_db">OPTIMIZE DBs</string>
+ <string name="optim_db_title">Optimize Databases</string>
+ <string name="ps_optim_db">This will optimize databases by using SQL command VACUUM.</string>
+
+ <string-array name="residual_info">
+ <item>Contains Android system log files</item>
+ <item>Contains log files from crashed apps</item>
+ <item>Contains constantly generated log files</item>
+ <item>Contains statistics about what apps you started</item>
+ <item>Contains traces from \'application not responding\' events</item>
+ <item>Contains temporary files</item>
+ </string-array>
+
+ <string name="prefcat_fix_perms">FIX PERMISSIONS</string>
+ <string name="fix_perms_title">Fix permissions</string>
+ <string name="fix_perms_msg">Operation may take several minutes. Continue?</string>
+ <string name="preflogg_fix_perms">Enable logging</string>
+ <string name="free">free %s</string>
+ <string name="used">used %s</string>
+
+ <!-- 2.1.0 -->
+ <string name="verify">Verifying…</string>
+ <string name="bad_zip">%s not found in zip file !</string>
+ <string name="closebtn">Close</string>
+ <string name="delallbtn">Delete all</string>
+ <string name="del_file_msg">%s will be deleted. Continue?</string>
+
+ <string-array name="batt_status">
+ <item>Unknown</item>
+ <item>Unknown</item>
+ <item>Charging</item>
+ <item>Discharging</item>
+ <item>Full</item>
+ <item>Not charging</item>
+ </string-array>
+ <!-- 2.1.2 -->
+ <!-- ksm -->
+ <string name="prefcat_ksm">KERNEL SAMEPAGE MERGING</string>
+ <string name="pt_run_ksm">Enable KSM</string>
+ <string name="ksm_adv_title">Settings</string>
+ <string name="ksm_fullscans">Full Scans:</string>
+ <string name="ksm_pagshared">Pages Shared:</string>
+ <string name="ksm_pagsharing">Pages Sharing:</string>
+ <string name="ksm_pagunshared">Pages Unshared:</string>
+ <string name="ksm_pagvolatile">Pages Volatile:</string>
+ <string name="ksm_pagtoscan">Pages to Scan:</string>
+ <string name="ksm_sleep">Sleep (ms):</string>
+
+ <!-- freezer -->
+ <string name="prefcat_freezer">FREEZE or DEFROST PACKAGES</string>
+ <string name="pt_freeze">Freeze Package</string>
+ <string name="pt_unfreeze">Defrost Package</string>
+ <string name="ps_freeze">List of all installed packages</string>
+ <string name="ps_unfreeze">List of frozen packages</string>
+ <string name="mt_system_packs">System Packages</string>
+ <string name="mt_user_packs">User Packages</string>
+ <string name="freeze_msg">%s will be frozen. Continue?</string>
+ <string name="unfreeze_msg">%s will be defrosted. Continue?</string>
+
+ <!-- zRam -->
+ <string name="prefcat_zram">zRAM</string>
+ <string name="pt_run_zram">Enable zRam</string>
+ <string name="zram_set_title">Settings</string>
+ <!-- 2.1.3 -->
+ <string name="ps_zram">Compress memory for increased virtual capacity</string>
+ <string name="mt_gov_ctrl">Governor Settings</string>
+
+ <!-- PC Settings -->
+ <string name="pt_use_light_theme">Use light theme</string>
+ <string name="ps_use_light_theme">If checked, Performance Control will use a Holo light theme</string>
+ <string name="pt_widget_bg_color">Widget bg color</string>
+ <string name="pt_widget_text_color">Widget text color</string>
+ <string name="pt_ver">"Version - "</string>
+ <!-- Color picker -->
+ <string name="dialog_color_picker">Color Picker</string>
+ <string name="press_color_to_apply">Press on Color to apply</string>
+ <string name="arrow_right">→</string>
+ <string name="arrow_down">↓</string>
+ <string name="hex">Hex:</string>
+ <string name="hex_hint">#FF000000</string>
+ <string name="set">Set</string>
+ <string name="ics_color">Holo</string>
+
+ <!-- Drawer -->
+ <string name="navigation_drawer_toggle">Toggle Drawer</string>
+ <string name="navigation_drawer_open">Open navigation drawer</string>
+ <string name="navigation_drawer_close">Close navigation drawer</string>
+ <string name="navigation_toggle_drawer">Switch to Drawer</string>
+ <string name="navigation_toggle_tabbed">Switch to Tabbed</string>
+
+
+ <!-- Performance Settings | Warning dialog -->
+ <string name="performance_settings_warning_title">Proceed with Caution</string>
+ <string name="performance_settings_warning_header">Warning</string>
+
+ <!-- PropModder -->
+ <string name="propmodder_title">Build.prop Mods</string>
+ <string name="propmodder_switches">Switches</string>
+ <string name="buildprop_title">build.prop mods (reboot required)</string>
+ <string name="buildprop_settings_warning">These settings are for experimentation and any changes made to them have the potential to cause instability, crashes, data loss or hardware failures.</string>
+ <string name="nonprop_cat_title">Mods involving init.d script</string>
+ <string name="pref_wifi_scan_interval_title">Wifi scan interval</string>
+ <string name="pref_wifi_scan_interval_summary">The time between wifi scans when no stored access points are available</string>
+ <string name="pref_wifi_scan_alt_summary">Time between wifi scans: %s</string>
+ <string name="pref_max_events_title">Windows Manager\'s max events per second</string>
+ <string name="pref_max_events_summary">This is a runtime value that controls the number of events the system will allow in a second</string>
+ <string name="pref_max_events_alt_summary">Max number of system events: %s</string>
+ <string name="pref_ring_delay_title">Telephone ringer delay</string>
+ <string name="pref_ring_delay_summary">The amount of time from when the system registers an incoming phone call until the ringer</string>
+ <string name="pref_ring_delay_alt_summary">Incoming call Delay: %s</string>
+ <string name="pref_vm_heapsize_title">Dalvik cache heapsize</string>
+ <string name="pref_vm_heapsize_summary">This controls the size of the cache the Dalvik VM has access to</string>
+ <string name="pref_vm_heapsize_alt_summary">Dalvik VM cache size: %s</string>
+ <string name="showbuild_title">Show The Build.Prop</string>
+ <string name="buildprop_summary">Find out whats in there</string>
+ <string name="showbuild_dialog">Displaying /system/Build.Prop</string>
+ <string name="showbuild_loading">Loading build.prop\u2026</string>
+ <string name="showbuild_error">Error loading build.prop\u2026</string>
+ <string name="showbuild_unknown">Unknown</string>
+ <string name="showbuild_version">Version</string>
+ <string name="showbuild_label">We should look because knowing is half the battle</string>
+ <string name="pref_fast_up_title">HSUPA upload speed hack</string>
+ <string name="pref_fast_up_summary">*WARNING* if you change this value it will add the needed values to your build.prop if they are not already present</string>
+ <string name="pref_fast_up_alt_summary">Fast up found active: %s</string>
+ <string name="pref_prox_delay_title">Proximity sensor delay</string>
+ <string name="pref_prox_delay_summary">When you are in-call screen is off when the device moves away from your face this delay value controls how long before screen turns on</string>
+ <string name="pref_prox_delay_alt_summary">Proximity sensor set to: %s</string>
+ <string name="pref_mod_version_title">Change your Build Number</string>
+ <string name="pref_mod_version_summary">This is astetic and doesn\'t improve the system</string>
+ <string name="pref_mod_version_alt_summary">Build Number: %s</string>
+ <string name="pref_mod_version_default"></string>
+ <string name="pref_sleep_title">PM Sleep mode</string>
+ <string name="pref_sleep_summary">Modify Nighttime sleep policy</string>
+ <string name="pref_sleep_alt_summary">Current Sleep Mode: %s</string>
+ <string name="pref_jit_title">Just In Time Complier</string>
+ <string name="pref_jit_summary">Enables/Disables JIT complier</string>
+ <string name="pref_tcp_stack_title">Optimize TCP Stack</string>
+ <string name="pref_tcp_stack_summary">Modify the buffer-size for better performance</string>
+ <string name="pref_g_speed_title">3G Speed Hack</string>
+ <string name="pref_g_speed_summary">Uncap 3g speed</string>
+ <string name="pref_gpu_title">GPU Acceleration</string>
+ <string name="pref_gpu_summary">Enable hardware acceleration where the GPU controls the UI instead of the CPU</string>
+ <string name="pref_lcd_title">Change LCD density</string>
+ <string name="pref_lcd_summary">Set your desired LCD density</string>
+ <string name="pref_lcd_default">480</string>
+ <string name="pref_lcd_alt_summary">Screen density: %s</string>
+
+ <!-- Init.d -->
+ <string name="header_summary_init_d">@null</string>
+ <string name="init_d_title">Init.d Tweaks</string>
+ <string name="pt_general">General</string>
+ <string name="pt_zipalign_apks">Zipalign apps</string>
+ <string name="ps_zipalign_apks">Zipalign any unaligned apps on each boot</string>
+ <string name="pt_fix_permissions">Fix permissions</string>
+ <string name="ps_fix_permissions">Fix permissions on apps and their data on each boot</string>
+ <string name="pt_enable_sysctl">Enable sysctl</string>
+ <string name="ps_enable_sysctl">Enable sysctl tweaks at boot</string>
+ <string name="pt_free_mem">Free memory</string>
+ <string name="ps_free_mem">Set minfree values at boot</string>
+ <string name="pt_clear_data_cache">Clear cache</string>
+ <string name="ps_clear_data_cache">Clear application cache files each boot</string>
+ <string name="pt_enable_cron">Enable scheduled tasks</string>
+ <string name="ps_enable_cron">Enable scheduled cron jobs</string>
+ <string name="pt_sd_boost">Enable SD boost</string>
+ <string name="ps_sd_boost">Enable/disable SD card speed boost</string>
+ <string name="pt_file_system_speedups">File system speedup</string>
+ <string name="ps_file_system_speedups">Speed up file systems at boot</string>
+ <string name="pt_foreground_app_mem">Foreground app mem</string>
+ <string name="pt_visible_app_mem">Visible app mem</string>
+ <string name="pt_perceptible_app_mem">Perceptible app mem</string>
+ <string name="pt_heavy_weight_app_mem">Heavy weight app mem</string>
+ <string name="pt_secondary_server_mem">Secondary server app mem</string>
+ <string name="pt_backup_app_mem">Backup app mem</string>
+ <string name="pt_home_app_mem">Home app mem</string>
+ <string name="pt_hidden_app_mem">Hidden app mem</string>
+ <string name="pt_empty_app_mem">Empty app mem</string>
+ <string name="pt_read_ahead_kb">Read ahead value</string>
+ <string name="pt_minfree_values">Minfree values</string>
+ <string name="pt_battery">Enable battery tweaks</string>
+ <string name="ps_battery">Enable/disable battery saving tweaks</string>
+ <string name="pt_touch">Enable touch tweaks</string>
+ <string name="ps_touch">Enable/disable touchscreen tweaks</string>
+ <string name="pt_minfree">Enable minfree values</string>
+ <string name="ps_minfree">Enable/disable minfree tweaks</string>
+ <string name="pt_gpurender">Enable gpu render</string>
+ <string name="ps_gpurender">Enable/disable gpu rendering tweaks</string>
+ <string name="pt_sleepers">Enable sleeping</string>
+ <string name="ps_sleepers">Enable/disable sleeping tweaks</string>
+ <string name="pt_journalism">Enable journalism</string>
+ <string name="ps_journalism">Enable/disable journalism tweaks</string>
+ <string name="pt_sqlite3">Enable sqlite3</string>
+ <string name="ps_sqlite3">Enable/disable sqlite3 tweaks</string>
+ <string name="pt_wifisleep">Enable wifi sleep</string>
+ <string name="ps_wifisleep">Enable/disable wifi sleep tweaks</string>
+ <string name="pt_iostats">Enable iostats</string>
+ <string name="ps_iostats">Enable/disable iostats</string>
+ <string name="pt_setrenice">Enable setrenice</string>
+ <string name="ps_setrenice">Enable/disable setrenice</string>
+ <string name="pt_tweaks">Enable super tweaks</string>
+ <string name="ps_tweaks">Enable/disable super tweaks</string>
+ <string name="pt_speedy_modified">Enable speedy modified</string>
+ <string name="ps_speedy_modified">Enable/disable Speedy modified tweaks</string>
+ <string name="pt_loopy_smoothness_tweak">Enable loopy smoothness</string>
+ <string name="ps_loopy_smoothness_tweak">Enable/disable loopy smoothness tweaks</string>
+ <string name="pt_init_d_credits">Developed by:</string>
+ <string name="ps_init_d_credits">Jared Rummler (JRummy16)</string>
+ <string name="dt_init_d_error">Init.d error</string>
+ <string name="dm_init_d_error">It looks like init.d isn\'t setup properly. Blame Kenneth!</string>
+ <string name="db_exit">Exit</string>
+
+ <!-- PropModder -->
+ <string-array name="entries_wifi_scan" translatable="false">
+ <item>0</item>
+ <item>15</item>
+ <item>30</item>
+ <item>45</item>
+ <item>60</item>
+ <item>75</item>
+ <item>90</item>
+ <item>105</item>
+ <item>120</item>
+ <item>135</item>
+ <item>150</item>
+ <item>165</item>
+ <item>180</item>
+ <item>195</item>
+ <item>210</item>
+ <item>225</item>
+ <item>240</item>
+ <item>255</item>
+ <item>270</item>
+ <item>285</item>
+ <item>300</item>
+ <item>315</item>
+ <item>330</item>
+ <item>345</item>
+ <item>360</item>
+ <item>375</item>
+ <item>390</item>
+ <item>405</item>
+ <item>420</item>
+ </string-array>
+
+ <string-array name="entries_lcd_density" translatable="false">
+ <item>240</item>
+ <item>242</item>
+ <item>244</item>
+ <item>246</item>
+ <item>248</item>
+ <item>250</item>
+ <item>252</item>
+ <item>254</item>
+ <item>256</item>
+ <item>258</item>
+ <item>260</item>
+ <item>262</item>
+ <item>264</item>
+ <item>266</item>
+ <item>268</item>
+ <item>270</item>
+ <item>272</item>
+ <item>274</item>
+ <item>276</item>
+ <item>278</item>
+ <item>280</item>
+ <item>282</item>
+ <item>284</item>
+ <item>285</item>
+ <item>286</item>
+ <item>288</item>
+ <item>290</item>
+ <item>292</item>
+ <item>294</item>
+ <item>296</item>
+ <item>298</item>
+ <item>300</item>
+ <item>302</item>
+ <item>304</item>
+ <item>306</item>
+ <item>308</item>
+ <item>310</item>
+ <item>312</item>
+ <item>314</item>
+ <item>316</item>
+ <item>318</item>
+ <item>320</item>
+ <item>322</item>
+ <item>324</item>
+ <item>326</item>
+ <item>328</item>
+ <item>330</item>
+ <item>332</item>
+ <item>334</item>
+ <item>336</item>
+ <item>338</item>
+ <item>340</item>
+ <item>342</item>
+ <item>344</item>
+ <item>346</item>
+ <item>348</item>
+ <item>350</item>
+ <item>352</item>
+ <item>354</item>
+ <item>356</item>
+ <item>358</item>
+ <item>360</item>
+ </string-array>
+
+ <string-array name="entries_max_events" translatable="false">
+ <item>60</item>
+ <item>65</item>
+ <item>70</item>
+ <item>75</item>
+ <item>80</item>
+ <item>85</item>
+ <item>90</item>
+ <item>95</item>
+ <item>100</item>
+ <item>105</item>
+ <item>110</item>
+ <item>115</item>
+ <item>120</item>
+ <item>160</item>
+ <item>165</item>
+ <item>170</item>
+ <item>175</item>
+ <item>180</item>
+ <item>185</item>
+ <item>190</item>
+ <item>195</item>
+ <item>200</item>
+ <item>205</item>
+ <item>210</item>
+ <item>215</item>
+ <item>220</item>
+ <item>225</item>
+ <item>230</item>
+ <item>235</item>
+ <item>240</item>
+ <item>245</item>
+ <item>250</item>
+ <item>260</item>
+ <item>265</item>
+ <item>270</item>
+ <item>275</item>
+ <item>280</item>
+ <item>290</item>
+ <item>295</item>
+ <item>300</item>
+ </string-array>
+
+ <string-array name="entries_ring_delay" translatable="false">
+ <item>0</item>
+ <item>50</item>
+ <item>100</item>
+ <item>200</item>
+ <item>300</item>
+ <item>400</item>
+ <item>500</item>
+ <item>600</item>
+ <item>700</item>
+ <item>800</item>
+ <item>900</item>
+ <item>1000</item>
+ <item>1050</item>
+ <item>1100</item>
+ <item>1200</item>
+ <item>1300</item>
+ <item>1400</item>
+ <item>1500</item>
+ <item>1600</item>
+ <item>1700</item>
+ <item>1800</item>
+ <item>1900</item>
+ <item>2000</item>
+ <item>2050</item>
+ <item>2100</item>
+ <item>2200</item>
+ <item>2300</item>
+ <item>2400</item>
+ <item>2500</item>
+ <item>3000</item>
+ </string-array>
+
+ <string-array name="entries_vm_heapsize" translatable="false">
+ <item>16m</item>
+ <item>24m</item>
+ <item>28m</item>
+ <item>32m</item>
+ <item>36m</item>
+ <item>42m</item>
+ <item>48m</item>
+ <item>52m</item>
+ <item>56m</item>
+ <item>64m</item>
+ <item>68m</item>
+ <item>72m</item>
+ <item>76m</item>
+ <item>84m</item>
+ <item>96m</item>
+ <item>128m</item>
+ <item>160m</item>
+ <item>192m</item>
+ <item>224m</item>
+ <item>256m</item>
+ <item>320m</item>
+ <item>384m</item>
+ <item>448m</item>
+ <item>512m</item>
+ <item>576m</item>
+ <item>640m</item>
+ <item>704m</item>
+ <item>768m</item>
+ </string-array>
+
+ <string-array name="entries_fast_up_explain">
+ <item>Remove</item>
+ <item>HSUPA Disabled (Capped)</item>
+ <item>HSUPA Enabled</item>
+ <item>HSUPA Enabled (Uncapped)</item>
+ </string-array>
+
+ <string-array name="entries_fast_up" translatable="false">
+ <item>disable</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ </string-array>
+
+ <string-array name="entries_prox_delay_explain">
+ <item>Remove</item>
+ <item>0</item>
+ <item>50</item>
+ <item>75</item>
+ <item>125</item>
+ <item>150</item>
+ <item>175</item>
+ <item>200</item>
+ <item>225</item>
+ <item>250</item>
+ <item>275</item>
+ <item>300</item>
+ <item>325</item>
+ <item>350</item>
+ <item>375</item>
+ <item>400</item>
+ <item>425</item>
+ <item>450</item>
+ <item>475</item>
+ <item>500</item>
+ </string-array>
+
+ <string-array name="entries_prox_delay">
+ <item>disable</item>
+ <item>0</item>
+ <item>50</item>
+ <item>75</item>
+ <item>125</item>
+ <item>150</item>
+ <item>175</item>
+ <item>200</item>
+ <item>225</item>
+ <item>250</item>
+ <item>275</item>
+ <item>300</item>
+ <item>325</item>
+ <item>350</item>
+ <item>375</item>
+ <item>400</item>
+ <item>425</item>
+ <item>450</item>
+ <item>475</item>
+ <item>500</item>
+ </string-array>
+
+ <string-array name="entries_sleep_explain">
+ <item>Disable</item>
+ <item>Power Collapse Suspend</item>
+ <item>Power Collapse (Best)</item>
+ <item>Apps Sleep</item>
+ <item>Slow Clock</item>
+ <item>Wait For Interrupt</item>
+ </string-array>
+
+ <string-array name="entries_sleep">
+ <item>disable</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>4</item>
+ </string-array>
+
+</resources> \ No newline at end of file
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 0000000..a073ec2
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,55 @@
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+
+ <style name="dialog_animation">
+ <item name="android:windowEnterAnimation">@anim/card_flip_left_in</item>
+ <item name="android:windowExitAnimation">@anim/card_flip_right_out</item>
+ </style>
+
+ <style name="EditTextAppTheme" parent="android:Widget.EditText">
+ <item name="android:background">@drawable/apptheme_edit_text_holo_dark</item>
+ <item name="android:textColor">#ffffff</item>
+ </style>
+
+ <style name="RadioButtonAppTheme" parent="android:Widget.CompoundButton.RadioButton">
+ <item name="android:button">@drawable/apptheme_btn_radio_holo_dark</item>
+ </style>
+
+ <style name="SeekBarAppTheme" parent="android:Widget.SeekBar">
+ <item name="android:progressDrawable">@drawable/apptheme_scrubber_progress_horizontal_holo_dark</item>
+ <item name="android:indeterminateDrawable">@drawable/apptheme_scrubber_progress_horizontal_holo_dark</item>
+ <item name="android:minHeight">13dip</item>
+ <item name="android:maxHeight">13dip</item>
+ <item name="android:thumb">@drawable/apptheme_scrubber_control_selector_holo_dark</item>
+ <item name="android:thumbOffset">16dip</item>
+ <item name="android:paddingLeft">16dip</item>
+ <item name="android:paddingRight">16dip</item>
+ </style>
+
+ <style name="ActionBar.Style" parent="android:Widget.Holo.Light.ActionBar.Solid.Inverse">
+ <item name="android:titleTextStyle">@style/TitleTextStyle</item>
+ </style>
+
+ <style name="TitleTextStyle" parent="@android:style/TextAppearance">
+ <item name="android:textColor">#FFFFFF</item>
+ </style>
+
+ <style name="LightListViewStyle" parent="@android:style/Widget.ListView">
+ <item name="android:dividerHeight">1px</item>
+ <item name="android:divider">@drawable/screen_background_selector_dark</item>
+ </style>
+
+</resources> \ No newline at end of file
diff --git a/res/values/themes.xml b/res/values/themes.xml
new file mode 100644
index 0000000..6bcdd44
--- /dev/null
+++ b/res/values/themes.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <style name="AppTheme" parent="android:Theme.Holo">
+ <item name="android:windowBackground">@drawable/screen_background_selector_dark</item>
+ <!-- <item name="android:editTextStyle">@style/EditTextAppTheme</item> -->
+ <item name="android:radioButtonStyle">@style/RadioButtonAppTheme</item>
+ <!-- <item name="android:seekBarStyle">@style/SeekBarAppTheme</item> -->
+ <item name="android:actionBarStyle">@style/ActionBar.Style</item>
+ <item name="android:listViewStyle">@android:style/Widget.Holo.ListView</item>
+ </style>
+
+ <style name="AppLight" parent="android:Theme.Holo.Light.DarkActionBar">
+ <item name="android:windowBackground">@drawable/screen_background_selector_light</item>
+ <item name="android:listViewStyle">@android:style/Widget.Holo.Light.ListView</item>
+ </style>
+
+</resources> \ No newline at end of file
diff --git a/res/xml/infos.xml b/res/xml/infos.xml
new file mode 100644
index 0000000..e80f85d
--- /dev/null
+++ b/res/xml/infos.xml
@@ -0,0 +1,16 @@
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ <Preference android:key="key_dsht"/>
+ <PreferenceCategory android:title="Developers">
+ <Preference android:key="key_cesco" android:title="Francesco Rigamonti" android:summary="Java code"/>
+ <Preference android:key="key_sollyx" android:title="Enrico Solazzo" android:summary="Graphics"/>
+ </PreferenceCategory>
+ <PreferenceCategory android:title="Open Source Projects">
+ <Preference android:summary="Some classes and xmls are based on the open source projects listed below."/>
+ <Preference android:key="key_aokp" android:title="AOKP"/>
+ <Preference android:key="key_omni" android:title="OMNI"/>
+ <Preference android:key="key_du" android:title="Dirty Unicorns"/>
+ </PreferenceCategory>
+ <PreferenceCategory android:title="Open Source Libraries">
+ <Preference android:key="key_slidingmenu" android:title="SlidingMenu" android:summary="Author: jfeinstein10"/>
+ </PreferenceCategory>
+ </PreferenceScreen>
diff --git a/res/xml/init_d.xml b/res/xml/init_d.xml
new file mode 100644
index 0000000..e712e84
--- /dev/null
+++ b/res/xml/init_d.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <PreferenceCategory android:title="@string/pt_general" >
+ <CheckBoxPreference
+ android:key="zipalign_apks"
+ android:summary="@string/ps_zipalign_apks"
+ android:title="@string/pt_zipalign_apks" />
+ <CheckBoxPreference
+ android:key="fix_permissions"
+ android:summary="@string/ps_fix_permissions"
+ android:title="@string/pt_fix_permissions" />
+ <CheckBoxPreference
+ android:key="clear_data_cache"
+ android:summary="@string/ps_clear_data_cache"
+ android:title="@string/pt_clear_data_cache" />
+ <CheckBoxPreference
+ android:key="enable_cron"
+ android:summary="@string/ps_enable_cron"
+ android:title="@string/pt_enable_cron" />
+ <CheckBoxPreference
+ android:key="file_system_speedups"
+ android:summary="@string/ps_tweaks"
+ android:title="@string/pt_tweaks" />
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/pc_settings.xml b/res/xml/pc_settings.xml
new file mode 100755
index 0000000..cba2cdd
--- /dev/null
+++ b/res/xml/pc_settings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+Performance Control - An Android CPU Control application
+Copyright (C) 2012 James Roberts
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <CheckBoxPreference
+ android:key="use_light_theme"
+ android:summary="@string/ps_use_light_theme"
+ android:title="@string/pt_use_light_theme" />
+
+ <Preference android:key="version_info" />
+
+</PreferenceScreen>
diff --git a/res/xml/pref_sccreen_uv.xml b/res/xml/pref_sccreen_uv.xml
new file mode 100644
index 0000000..b37fa0f
--- /dev/null
+++ b/res/xml/pref_sccreen_uv.xml
@@ -0,0 +1,8 @@
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <PreferenceCategory
+ android:key="key_uv_category"
+ android:title="@string/uv_title" >
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/pref_screen_cpu.xml b/res/xml/pref_screen_cpu.xml
new file mode 100644
index 0000000..5f66df1
--- /dev/null
+++ b/res/xml/pref_screen_cpu.xml
@@ -0,0 +1,36 @@
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="key_root" >
+
+ <PreferenceCategory android:title="CPU Parameters" >
+ <com.dsht.kerneltweaker.CustomListPreference
+ android:key="key_cpu_max"
+ android:title="@string/cpu_max" />
+ <com.dsht.kerneltweaker.CustomListPreference
+ android:key="key_cpu_min"
+ android:title="@string/cpu_min" />
+ <com.dsht.kerneltweaker.CustomListPreference
+ android:key="key_cpu_governor"
+ android:title="@string/cpu_governor" />
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="key_hotplug_category"
+ android:title="@string/cpu_hotplug" >
+ <com.dsht.kerneltweaker.CustomListPreference
+ android:key="key_cpuquiet"
+ android:summary="@string/cpu_cpuquiet_desc"
+ android:title="@string/cpu_cpuquiet_title" />
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="key_advanced"
+ android:title="@string/cpu_advanced" >
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="key_advanced_governor"
+ android:summary="@string/cpu_adv_gov_desc"
+ android:title="@string/cpu_adv_gov_title" />
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="key_advanced_cpuquiet"
+ android:summary="@string/cpu_adv_quiet_desc"
+ android:title="@string/cpu_adv_quiet_title" />
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/pref_screen_governor.xml b/res/xml/pref_screen_governor.xml
new file mode 100644
index 0000000..67c7069
--- /dev/null
+++ b/res/xml/pref_screen_governor.xml
@@ -0,0 +1,9 @@
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="key_root" >
+
+ <PreferenceCategory
+ android:key="key_gov_category"
+ android:title="@string/gov_title" >
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/pref_screen_gpu.xml b/res/xml/pref_screen_gpu.xml
new file mode 100644
index 0000000..f35809b
--- /dev/null
+++ b/res/xml/pref_screen_gpu.xml
@@ -0,0 +1,13 @@
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="key_root" >
+
+ <PreferenceCategory
+ android:key="key_gpu_category"
+ android:title="@string/gpu_category" >
+ <com.dsht.kerneltweaker.CustomListPreference
+ android:key="key_gpu_frequency"
+ android:summary="@string/gpu_freq_desc"
+ android:title="@string/gpu_freq_title" />
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/pref_screen_kernel.xml b/res/xml/pref_screen_kernel.xml
new file mode 100644
index 0000000..5bee4d7
--- /dev/null
+++ b/res/xml/pref_screen_kernel.xml
@@ -0,0 +1,75 @@
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="key_pref_screen" >
+
+ <PreferenceCategory android:title="I/O Scheduler"
+ android:key="key_sched_cat" >
+ <com.dsht.kerneltweaker.CustomListPreference
+ android:key="key_cpu_sched"
+ android:title="I/O Scheduler" />
+ <com.dsht.kerneltweaker.CustomListPreference
+ android:key="key_cpu_readahead"
+ android:title="Read Ahead size" />
+
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="key_advanced_scheduler"
+ android:summary="Fine tune I/O Scheduler parameters"
+ android:title="Scheduler Tuning" />
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="key_kernel_tweaks"
+ android:title="Kernel Tweaks" >
+ <com.dsht.kerneltweaker.CustomCheckBoxPreference
+ android:key="key_dynfsync_switch"
+ android:summary="Asyncronous Fsync. If enabled gives stock I/O and data integrity, if Disabled you will have more I/O but less data integrity"
+ android:title="Dynamic Fsync" />
+ <com.dsht.kerneltweaker.CustomCheckBoxPreference
+ android:key="key_fsync_switch"
+ android:summary="If enabled gives stock I/O and data integrity, if Disabled you will have more I/O but less data integrity"
+ android:title="Fsync" />
+ <com.dsht.kerneltweaker.CustomCheckBoxPreference
+ android:key="key_fcharge_switch"
+ android:summary="If enabled, device will charge faster when connected through USB"
+ android:title="Fast Charge" />
+ <com.dsht.kerneltweaker.CustomCheckBoxPreference
+ android:key="key_intelliplug_switch"
+ android:summary="In-kernel solution for MPDecision\n(should save battery)"
+ android:title="Intelli-Plug" />
+ <com.dsht.kerneltweaker.CustomCheckBoxPreference
+ android:key="key_ecomode_switch"
+ android:summary="Child of Intelli-plug, will try to use only two cores without loosing performance"
+ android:title="Eco mode" />
+ <com.dsht.kerneltweaker.CustomCheckBoxPreference
+ android:key="key_dt2w_switch"
+ android:summary="If enabled, you will be able to wake your device with a double tap on the screen"
+ android:title="DoubleTap 2 Wake " />
+ <com.dsht.kerneltweaker.CustomCheckBoxPreference
+ android:key="key_s2w_switch"
+ android:summary="If enabled, you will be able to wake or turn off the screen by swiping on navigation bar area"
+ android:title="Sweep 2 Wake " />
+ <com.dsht.kerneltweaker.CustomCheckBoxPreference
+ android:key="key_s2ws_switch"
+ android:summary="If enabled, you will be able to only turn off the screen by swiping on navigation bar"
+ android:title="Sweep 2 Sleep " />
+ <com.dsht.kerneltweaker.CustomCheckBoxPreference
+ android:key="key_f2w_switch"
+ android:summary="If enabled, you will be able to only turn off the screen by swiping on navigation bar"
+ android:title="Flick 2 Wake " />
+ <com.dsht.kerneltweaker.CustomCheckBoxPreference
+ android:key="key_f2s_switch"
+ android:summary="If enabled, you will be able to only turn off the screen by swiping on navigation bar"
+ android:title="Flick 2 Sleep " />
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="key_vibration"
+ android:summary=""
+ android:title="Vibration Intensity" />
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="key_sound_category"
+ android:title="Sound Tweaks" >
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="key_kernel_info"
+ android:summary="These tweaks changes gains of microphone speaker and headsets. Values from -20 to 20"
+ android:title="Information" />
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/pref_screen_minfree.xml b/res/xml/pref_screen_minfree.xml
new file mode 100644
index 0000000..00bc36f
--- /dev/null
+++ b/res/xml/pref_screen_minfree.xml
@@ -0,0 +1,2 @@
+
+ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"></PreferenceScreen>
diff --git a/res/xml/pref_screen_review.xml b/res/xml/pref_screen_review.xml
new file mode 100644
index 0000000..2f72b61
--- /dev/null
+++ b/res/xml/pref_screen_review.xml
@@ -0,0 +1,41 @@
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="key_pref_screen" >
+
+ <PreferenceCategory
+ android:key="cat_cpu"
+ android:title="CPU" >
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="cat_gpu"
+ android:title="GPU" >
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="cat_uv"
+ android:title="UV Table" >
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="cat_kernel"
+ android:title="Kernel " >
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="cat_lmk"
+ android:title="Low memory killer" >
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="cat_gov"
+ android:title="Governor Tuning" >
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="cat_sched"
+ android:title="Scheduler Tuning" >
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="cat_quiet"
+ android:title="Cpuquiet" >
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="cat_vm"
+ android:title="Virtual Machine" >
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/pref_screen_scheduler.xml b/res/xml/pref_screen_scheduler.xml
new file mode 100644
index 0000000..422a8f4
--- /dev/null
+++ b/res/xml/pref_screen_scheduler.xml
@@ -0,0 +1,9 @@
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="key_root" >
+
+ <PreferenceCategory
+ android:key="key_sched_category"
+ android:title="Tweakable Governor Values" >
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/pref_settings.xml b/res/xml/pref_settings.xml
new file mode 100644
index 0000000..08752f9
--- /dev/null
+++ b/res/xml/pref_settings.xml
@@ -0,0 +1,169 @@
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto" >
+
+ <PreferenceCategory android:title="Debug options" >
+ <CheckBoxPreference
+ android:key="key_debug"
+ android:summary="Values are not applied on boot? Enable this option! The app will create a file on the external storage while device boots. Only app related data will be collected."
+ android:title="Enable debugging" />
+
+ <Preference
+ android:key="key_slog"
+ android:summary="Take a look at log file saved on external storage"
+ android:title="Read Log File" />
+ <Preference
+ android:key="key_runlog"
+ android:summary="If you want to test if all works tap here! This option will not reboot your phone.\n\nNOTE: You must have at least one item set on boot!"
+ android:title="Run Boot commands" />
+ </PreferenceCategory>
+ <PreferenceCategory android:title="Theme options" >
+ <CheckBoxPreference
+ android:key="key_theme"
+ android:summary="Use Holo Light with Dark ActionBar Theme"
+ android:title="Use Light theme" />
+ <CheckBoxPreference
+ android:key="key_enable_global"
+ android:summary="Change color for every tab and menu"
+ android:title="Use Global color" />
+
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_global_color"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:summary="Change titles colors"
+ android:title="Titles color"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+
+ <CheckBoxPreference
+ android:key="key_enable_personal"
+ android:summary="Select your preferred color for every tab"
+ android:title="Use Personal colors" />
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="key_personal_category"
+ android:title="Personal colors" >
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_stats"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="CPU stats"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_info"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="CPU info"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_cpu"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="CPU Params"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_gpu"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="GPU Params"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_uv"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="UV Table"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_kernel"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="Kernel"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_lmk"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="Low Memory Killer"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_vm"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="Virtual Machine"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_review"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="Review Items"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_file"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="File Manager"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_backup"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="Backup"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_recovery"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="Recovery"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_prop"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="Build.Prop"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_init"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="Init.d"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ <it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference
+ android:defaultValue="@android:color/white"
+ android:key="key_color_blur"
+ android:negativeButtonText="@null"
+ android:positiveButtonText="@null"
+ android:title="WP Blur"
+ app:cal_itemLayout="@layout/calendar_grid_item_color"
+ app:cal_numColumns="5" />
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/propmodder.xml b/res/xml/propmodder.xml
new file mode 100644
index 0000000..ec477b8
--- /dev/null
+++ b/res/xml/propmodder.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <PreferenceCategory
+ android:title="@string/performance_settings_warning_header">
+
+ <PreferenceScreen
+ android:title="@string/performance_settings_warning_title"
+ android:summary="@string/buildprop_settings_warning" />
+
+ </PreferenceCategory>
+
+ <PreferenceCategory android:key="general_category"
+ android:title="@string/buildprop_title">
+
+ <ListPreference android:key="pref_wifi_scan_interval"
+ android:dialogTitle="@string/pref_wifi_scan_interval_title"
+ android:title="@string/pref_wifi_scan_interval_title"
+ android:summary="@string/pref_wifi_scan_interval_summary"
+ android:entries="@array/entries_wifi_scan"
+ android:entryValues="@array/entries_wifi_scan"
+ android:persistent="true" />
+
+ <ListPreference android:key="pref_sleep"
+ android:dialogTitle="@string/pref_sleep_title"
+ android:title="@string/pref_sleep_title"
+ android:summary="@string/pref_sleep_summary"
+ android:entries="@array/entries_sleep_explain"
+ android:entryValues="@array/entries_sleep"
+ android:persistent="true" />
+
+ <ListPreference android:key="pref_vm_heapsize"
+ android:dialogTitle="@string/pref_vm_heapsize_title"
+ android:title="@string/pref_vm_heapsize_title"
+ android:summary="@string/pref_vm_heapsize_summary"
+ android:entries="@array/entries_vm_heapsize"
+ android:entryValues="@array/entries_vm_heapsize"
+ android:persistent="true" />
+
+ <ListPreference android:key="pref_max_events"
+ android:dialogTitle="@string/pref_max_events_title"
+ android:title="@string/pref_max_events_title"
+ android:summary="@string/pref_max_events_summary"
+ android:entries="@array/entries_max_events"
+ android:entryValues="@array/entries_max_events"
+ android:persistent="true" />
+
+ <ListPreference android:key="pref_ring_delay"
+ android:dialogTitle="@string/pref_ring_delay_title"
+ android:title="@string/pref_ring_delay_title"
+ android:summary="@string/pref_ring_delay_summary"
+ android:entries="@array/entries_ring_delay"
+ android:entryValues="@array/entries_ring_delay"
+ android:persistent="true" />
+
+ <ListPreference android:key="pref_fast_up"
+ android:dialogTitle="@string/pref_fast_up_title"
+ android:title="@string/pref_fast_up_title"
+ android:summary="@string/pref_fast_up_summary"
+ android:entries="@array/entries_fast_up_explain"
+ android:entryValues="@array/entries_fast_up"
+ android:persistent="true" />
+
+ <ListPreference android:key="pref_prox_delay"
+ android:dialogTitle="@string/pref_prox_delay_title"
+ android:title="@string/pref_prox_delay_title"
+ android:summary="@string/pref_prox_delay_summary"
+ android:entries="@array/entries_prox_delay_explain"
+ android:entryValues="@array/entries_prox_delay"
+ android:persistent="true" />
+
+ <EditTextPreference android:key="pref_mod_version"
+ android:dialogTitle="@string/pref_mod_version_title"
+ android:title="@string/pref_mod_version_title"
+ android:summary="@string/pref_mod_version_summary"
+ android:singleLine="true"
+ android:hint="@string/pref_mod_version_default"
+ android:persistent="true" />
+
+ <EditTextPreference android:key="pref_lcd_density"
+ android:dialogTitle="@string/pref_lcd_title"
+ android:title="@string/pref_lcd_title"
+ android:summary="@string/pref_lcd_summary"
+ android:singleLine="true"
+ android:hint="@string/pref_lcd_default"
+ android:persistent="true" />
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/propmodder_switches">
+
+ <CheckBoxPreference android:key="pref_g_speed"
+ android:title="@string/pref_g_speed_title"
+ android:summary="@string/pref_g_speed_summary"
+ android:persistent="true" />
+
+ <CheckBoxPreference android:key="pref_tcp_stack"
+ android:title="@string/pref_tcp_stack_title"
+ android:summary="@string/pref_tcp_stack_summary"
+ android:persistent="true" />
+
+ <CheckBoxPreference android:key="pref_jit"
+ android:title="@string/pref_jit_title"
+ android:summary="@string/pref_jit_summary"
+ android:persistent="true" />
+
+ <CheckBoxPreference android:key="pref_gpu"
+ android:title="@string/pref_gpu_title"
+ android:summary="@string/pref_gpu_summary"
+ android:persistent="true" />
+
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/vm.xml b/res/xml/vm.xml
new file mode 100755
index 0000000..6967d53
--- /dev/null
+++ b/res/xml/vm.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="key_root"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <PreferenceCategory
+ android:key="vm_settings"
+ android:title="@string/prefcat_vm_settings">
+
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="pref_dirty_ratio"
+ android:title="@string/dirty_ratio_title" />
+
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="pref_dirty_background"
+ android:title="@string/dirty_background_title" />
+
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="pref_dirty_expire"
+ android:title="@string/dirty_expire_title" />
+
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="pref_dirty_writeback"
+ android:title="@string/dirty_writeback_title" />
+
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="pref_min_free_kb"
+ android:title="@string/min_free_title" />
+
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="pref_overcommit"
+ android:title="@string/overcommit_title" />
+
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="pref_swappiness"
+ android:title="@string/swappiness_title" />
+
+ <com.dsht.kerneltweaker.CustomPreference
+ android:key="pref_vfs"
+ android:title="@string/vfs_title" />
+ </PreferenceCategory>
+
+</PreferenceScreen>
+
diff --git a/res/xml/vm_settings.xml b/res/xml/vm_settings.xml
new file mode 100755
index 0000000..b1922bf
--- /dev/null
+++ b/res/xml/vm_settings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Performance Control - An Android CPU Control application
+Copyright (C) 2012 James Roberts
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <Preference
+ android:key="pref_dirty_ratio"
+ android:title="@string/dirty_ratio_title" />
+ <Preference
+ android:key="pref_dirty_background"
+ android:title="@string/dirty_background_title" />
+ <Preference
+ android:key="pref_dirty_expire"
+ android:title="@string/dirty_expire_title" />
+ <Preference
+ android:key="pref_dirty_writeback"
+ android:title="@string/dirty_writeback_title" />
+ <Preference
+ android:key="pref_min_free_kb"
+ android:title="@string/min_free_title" />
+ <Preference
+ android:key="pref_overcommit"
+ android:title="@string/overcommit_title" />
+ <Preference
+ android:key="pref_swappiness"
+ android:title="@string/swappiness_title" />
+ <Preference
+ android:key="pref_vfs"
+ android:title="@string/vfs_title" />
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/wallpaper.xml b/res/xml/wallpaper.xml
new file mode 100644
index 0000000..7e98bdc
--- /dev/null
+++ b/res/xml/wallpaper.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wallpaper
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:thumbnail="@drawable/ic_launcher"
+ android:description="@string/gift"/> \ No newline at end of file
diff --git a/src/com/dsht/glossary/ConservativeGlossaryFragment.java b/src/com/dsht/glossary/ConservativeGlossaryFragment.java
new file mode 100644
index 0000000..c90acfc
--- /dev/null
+++ b/src/com/dsht/glossary/ConservativeGlossaryFragment.java
@@ -0,0 +1,41 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class ConservativeGlossaryFragment extends Fragment {
+
+ private Context mContext;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ ListView list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_conservative_titles),
+ getResources().getStringArray(R.array.glo_conservative_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/glossary/CpuGlossaryFragment.java b/src/com/dsht/glossary/CpuGlossaryFragment.java
new file mode 100644
index 0000000..995aac8
--- /dev/null
+++ b/src/com/dsht/glossary/CpuGlossaryFragment.java
@@ -0,0 +1,66 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.CustomArrayAdapter;
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.fragments.CpuPreferenceFragment;
+
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class CpuGlossaryFragment extends Fragment implements OnItemClickListener {
+
+ private Context mContext;
+ private ListView list;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_cpu_titles),
+ getResources().getStringArray(R.array.glo_cpu_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ list.setOnItemClickListener(this);
+ return v;
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> arg0, View parent, int position, long id) {
+ // TODO Auto-generated method stub
+ View v = list.getChildAt(position);
+ TextView tv = (TextView) v.findViewById(android.R.id.text1);
+ if(tv.getText().toString().equalsIgnoreCase("governor")) {
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ GovernorGlossaryFragment glo = new GovernorGlossaryFragment();
+ // This adds the newly created Preference fragment to my main layout, shown below
+ ft.replace(R.id.menu_frame, glo);
+ // By hiding the main fragment, transparency isn't an issue
+ ft.addToBackStack("TAG");
+ ft.commit();
+ }
+
+ }
+
+}
diff --git a/src/com/dsht/glossary/GovernorGlossaryFragment.java b/src/com/dsht/glossary/GovernorGlossaryFragment.java
new file mode 100644
index 0000000..e2937a8
--- /dev/null
+++ b/src/com/dsht/glossary/GovernorGlossaryFragment.java
@@ -0,0 +1,42 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.CustomArrayAdapter;
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class GovernorGlossaryFragment extends Fragment {
+
+ private Context mContext;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ ListView list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_gov_titles),
+ getResources().getStringArray(R.array.glo_gov_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/glossary/GpuGlossaryFragment.java b/src/com/dsht/glossary/GpuGlossaryFragment.java
new file mode 100644
index 0000000..9304fb3
--- /dev/null
+++ b/src/com/dsht/glossary/GpuGlossaryFragment.java
@@ -0,0 +1,41 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class GpuGlossaryFragment extends Fragment {
+
+ private Context mContext;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ ListView list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_gpu_titles),
+ getResources().getStringArray(R.array.glo_gpu_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/glossary/InteractiveGlossaryFragment.java b/src/com/dsht/glossary/InteractiveGlossaryFragment.java
new file mode 100644
index 0000000..36e3ee5
--- /dev/null
+++ b/src/com/dsht/glossary/InteractiveGlossaryFragment.java
@@ -0,0 +1,41 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class InteractiveGlossaryFragment extends Fragment {
+
+ private Context mContext;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ ListView list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_interactive_titles),
+ getResources().getStringArray(R.array.glo_interactive_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/glossary/KernelGlossaryFragment.java b/src/com/dsht/glossary/KernelGlossaryFragment.java
new file mode 100644
index 0000000..7ff416c
--- /dev/null
+++ b/src/com/dsht/glossary/KernelGlossaryFragment.java
@@ -0,0 +1,73 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class KernelGlossaryFragment extends Fragment implements OnItemClickListener {
+
+ private Context mContext;
+ private ListView list;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_kernel_titles),
+ getResources().getStringArray(R.array.glo_kernel_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+ list.setOnItemClickListener(this);
+
+ return v;
+ }
+ @Override
+ public void onItemClick(AdapterView<?> arg0, View parent, int position, long id) {
+ // TODO Auto-generated method stub
+ View v = list.getChildAt(position);
+ if(v != null) {
+ TextView tv = (TextView) v.findViewById(android.R.id.text1);
+ if(tv.getText().toString().equalsIgnoreCase("I/O Scheduler")) {
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ SchedGlossaryFragment glo = new SchedGlossaryFragment();
+ // This adds the newly created Preference fragment to my main layout, shown below
+ ft.replace(R.id.menu_frame, glo);
+ // By hiding the main fragment, transparency isn't an issue
+ ft.addToBackStack("TAG");
+ ft.commit();
+ }
+ if(tv.getText().toString().equalsIgnoreCase("TCP Congestion Control")) {
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ TcpGlossaryFragment glo = new TcpGlossaryFragment();
+ // This adds the newly created Preference fragment to my main layout, shown below
+ ft.replace(R.id.menu_frame, glo);
+ // By hiding the main fragment, transparency isn't an issue
+ ft.addToBackStack("TAG");
+ ft.commit();
+ }
+ }
+ }
+
+}
diff --git a/src/com/dsht/glossary/LmkGlossaryFragment.java b/src/com/dsht/glossary/LmkGlossaryFragment.java
new file mode 100644
index 0000000..b49a602
--- /dev/null
+++ b/src/com/dsht/glossary/LmkGlossaryFragment.java
@@ -0,0 +1,41 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class LmkGlossaryFragment extends Fragment {
+
+ private Context mContext;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ ListView list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_lmk_titles),
+ getResources().getStringArray(R.array.glo_lmk_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/glossary/OndemandGlossaryFragment.java b/src/com/dsht/glossary/OndemandGlossaryFragment.java
new file mode 100644
index 0000000..e16b624
--- /dev/null
+++ b/src/com/dsht/glossary/OndemandGlossaryFragment.java
@@ -0,0 +1,41 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class OndemandGlossaryFragment extends Fragment {
+
+ private Context mContext;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ ListView list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_ondemand_titles),
+ getResources().getStringArray(R.array.glo_ondemand_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/glossary/SchedGlossaryFragment.java b/src/com/dsht/glossary/SchedGlossaryFragment.java
new file mode 100644
index 0000000..a03bb4f
--- /dev/null
+++ b/src/com/dsht/glossary/SchedGlossaryFragment.java
@@ -0,0 +1,41 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class SchedGlossaryFragment extends Fragment {
+
+ private Context mContext;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ ListView list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_sched_titles),
+ getResources().getStringArray(R.array.glo_sched_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/glossary/TcpGlossaryFragment.java b/src/com/dsht/glossary/TcpGlossaryFragment.java
new file mode 100644
index 0000000..5c7d501
--- /dev/null
+++ b/src/com/dsht/glossary/TcpGlossaryFragment.java
@@ -0,0 +1,41 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class TcpGlossaryFragment extends Fragment {
+
+ private Context mContext;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ ListView list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_tcp_titles),
+ getResources().getStringArray(R.array.glo_tcp_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/glossary/UvGlossaryFragment.java b/src/com/dsht/glossary/UvGlossaryFragment.java
new file mode 100644
index 0000000..26850cb
--- /dev/null
+++ b/src/com/dsht/glossary/UvGlossaryFragment.java
@@ -0,0 +1,41 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class UvGlossaryFragment extends Fragment {
+
+ private Context mContext;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ ListView list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_uv_titles),
+ getResources().getStringArray(R.array.glo_uv_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/glossary/VmGlossaryFragment.java b/src/com/dsht/glossary/VmGlossaryFragment.java
new file mode 100644
index 0000000..8003746
--- /dev/null
+++ b/src/com/dsht/glossary/VmGlossaryFragment.java
@@ -0,0 +1,41 @@
+package com.dsht.glossary;
+
+import com.dsht.kerneltweaker.GlossaryArrayAdapter;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class VmGlossaryFragment extends Fragment {
+
+ private Context mContext;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.menu_list, container,false);
+
+ ListView list = (ListView) v.findViewById(R.id.navbarlist);
+ GlossaryArrayAdapter mAdapter = new GlossaryArrayAdapter(
+ mContext,
+ R.layout.list_item,
+ getResources().getStringArray(R.array.glo_vm_titles),
+ getResources().getStringArray(R.array.glo_vm_descs),
+ getResources().getStringArray(R.array.menu_colors)[0]);
+ list.setAdapter(mAdapter);
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/BackupBaseAdapter.java b/src/com/dsht/kerneltweaker/BackupBaseAdapter.java
new file mode 100644
index 0000000..87f5693
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/BackupBaseAdapter.java
@@ -0,0 +1,85 @@
+package com.dsht.kerneltweaker;
+
+import java.io.File;
+import java.util.List;
+
+import com.dsht.settings.SettingsFragment;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class BackupBaseAdapter extends BaseAdapter {
+
+ Context mContext;
+ private List<File> files;
+
+ public BackupBaseAdapter(Context context, List<File> listFiles) {
+ this.mContext = context;
+ this.files = listFiles;
+ }
+
+ @Override
+ public int getCount() {
+ // TODO Auto-generated method stub
+ return files.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ // TODO Auto-generated method stub
+ return files.get(position);
+ }
+
+ @Override
+ public long getItemId(int arg0) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public void update(List<File> files) {
+ this.files.clear();
+ this.files = files;
+ this.notifyDataSetChanged();
+ }
+
+ public void remove(Object object){
+ files.remove(object);
+ }
+
+ public void add(Object object){
+ files.add((File)object);
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public View getView(int position, View v, ViewGroup parent) {
+ // TODO Auto-generated method stub
+ if(v==null) {
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = inflater.inflate(R.layout.backup_list_item, parent, false);
+ }
+
+
+ TextView title = (TextView) v.findViewById(R.id.filename);
+ title.setText(files.get(position).getName());
+ ImageView drag = (ImageView) v.findViewById(R.id.image);
+
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int color = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ title.setTextColor(color);
+ drag.setColorFilter(color);
+ }else if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int color = MainActivity.mPrefs.getInt(SettingsFragment.KEY_BAK, 0);
+ title.setTextColor(color);
+ drag.setColorFilter(color);
+ }
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/CircleAnimatedCheckBox.java b/src/com/dsht/kerneltweaker/CircleAnimatedCheckBox.java
new file mode 100644
index 0000000..9af9d4a
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/CircleAnimatedCheckBox.java
@@ -0,0 +1,147 @@
+package com.dsht.kerneltweaker;
+
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+
+public class CircleAnimatedCheckBox extends CheckBox {
+
+ private static final int PRESSED_COLOR_LIGHTUP = 255 / 25;
+ private static final int PRESSED_RING_ALPHA = 75;
+ private static final int DEFAULT_PRESSED_RING_WIDTH_DIP = 4;
+ private static final int ANIMATION_TIME_ID = android.R.integer.config_shortAnimTime;
+
+ private int centerY;
+ private int centerX;
+ private int outerRadius;
+ private int pressedRingRadius;
+
+ private Paint circlePaint;
+ private Paint focusPaint;
+
+ private float animationProgress;
+
+ private int pressedRingWidth;
+ private int defaultColor = Color.BLACK;
+ private int pressedColor;
+ private ObjectAnimator pressedAnimator;
+
+ public CircleAnimatedCheckBox(Context context) {
+ super(context);
+ init(context, null);
+ }
+
+ public CircleAnimatedCheckBox(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs);
+ }
+
+ public CircleAnimatedCheckBox(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context, attrs);
+ }
+
+ @Override
+ public void setPressed(boolean pressed) {
+ super.setPressed(pressed);
+
+ if (circlePaint != null) {
+ circlePaint.setColor(pressed ? pressedColor : defaultColor);
+ }
+
+ if (pressed) {
+ showPressedRing();
+ } else {
+ hidePressedRing();
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawCircle(centerX, centerY, pressedRingRadius + animationProgress, focusPaint);
+ //canvas.drawCircle(centerX, centerY, outerRadius - pressedRingWidth, circlePaint);
+ super.onDraw(canvas);
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ centerX = w/2;
+ centerY = h/2;
+ outerRadius = Math.min(w, h) / 2;
+ pressedRingRadius = outerRadius - pressedRingWidth - pressedRingWidth / 2;
+ }
+
+ public float getAnimationProgress() {
+ return animationProgress;
+ }
+
+ public void setAnimationProgress(float animationProgress) {
+ this.animationProgress = animationProgress;
+ this.invalidate();
+ }
+
+ public void setColor(int color) {
+ this.defaultColor = color;
+ this.pressedColor = getHighlightColor(color, PRESSED_COLOR_LIGHTUP);
+
+ circlePaint.setColor(defaultColor);
+ circlePaint.setAlpha(PRESSED_RING_ALPHA);
+ focusPaint.setColor(defaultColor);
+ //focusPaint.setAlpha(PRESSED_RING_ALPHA);
+
+ this.invalidate();
+ }
+
+ private void hidePressedRing() {
+ pressedAnimator.setFloatValues(pressedRingWidth, 0f);
+ pressedAnimator.start();
+ }
+
+ private void showPressedRing() {
+ pressedAnimator.setFloatValues(animationProgress, pressedRingWidth);
+ pressedAnimator.start();
+ }
+
+ private void init(Context context, AttributeSet attrs) {
+ //this.setFocusable(true);
+ //this.setScaleType(ScaleType.CENTER_INSIDE);
+ //setClickable(true);
+
+ circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ circlePaint.setStyle(Paint.Style.FILL);
+
+ focusPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ focusPaint.setStyle(Paint.Style.STROKE);
+
+ pressedRingWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_PRESSED_RING_WIDTH_DIP, getResources()
+ .getDisplayMetrics());
+
+ int color = Color.BLACK;
+ if (attrs != null) {
+ final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleAnimatedCheckBox);
+ color = a.getColor(R.styleable.CircleAnimatedCheckBox_cb_color, color);
+ pressedRingWidth = (int) a.getDimension(R.styleable.CircleAnimatedCheckBox_cb_pressed_ring_width, pressedRingWidth);
+ a.recycle();
+ }
+
+ setColor(color);
+
+ focusPaint.setStrokeWidth(pressedRingWidth);
+ final int pressedAnimationTime = getResources().getInteger(ANIMATION_TIME_ID);
+ pressedAnimator = ObjectAnimator.ofFloat(this, "animationProgress", 0f, 0f);
+ pressedAnimator.setDuration(pressedAnimationTime);
+ }
+
+ private int getHighlightColor(int color, int amount) {
+ return Color.argb(Math.min(255, Color.alpha(color)), Math.min(255, Color.red(color) + amount),
+ Math.min(255, Color.green(color) + amount), Math.min(255, Color.blue(color) + amount));
+ }
+}
diff --git a/src/com/dsht/kerneltweaker/CustomArrayAdapter.java b/src/com/dsht/kerneltweaker/CustomArrayAdapter.java
new file mode 100644
index 0000000..dd3518b
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/CustomArrayAdapter.java
@@ -0,0 +1,169 @@
+package com.dsht.kerneltweaker;
+
+import com.dsht.settings.SettingsFragment;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.preference.PreferenceManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class CustomArrayAdapter extends BaseAdapter {
+
+ Context mContext;
+ int layoutResourceId;
+ String[] titles;
+ String[] descs;
+ String[] colors;
+ int[] icons;
+ SharedPreferences mPrefs;
+
+ public CustomArrayAdapter(Context mContext, int layoutResourceId, String[] titles, String[] descs, String[] colors, int[] icons) {
+
+ this.layoutResourceId = layoutResourceId;
+ this.mContext = mContext;
+ this.titles = titles;
+ this.descs = descs;
+ this.colors = colors;
+ this.icons = icons;
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ }
+
+ @Override
+ public int getCount() {
+ // TODO Auto-generated method stub
+ return titles.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ // TODO Auto-generated method stub
+ return position;
+ }
+
+ @Override
+ public long getItemId(int arg0) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 2; //return 2, you have two types that the getView() method will return, normal(0) and for the last row(1)
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return (titles[position].contains("--")) ? 1 : 0; //if we are at the last position then return 1, for any other position return 0
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ if(getItemViewType(position) == 1) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public View getView(int position, View v, ViewGroup parent) {
+ // TODO Auto-generated method stub
+ int type = getItemViewType(position);
+ if(v == null) {
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+ if(type == 0) {
+ v = inflater.inflate(layoutResourceId, parent, false);
+ }else if(type == 1) {
+ v = inflater.inflate(R.layout.menu_header, parent, false);
+ }
+ }
+ if(type == 0) {
+ TextView text1 = (TextView) v.findViewById(android.R.id.text1);
+ ImageView image = (ImageView) v.findViewById(R.id.image);
+ image.setImageDrawable(mContext.getResources().getDrawable(icons[position]));
+ image.setColorFilter(Color.parseColor("#FFFFFF"));
+ if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int color = mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ text1.setTextColor(color);
+ image.setColorFilter(color);
+ }else if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int color = Color.parseColor("#ff0099cc");
+ switch(position) {
+ case 1:
+ color = mPrefs.getInt(SettingsFragment.KEY_STAT, Color.parseColor("#FFFFFF"));
+ break;
+ case 2:
+ color = mPrefs.getInt(SettingsFragment.KEY_INFO, Color.parseColor("#FFFFFF"));
+ break;
+ case 4:
+ color = mPrefs.getInt(SettingsFragment.KEY_CPU, Color.parseColor("#FFFFFF"));
+ break;
+ case 5:
+ color = mPrefs.getInt(SettingsFragment.KEY_GPU, Color.parseColor("#FFFFFF"));
+ break;
+ case 6:
+ color = mPrefs.getInt(SettingsFragment.KEY_UV, Color.parseColor("#FFFFFF"));
+ break;
+ case 8:
+ color = mPrefs.getInt(SettingsFragment.KEY_KERNEL, Color.parseColor("#FFFFFF"));
+ break;
+ case 9:
+ color = mPrefs.getInt(SettingsFragment.KEY_LMK, Color.parseColor("#FFFFFF"));
+ break;
+ case 10:
+ color = mPrefs.getInt(SettingsFragment.KEY_VM, Color.parseColor("#FFFFFF"));
+ break;
+ case 12:
+ color = mPrefs.getInt(SettingsFragment.KEY_REVIEW, Color.parseColor("#FFFFFF"));
+ break;
+ case 14:
+ color = mPrefs.getInt(SettingsFragment.KEY_FILE, Color.parseColor("#FFFFFF"));
+ break;
+ case 15:
+ color = mPrefs.getInt(SettingsFragment.KEY_BAK, Color.parseColor("#FFFFFF"));
+ break;
+ case 16:
+ color = mPrefs.getInt(SettingsFragment.KEY_RECOVERY, Color.parseColor("#FFFFFF"));
+ break;
+ case 18:
+ color = mPrefs.getInt(SettingsFragment.KEY_PROP, Color.parseColor("#FFFFFF"));
+ break;
+ case 19:
+ color = mPrefs.getInt(SettingsFragment.KEY_INIT, Color.parseColor("#FFFFFF"));
+ break;
+ case 20:
+ color = mPrefs.getInt(SettingsFragment.KEY_BLUR, Color.parseColor("#FFFFFF"));
+ break;
+ }
+ text1.setTextColor(color);
+ image.setColorFilter(color);
+ }else {
+ int color = Color.parseColor("#ff0099cc");
+ text1.setTextColor(color);
+ image.setColorFilter(color);
+ }
+ text1.setText(titles[position]);
+ }
+ else if(type == 1) {
+ TextView header = (TextView) v.findViewById(R.id.menu_header);
+ header.setText(titles[position].replaceAll("--", ""));
+ header.setClickable(false);
+ boolean light = mPrefs.getBoolean(SettingsFragment.KEY_THEME, false);
+ if(light){
+ header.setTextColor(Color.BLACK);
+ }else {
+ header.setTextColor(Color.WHITE);
+ }
+ }
+ return v;
+ }
+
+}
+
diff --git a/src/com/dsht/kerneltweaker/CustomBaseAdapter.java b/src/com/dsht/kerneltweaker/CustomBaseAdapter.java
new file mode 100644
index 0000000..1b5c648
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/CustomBaseAdapter.java
@@ -0,0 +1,171 @@
+package com.dsht.kerneltweaker;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.widget.TextView;
+
+public class CustomBaseAdapter extends BaseAdapter {
+
+ Context mContext;
+ String[] values;
+ String[] names;
+ String[] summaries;
+ String color;
+ String FILE;
+ DatabaseHandler db;
+ int newValue;
+ SharedPreferences mPrefs;
+
+ public CustomBaseAdapter(Context mContext, String[] items, String[] names,
+ String[] summaries, String file, String color, DatabaseHandler db) {
+ this.mContext = mContext;
+ this.values = items;
+ this.names = names;
+ this.summaries = summaries;
+ this.FILE = file;
+ this.color = color;
+ this.db = db;
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ }
+
+ @Override
+ public int getCount() {
+ // TODO Auto-generated method stub
+ return values.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ // TODO Auto-generated method stub
+ return values[position];
+ }
+
+ @Override
+ public long getItemId(int position) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public String[] getValues() {
+ return this.values;
+ }
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ // TODO Auto-generated method stub
+ View v = convertView;
+ if(v==null) {
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = inflater.inflate(R.layout.preference_widget_seekbar, parent, false);
+ }
+
+ TextView title = (TextView) v.findViewById(R.id.title);
+ TextView summary = (TextView) v.findViewById(R.id.summary);
+ final TextView currValue = (TextView) v.findViewById(R.id.currvalue);
+ SeekBar seekbar = (SeekBar) v.findViewById(R.id.seekbar);
+ title.setText(names[position]);
+ if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int color = mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ title.setTextColor(color);
+ }else if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_LMK, Color.parseColor("#ff0099cc"));
+ title.setTextColor(col);
+ }
+ else {
+ int color = Color.parseColor( mContext.getResources().getStringArray(R.array.menu_colors)[6]);
+ title.setTextColor(color);
+ }
+ summary.setText(summaries[position]);
+ seekbar.setMax(200);
+ int sbValue = Integer.parseInt(values[position])*4/1024;
+ Log.d("VALUE "+ position, sbValue+"");
+ seekbar.setProgress(sbValue);
+ currValue.setText(sbValue+" Mb");
+ seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
+
+ @Override
+ public void onProgressChanged(SeekBar sb, int arg1, boolean arg2) {
+ // TODO Auto-generated method stub
+ newValue = sb.getProgress();
+ //((sb.getProgress()*1024)/4);
+ //values[position] = new String(String.valueOf(newValue));
+ currValue.setText(sb.getProgress()+" Mb");
+
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar sb) {
+ // TODO Auto-generated method stub
+ int finalValue = ((sb.getProgress()*1024)/4);
+ values[position] = new String(String.valueOf(finalValue));
+ Log.d("STRING", buildString(values));
+ CommandCapture command = new CommandCapture(0,"echo \""+buildString(values)+"\" > "+FILE);
+ try {
+ RootTools.getShell(true).add(command);
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().toString().contains(FILE)) {
+ db.deleteItemByName("'"+FILE+"'");
+ db.addItem(new DataItem("'"+FILE+"'",
+ buildString(values),
+ "LOW MEMORY KILLER",
+ "lmk"));
+ break;
+ }
+ }
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ });
+ return v;
+ }
+
+ public String buildString(String[] values) {
+ String builded = "";
+ for(int i = 0; i<values.length; i++) {
+ if(i!=values.length-1) {
+ builded+=values[i]+",";
+ }else {
+ builded+=values[i];
+ }
+ }
+ return builded;
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/CustomCheckBoxPreference.java b/src/com/dsht/kerneltweaker/CustomCheckBoxPreference.java
new file mode 100644
index 0000000..c5ebdcb
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/CustomCheckBoxPreference.java
@@ -0,0 +1,170 @@
+package com.dsht.kerneltweaker;
+
+import java.util.List;
+
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.os.AsyncTask;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.TextView;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+
+public class CustomCheckBoxPreference extends CheckBoxPreference implements OnCheckedChangeListener {
+
+ String color = "#FFFFFF";
+ TextView title;
+ TextView summary;
+ CheckBox checkbox;
+ CheckBox cb;
+ View separator;
+ CustomCheckBoxPreference pref;
+ DatabaseHandler db = MainActivity.db;
+ List<DataItem> items = db.getAllItems();
+ String category;
+ String value;
+ boolean bootEnabled = true;
+ boolean hide = false;
+ boolean checked = false;
+ SharedPreferences mPrefs;
+
+ public CustomCheckBoxPreference(Context context) {
+ super(context);
+ setLayoutResource(R.layout.preference);
+ }
+
+ public CustomCheckBoxPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setLayoutResource(R.layout.preference);
+ }
+
+ public CustomCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setLayoutResource(R.layout.preference);
+ }
+
+ public void setTitleColor(String color) {
+ this.color = color;
+ }
+
+ public void setCategory(String cat) {
+ this.category = cat;
+ }
+
+ public String getCategory() {
+ return this.category;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+
+ public void setBootEnabled(boolean enabled) {
+ this.bootEnabled = enabled;
+ }
+
+ public boolean isBootEnabled() {
+ return this.bootEnabled;
+ }
+
+ public void setBootChecked(boolean checked) {
+ this.checked = checked;
+ }
+
+ public void hideBoot(boolean hide) {
+ this.hide = hide;
+ }
+
+ public boolean isBootChecked() {
+ return this.checked;
+ }
+
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.mContext);
+ title = (TextView) view.findViewById(android.R.id.title);
+ title.setTextColor(Color.parseColor(color));
+ summary = (TextView) view.findViewById(android.R.id.summary);
+ checkbox = (CheckBox) view.findViewById(android.R.id.checkbox);
+ pref = this;
+
+ title.setTypeface(Typeface.create("sans-serif-condensed", Typeface.NORMAL));
+ summary.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
+ view.setBackground(getContext().getResources().getDrawable(R.drawable.selector));
+
+ cb = (CheckBox) view.findViewById(R.id.cb);
+ cb.setChecked(mPrefs.getBoolean(this.getTitle().toString(), false));
+ cb.setOnCheckedChangeListener(this);
+
+ separator = (View) view.findViewById(R.id.separator);
+ }
+
+ public void updateDb( final Preference p, final String value,final boolean isChecked) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ if(isChecked) {
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+ } else {
+ if(db.getContactsCount() != 0) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+ items = db.getAllItems();
+ }
+ }
+ new LongOperation().execute();
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton arg0, boolean checked) {
+ // TODO Auto-generated method stub
+ updateDb(pref,pref.getValue().toString(), checked);
+ this.checked = checked;
+ SharedPreferences.Editor editor = mPrefs.edit();
+ editor.putBoolean(pref.getTitle().toString(), checked);
+ editor.commit();
+ }
+
+ private void hideBootViews(boolean hide) {
+ if(hide) {
+ separator.setVisibility(View.GONE);
+ cb.setVisibility(View.GONE);
+ }
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/CustomListPreference.java b/src/com/dsht/kerneltweaker/CustomListPreference.java
new file mode 100644
index 0000000..441100d
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/CustomListPreference.java
@@ -0,0 +1,169 @@
+package com.dsht.kerneltweaker;
+
+import java.util.List;
+
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.CheckBox;
+import android.widget.Checkable;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class CustomListPreference extends ListPreference implements OnCheckedChangeListener {
+
+ String color = "#FFFFFF";
+ TextView title;
+ TextView summary;
+ ImageView icon;
+ CheckBox cb;
+ View separator;
+ Context mContext;
+ DatabaseHandler db = MainActivity.db;
+ CustomListPreference pref;
+ List<DataItem> items = db.getAllItems();
+ Drawable mIcon = null;
+ View mView;
+ int mIconResId;
+ String mCurrentValue;
+ boolean checkboxState;
+ String category;
+ boolean exclude = false;
+ boolean hide = false;
+ boolean ischecked = false;
+ SharedPreferences mPrefs;
+
+ public CustomListPreference(Context context, String category) {
+ super(context);
+ this.category = category;
+ setLayoutResource(R.layout.preference);
+ }
+
+ public CustomListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setLayoutResource(R.layout.preference);
+ }
+
+ public void setTitleColor(String color) {
+ this.color = color;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public void excludeFromBoot(boolean exclude) {
+ this.exclude = exclude;
+ }
+
+ public String getCategory() {
+ return this.category;
+ }
+
+ public boolean getCheckBoxState() {
+ return this.checkboxState;
+ }
+
+ public void setBootChecked(boolean checked) {
+ ischecked = checked;
+ }
+
+ public void hideBoot(boolean hide) {
+ this.hide = hide;
+ }
+
+ public boolean isBootChecked() {
+ return ischecked;
+ }
+
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+ pref = this;
+ mView = view;
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.mContext);
+ title = (TextView) view.findViewById(android.R.id.title);
+ title.setTextColor(Color.parseColor(color));
+ summary = (TextView) view.findViewById(android.R.id.summary);
+ icon = (ImageView) view.findViewById(android.R.id.icon);
+ cb = (CheckBox) view.findViewById(R.id.cb);
+
+ cb.setChecked(mPrefs.getBoolean(this.getTitle().toString(), false));
+
+ title.setTypeface(Typeface.create("sans-serif-condensed", Typeface.NORMAL));
+ summary.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
+ view.setBackground(getContext().getResources().getDrawable(R.drawable.selector));
+
+ cb.setOnCheckedChangeListener(this);
+ separator = (View) view.findViewById(R.id.separator);
+ hideBootViews(hide);
+ }
+
+ public void updateDb( final Preference p, final String value,final boolean isChecked) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ if(isChecked) {
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+ } else {
+ if(db.getContactsCount() != 0) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+ items = db.getAllItems();
+ }
+ }
+ new LongOperation().execute();
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton arg0, boolean checked) {
+ // TODO Auto-generated method stub
+ updateDb(pref,pref.getSummary().toString(), checked);
+ this.ischecked = checked;
+ SharedPreferences.Editor editor = mPrefs.edit();
+ editor.putBoolean(pref.getTitle().toString(), checked);
+ editor.commit();
+
+ }
+
+ private void hideBootViews(boolean hide) {
+ if(hide) {
+ separator.setVisibility(View.GONE);
+ cb.setVisibility(View.GONE);
+ }
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/CustomPreference.java b/src/com/dsht/kerneltweaker/CustomPreference.java
new file mode 100644
index 0000000..c7d9665
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/CustomPreference.java
@@ -0,0 +1,220 @@
+package com.dsht.kerneltweaker;
+
+import java.util.List;
+
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.os.AsyncTask;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.TextView;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+
+public class CustomPreference extends Preference implements OnCheckedChangeListener {
+
+ TextView title;
+ TextView summary;
+ CheckBox cb;
+ View separator;
+ String color = "#FFFFFF";
+ String sumColor = null;
+ DatabaseHandler db = MainActivity.db;
+ Preference pref;
+ List<DataItem> items = db.getAllItems();
+ boolean excludeDialog;
+ boolean checkBoxState;
+ boolean areMilliVolts;
+ boolean hide = false;
+ boolean checked = false;
+ String category;
+ Context mContext;
+ int ID = 0;
+ SharedPreferences mPrefs;
+
+ public CustomPreference(Context context, boolean excludeDialog, String category) {
+ super(context);
+ this.mContext = context;
+ this.excludeDialog = excludeDialog;
+ this.category = category;
+ setLayoutResource(R.layout.preference);
+ }
+
+ public CustomPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setLayoutResource(R.layout.preference);
+ }
+
+ public CustomPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setLayoutResource(R.layout.preference);
+ }
+
+ public void setCustomSummaryKeyPlus(int plus) {
+ String currValue = this.getKey();
+ int newValue = Integer.parseInt(currValue) + plus;
+ this.setKey(newValue+"");
+ if(areMilliVolts) {
+ this.setSummary(newValue + " mV");
+ } else {
+ this.setSummary(newValue+"");
+ }
+ }
+
+ public void setCustomSummaryKeyMinus(int minus) {
+ String currValue = this.getKey();
+ int newValue = Integer.parseInt(currValue) - minus;
+ this.setKey(newValue+"");
+ if(areMilliVolts) {
+ this.setSummary(newValue + " mV");
+ } else {
+ this.setSummary(newValue+"");
+ }
+ }
+
+ public void restoreSummaryKey(String summary, String key) {
+ this.setKey(key);
+ if(areMilliVolts) {
+ this.setSummary(summary + " mV");
+ } else {
+ this.setSummary(summary+"");
+ }
+ }
+
+ public void areMilliVolts(boolean areMillivolts) {
+ this.areMilliVolts = areMillivolts;
+ }
+
+ public boolean getCheckBoxState() {
+ return checkBoxState;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public void setTitleColor(String color) {
+ this.color = color;
+ }
+
+ public void setSummaryColor(String color) {
+ this.sumColor = color;
+ }
+
+ public void excludeFromDialog(boolean exclude) {
+ this.excludeDialog = exclude;
+ }
+
+ public void setID(int id) {
+ this.ID = id;
+ }
+
+ public int getID() {
+ return this.ID;
+ }
+
+ public String getCategory() {
+ return this.category;
+ }
+
+ public void setBootChecked(boolean checked) {
+ this.checked = checked;
+ }
+
+ public boolean isBootChecked() {
+ return this.checked;
+ }
+
+ public void hideBoot(boolean hide) {
+ this.hide = hide;
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+ pref = this;
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.mContext);
+ title = (TextView) view.findViewById(android.R.id.title);
+ title.setTextColor(Color.parseColor(color));
+ summary = (TextView) view.findViewById(android.R.id.summary);
+ if(sumColor != null) {
+ summary.setTextColor(Color.parseColor(sumColor));
+ }
+
+ title.setTypeface(Typeface.create("sans-serif-condensed", Typeface.NORMAL));
+ summary.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
+ view.setBackground(getContext().getResources().getDrawable(R.drawable.selector));
+
+ cb = (CheckBox) view.findViewById(R.id.cb);
+ cb.setChecked(mPrefs.getBoolean(this.getTitle().toString(), false));
+ cb.setOnCheckedChangeListener(this);
+
+ separator = (View) view.findViewById(R.id.separator);
+
+ hideBootViews(hide);
+ }
+
+
+ public void updateDb( final Preference p, final String value,final boolean isChecked) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ if(isChecked) {
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+ } else {
+ if(db.getContactsCount() != 0) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+ items = db.getAllItems();
+ }
+ }
+ new LongOperation().execute();
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton arg0, boolean checked) {
+ // TODO Auto-generated method stub
+ updateDb(pref,pref.getSummary().toString(), checked);
+ this.checked = checked;
+ SharedPreferences.Editor editor = mPrefs.edit();
+ editor.putBoolean(pref.getTitle().toString(), checked);
+ editor.commit();
+ }
+
+ private void hideBootViews(boolean hide) {
+ if(hide) {
+ separator.setVisibility(View.GONE);
+ cb.setVisibility(View.GONE);
+ } else {
+ separator.setVisibility(View.VISIBLE);
+ cb.setVisibility(View.VISIBLE);
+ }
+ }
+}
diff --git a/src/com/dsht/kerneltweaker/FileBaseAdapter.java b/src/com/dsht/kerneltweaker/FileBaseAdapter.java
new file mode 100644
index 0000000..458dc77
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/FileBaseAdapter.java
@@ -0,0 +1,75 @@
+package com.dsht.kerneltweaker;
+
+import java.io.File;
+import java.util.Date;
+
+import com.dsht.settings.SettingsFragment;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.text.format.Formatter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class FileBaseAdapter extends BaseAdapter {
+
+ private Context mContext;
+ private File[] files;
+
+ public FileBaseAdapter(Context context, File[] filesList) {
+ this.mContext = context;
+ this.files = filesList;
+ }
+
+ @Override
+ public int getCount() {
+ // TODO Auto-generated method stub
+ return files.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ // TODO Auto-generated method stub
+ return files[position];
+ }
+
+ @Override
+ public long getItemId(int arg0) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View v, ViewGroup parent) {
+ // TODO Auto-generated method stub
+ if (v == null) {
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = inflater.inflate(R.layout.file_list_item, parent, false);
+ }
+ ImageView icon = (ImageView) v.findViewById(R.id.icon);
+ TextView title = (TextView) v.findViewById(R.id.name);
+ TextView info = (TextView) v.findViewById(R.id.info);
+
+ if(files[position].isDirectory()) {
+ icon.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_folder));
+ long lastModified = files[position].lastModified();
+ Date date = new Date(lastModified);
+ info.setText(date+"");
+ } else {
+ icon.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_file));
+ long lastModified = files[position].lastModified();
+ Date date = new Date(lastModified);
+ long size = files[position].length();
+ info.setText(date+" "+Formatter.formatFileSize(mContext, size));
+ }
+ title.setText(files[position].getName());
+
+
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/GlossaryArrayAdapter.java b/src/com/dsht/kerneltweaker/GlossaryArrayAdapter.java
new file mode 100644
index 0000000..462d344
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/GlossaryArrayAdapter.java
@@ -0,0 +1,72 @@
+package com.dsht.kerneltweaker;
+
+import com.dsht.settings.SettingsFragment;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Color;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+public class GlossaryArrayAdapter extends BaseAdapter {
+
+ Context mContext;
+ int layoutResourceId;
+ String[] titles;
+ String[] descs;
+ String color;
+
+ public GlossaryArrayAdapter(Context mContext, int layoutResourceId, String[] titles, String[] descs, String color) {
+
+ this.layoutResourceId = layoutResourceId;
+ this.mContext = mContext;
+ this.titles = titles;
+ this.descs = descs;
+ this.color = color;
+ }
+
+ @Override
+ public int getCount() {
+ // TODO Auto-generated method stub
+ return titles.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ // TODO Auto-generated method stub
+ return position;
+ }
+
+ @Override
+ public long getItemId(int arg0) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View v, ViewGroup parent) {
+ // TODO Auto-generated method stub
+ if(v == null) {
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+ v = inflater.inflate(layoutResourceId, parent, false);
+ }
+ TextView text1 = (TextView) v.findViewById(android.R.id.text1);
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int color = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ text1.setTextColor(color);
+ } else {
+ int col = Color.parseColor(color);
+ text1.setTextColor(col);
+ }
+ text1.setTextAppearance(mContext, android.R.attr.textAppearanceListItemSmall);
+ TextView text2 = (TextView) v.findViewById(android.R.id.text2);
+ text1.setText(titles[position]);
+ text2.setText(descs[position]);
+ return v;
+ }
+
+}
+
diff --git a/src/com/dsht/kerneltweaker/Helpers.java b/src/com/dsht/kerneltweaker/Helpers.java
new file mode 100644
index 0000000..2767d50
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/Helpers.java
@@ -0,0 +1,730 @@
+package com.dsht.kerneltweaker;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Properties;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kernetweaker.cmdprocessor.CMDProcessor;
+import com.dsht.kernetweaker.cmdprocessor.CMDProcessor.CommandResult2;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.AssetManager;
+import android.os.Environment;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+public class Helpers {
+
+ private static final String FREQ_FILE = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies";
+ private static final String GOVERNOR_FILE = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors";
+ static String[] error = {"error while reading frequencies. Please reload this page"};
+
+ public static String[] getFrequencies() {
+ setPermissions(FREQ_FILE);
+ File freqfile = new File(FREQ_FILE);
+ FileInputStream fin1 = null;
+ String s1 = null;
+ try {
+ fin1 = new FileInputStream(freqfile);
+ byte fileContent[] = new byte[(int)freqfile.length()];
+ fin1.read(fileContent);
+ s1 = new String(fileContent);
+ }
+ catch (FileNotFoundException e1) {
+ //System.out.println("File not found" + e1);
+ }
+ catch (IOException ioe1) {
+ //System.out.println("Exception while reading file " + ioe1);
+ }
+ finally {
+ try {
+ if (fin1 != null) {
+ fin1.close();
+ }
+ }
+ catch (IOException ioe1) {
+ //System.out.println("Error while closing stream: " + ioe1);
+ }
+ }
+ if(s1 != null) {
+ String[] frequencies = s1.trim().split(" ");
+ return frequencies;
+ } else {
+ return error;
+ }
+ }
+
+ public static void setPermissions(String file) {
+ if(new File(file).exists()) {
+ CommandCapture command = new CommandCapture(0, "chmod 655 "+file);
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static String binExist(String b) {
+ CommandResult2 cr = null;
+ cr = new CMDProcessor().sh.runWaitFor("busybox which " + b);
+ if (cr.success()) {
+ return cr.stdout;
+ } else {
+ return "NOT_FOUND";
+ }
+ }
+
+ public static boolean writeOneLine(String fname, String value) {
+ if (!new File(fname).exists()) {
+ return false;
+ }
+ try {
+ FileWriter fw = new FileWriter(fname);
+ try {
+ fw.write(value);
+ } finally {
+ fw.close();
+ }
+ } catch (IOException e) {
+ String Error = "Error writing to " + fname + ". Exception: ";
+ Log.e("TAG", Error, e);
+ return false;
+ }
+ return true;
+ }
+
+ public static void runRootCommand(String command) {
+ CommandCapture comm = new CommandCapture(0, command);
+ try {
+ RootTools.getShell(true).add(comm);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public static int getNumOfCpus() {
+ int numOfCpu = 1;
+ setPermissions("/sys/devices/system/cpu/present");
+ String numOfCpus = Helpers.readFileViaShell("/sys/devices/system/cpu/present", false);
+ String[] cpuCount = numOfCpus.trim().split("-");
+ Log.d("NUM", numOfCpus+ "----"+cpuCount.length);
+ if (cpuCount.length > 1) {
+ try {
+ int cpuStart = Integer.parseInt(cpuCount[0]);
+ int cpuEnd = Integer.parseInt(cpuCount[1]);
+
+ numOfCpu = cpuEnd - cpuStart + 1;
+ Log.d("NUM", numOfCpu+"");
+
+ if (numOfCpu < 0) {
+ numOfCpu = 1;
+ Log.d("NUM", "ONE");
+ }
+
+ } catch (NumberFormatException ex) {
+ numOfCpu = 1;
+ Log.d("NUM", "ERROR");
+ }
+ }
+ return numOfCpu;
+ }
+
+ public static boolean fileExists(String fname) {
+ return new File(fname).exists();
+ }
+
+ public static String shExec(StringBuilder s, Context c, Boolean su) {
+ get_assetsScript("run", c, s.toString(), "");
+ if (isSystemApp(c)) {
+ new CMDProcessor().sh.runWaitFor("busybox chmod 750 " + c.getFilesDir() + "/run");
+ } else {
+ new CMDProcessor().su.runWaitFor("busybox chmod 750 " + c.getFilesDir() + "/run");
+ }
+ CommandResult2 cr = null;
+ if (su && !isSystemApp(c))
+ cr = new CMDProcessor().su.runWaitFor(c.getFilesDir() + "/run");
+ else
+ cr = new CMDProcessor().sh.runWaitFor(c.getFilesDir() + "/run");
+ if (cr.success()) {
+ return cr.stdout;
+ } else {
+ Log.d("TAG", "execute: " + cr.stderr);
+ return null;
+ }
+ }
+
+ public static void get_assetsScript(String fn, Context c, String prefix, String postfix) {
+ byte[] buffer;
+ final AssetManager assetManager = c.getAssets();
+ try {
+ InputStream f = assetManager.open(fn);
+ buffer = new byte[f.available()];
+ f.read(buffer);
+ f.close();
+ final String s = new String(buffer);
+ final StringBuilder sb = new StringBuilder(s);
+ if (!postfix.equals("")) {
+ sb.append("\n\n").append(postfix);
+ }
+ if (!prefix.equals("")) {
+ sb.insert(0, prefix + "\n");
+ }
+ sb.insert(0, "#!" + Helpers.binExist("sh") + "\n\n");
+ try {
+ FileOutputStream fos;
+ fos = c.openFileOutput(fn, Context.MODE_PRIVATE);
+ fos.write(sb.toString().getBytes());
+ fos.close();
+
+ } catch (IOException e) {
+ Log.d("TAG", "error write " + fn + " file");
+ e.printStackTrace();
+ }
+
+ } catch (IOException e) {
+ Log.d("TAG", "error read " + fn + " file");
+ e.printStackTrace();
+ }
+ }
+
+ public static void restartPC(final Activity activity) {
+ if (activity == null)
+ return;
+ final int enter_anim = android.R.anim.fade_in;
+ final int exit_anim = android.R.anim.fade_out;
+ activity.overridePendingTransition(enter_anim, exit_anim);
+ activity.finish();
+ activity.overridePendingTransition(enter_anim, exit_anim);
+ activity.startActivity(activity.getIntent());
+ }
+
+
+ public static String[] getFrequenciesNames() {
+ ArrayList<String> names = new ArrayList<String>();
+ setPermissions(FREQ_FILE);
+ File freqfile = new File(FREQ_FILE);
+ FileInputStream fin1 = null;
+ String s1 = null;
+ try {
+ fin1 = new FileInputStream(freqfile);
+ byte fileContent[] = new byte[(int)freqfile.length()];
+ fin1.read(fileContent);
+ s1 = new String(fileContent);
+ }
+ catch (FileNotFoundException e1) {
+ //System.out.println("File not found" + e1);
+ }
+ catch (IOException ioe1) {
+ //System.out.println("Exception while reading file " + ioe1);
+ }
+ finally {
+ try {
+ if (fin1 != null) {
+ fin1.close();
+ }
+ }
+ catch (IOException ioe1) {
+ //System.out.println("Error while closing stream: " + ioe1);
+ }
+ }
+ if(s1 != null) {
+ String[] frequencies = s1.trim().split(" ");
+ for(String s : frequencies) {
+ int conv = (Integer.parseInt(s) / 1000);
+ names.add(conv + " Mhz");
+ }
+ String[] toMhz = new String[names.size()];
+ toMhz = names.toArray(toMhz);
+ return toMhz;
+ }else {
+ return error;
+ }
+ }
+
+
+ public static String[] getFreqToMhz(String file) {
+ ArrayList<String> names = new ArrayList<String>();
+ setPermissions(file);
+ File freqfile = new File(file);
+ FileInputStream fin1 = null;
+ String s1 = null;
+ try {
+ fin1 = new FileInputStream(freqfile);
+ byte fileContent[] = new byte[(int)freqfile.length()];
+ fin1.read(fileContent);
+ s1 = new String(fileContent);
+ }
+ catch (FileNotFoundException e1) {
+ //System.out.println("File not found" + e1);
+ }
+ catch (IOException ioe1) {
+ //System.out.println("Exception while reading file " + ioe1);
+ }
+ finally {
+ try {
+ if (fin1 != null) {
+ fin1.close();
+ }
+ }
+ catch (IOException ioe1) {
+ //System.out.println("Error while closing stream: " + ioe1);
+ }
+ }
+ if(s1 != null) {
+ String[] frequencies = s1.trim().split(" ");
+ for(String s : frequencies) {
+ int conv = (Integer.parseInt(s) / 1000000);
+ names.add(conv + " Mhz");
+ }
+ String[] toMhz = new String[names.size()];
+ toMhz = names.toArray(toMhz);
+ return toMhz;
+ }else {
+ return error;
+ }
+ }
+
+ public static String[] getGovernors() {
+ setPermissions(GOVERNOR_FILE);
+ File govfile = new File(GOVERNOR_FILE);
+ FileInputStream fin = null;
+ String s = null;
+ try {
+ fin = new FileInputStream(govfile);
+ byte fileContent[] = new byte[(int)govfile.length()];
+ fin.read(fileContent);
+ s = new String(fileContent);
+ }
+ catch (FileNotFoundException e) {
+ }
+ catch (IOException ioe) {
+ //System.out.println("Exception while reading file " + ioe);
+ }
+ finally {
+ try {
+ fin.close();
+ }
+ catch (IOException ioe) {
+ //System.out.println("Error while closing stream: " + ioe);
+ }
+ }
+ if(s != null) {
+ String[] governors = s.trim().split(" ");
+ return governors;
+ }else {
+ return error;
+ }
+ }
+
+ public static String[] getUvTableNames() {
+ ArrayList<String> Tokens = new ArrayList<String>();
+
+ try {
+ // Open the file that is the first
+ // command line parameter
+ FileInputStream fstream = null;
+ File f = new File("/sys/devices/system/cpu/cpufreq/vdd_table/vdd_levels");
+ if(f.exists()) {
+ fstream = new FileInputStream("/sys/devices/system/cpu/cpufreq/vdd_table/vdd_levels");
+ }
+ else {
+ File ff = new File("/sys/devices/system/cpu/cpu0/cpufreq/UV_mV_table");
+ if(ff.exists()) {
+ fstream = new FileInputStream("/sys/devices/system/cpu/cpu0/cpufreq/UV_mV_table");
+ }
+ }
+ // Get the object of DataInputStream
+ DataInputStream in = new DataInputStream(fstream);
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ String strLine;
+ // Read File Line By Line
+ while ((strLine = br.readLine()) != null) {
+ strLine = strLine.trim();
+
+ if ((strLine.length()!=0)) {
+ String[] names = strLine.replaceAll(":", "").split("\\s+");
+ Tokens.add(names[0]);
+ }
+
+
+ }
+ // Close the input stream
+ in.close();
+ } catch (Exception e) {// Catch exception if any
+ System.err.println("Error: " + e.getMessage());
+ }
+ String[] names = new String[Tokens.size()-1];
+ names = Tokens.toArray(names);
+ return names;
+ }
+
+ public static String[] getUvValues() {
+ ArrayList<String> value = new ArrayList<String>();
+
+ try {
+ // Open the file that is the first
+ // command line parameter
+ FileInputStream fstream = null;
+ File f = new File("/sys/devices/system/cpu/cpufreq/vdd_table/vdd_levels");
+ if(f.exists()) {
+ fstream = new FileInputStream("/sys/devices/system/cpu/cpufreq/vdd_table/vdd_levels");
+ }
+ else {
+ File ff = new File("/sys/devices/system/cpu/cpu0/cpufreq/UV_mV_table");
+ if(ff.exists()) {
+ fstream = new FileInputStream("/sys/devices/system/cpu/cpu0/cpufreq/UV_mV_table");
+ }
+ }
+ // Get the object of DataInputStream
+ DataInputStream in = new DataInputStream(fstream);
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ String strLine;
+ // Read File Line By Line
+ while ((strLine = br.readLine()) != null) {
+ strLine = strLine.trim();
+
+ if ((strLine.length()!=0)) {
+ String[] val = strLine.split("\\s+");
+ value.add(val[1]);
+ }
+
+
+ }
+ // Close the input stream
+ in.close();
+ } catch (Exception e) {// Catch exception if any
+ System.err.println("Error: " + e.getMessage());
+ }
+ String[] values = new String[value.size()-1];
+ values = value.toArray(values);
+ return values;
+ }
+
+ public static boolean UvTableExists(String file) {
+ File f = new File(file);
+ if(f.exists()) {
+ return true;
+ }
+ return false;
+ }
+
+ public static String[] getAvailableSchedulers() {
+ File iofile = new File("/sys/block/mmcblk0/queue/scheduler");
+ String s ="";
+ FileInputStream fin2 = null;
+ try {
+ fin2 = new FileInputStream(iofile);
+ byte fileContent[] = new byte[(int)iofile.length()];
+ fin2.read(fileContent);
+ s = new String(fileContent).trim().split("\n")[0];
+ }
+ catch (FileNotFoundException e) {
+ //System.out.println("File not found" + e);
+ }
+ catch (IOException ioe) {
+ //System.out.println("Exception while reading file " + ioe);
+ }
+ finally {
+ try {
+ if (fin2 != null) {
+ fin2.close();
+ }
+ }
+ catch (IOException ioe) {
+ //System.out.println("Error while closing stream: " + ioe);
+ }
+ }
+ String[] IOSchedulers = s.replace("[", "").replace("]", "").split(" ");
+ return IOSchedulers;
+ }
+
+ public static String getCurrentScheduler() {
+ File iofile = new File("/sys/block/mmcblk0/queue/scheduler");
+ String s ="";
+ FileInputStream fin2 = null;
+ try {
+ fin2 = new FileInputStream(iofile);
+ byte fileContent[] = new byte[(int)iofile.length()];
+ fin2.read(fileContent);
+ s = new String(fileContent).trim().split("\n")[0];
+ }
+ catch (FileNotFoundException e) {
+ //System.out.println("File not found" + e);
+ }
+ catch (IOException ioe) {
+ //System.out.println("Exception while reading file " + ioe);
+ }
+ finally {
+ try {
+ if (fin2 != null) {
+ fin2.close();
+ }
+ }
+ catch (IOException ioe) {
+ //System.out.println("Error while closing stream: " + ioe);
+ }
+ }
+ int bropen = s.indexOf("[");
+ int brclose = s.lastIndexOf("]");
+ return s.substring(bropen + 1, brclose);
+ }
+
+ public static String getCurrentGovernor() {
+ setPermissions("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
+ File govfile = new File("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
+ FileInputStream fin = null;
+ String s = null;
+ try {
+ fin = new FileInputStream(govfile);
+ byte fileContent[] = new byte[(int)govfile.length()];
+ fin.read(fileContent);
+ s = new String(fileContent);
+ }
+ catch (FileNotFoundException e) {
+ }
+ catch (IOException ioe) {
+ //System.out.println("Exception while reading file " + ioe);
+ }
+ finally {
+ try {
+ fin.close();
+ }
+ catch (IOException ioe) {
+ //System.out.println("Error while closing stream: " + ioe);
+ }
+ }
+
+ return s.trim();
+ }
+
+ public static String getFileContent( File file) {
+ setPermissions(file.getAbsolutePath());
+ FileInputStream fin = null;
+ //Log.d("FILE", file.getAbsolutePath());
+ String s = null;
+ try {
+ fin = new FileInputStream(file);
+ byte fileContent[] = new byte[(int)file.length()];
+ fin.read(fileContent);
+ s = new String(fileContent);
+ }
+ catch (FileNotFoundException e) {
+ }
+ catch (IOException ioe) {
+ //System.out.println("Exception while reading file " + ioe);
+ }
+ finally {
+ try {
+ if(fin != null) {
+ fin.close();
+ }
+ }
+ catch (IOException ioe) {
+ //System.out.println("Error while closing stream: " + ioe);
+ }
+ }
+ if(s == null) {
+ s=" ";
+ } else {
+ s = s.split("\n")[0];
+ }
+ return s;
+ }
+
+ public static void waitForMillis(final int millis, Context context) {
+ Thread thread= new Thread(){
+ @Override
+ public void run(){
+ try {
+ synchronized(this){
+ wait(millis);
+ }
+ }
+ catch(InterruptedException ex){
+ }
+
+ // TODO
+ }
+ };
+
+ thread.start();
+ }
+
+
+ public static String readOneLine(String fname) {
+ BufferedReader br = null;
+ String line = null;
+ try {
+ br = new BufferedReader(new FileReader(fname), 1024);
+ line = br.readLine();
+ } catch (FileNotFoundException ignored) {
+ Log.d("TAG", "File was not found! trying via shell...");
+ return readFileViaShell(fname, true).trim().split("\\W+")[0];
+ } catch (IOException e) {
+ Log.d("TAG", "IOException while reading system file", e);
+ return readFileViaShell(fname, true).trim().split("\\W+")[0];
+ } finally {
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException ignored) {
+ // failed to close reader
+ }
+ }
+ }
+ return line.trim().split("\\W+")[0];
+ }
+
+ public static String readFileViaShell(String filePath, boolean useSu) {
+ String command = new String("cat " + filePath);
+ return useSu ? CMDProcessor.runSuCommand(command).getStdout()
+ : CMDProcessor.runShellCommand(command).getStdout();
+ }
+
+ public static String readCommandStrdOut(String command, boolean useSu) {
+ return useSu ? CMDProcessor.runSuCommand(command).getStdout()
+ : CMDProcessor.runShellCommand(command).getStdout();
+ }
+
+ public static File[] listFilesViaShell(String dirPath, boolean useSu) {
+ String command = new String("ls" + dirPath);
+ String content = useSu ? CMDProcessor.runSuCommand(command).getStdout()
+ : CMDProcessor.runShellCommand(command).getStdout();
+ String[] folders = content.trim().split("\n");
+ File[] list = new File[folders.length];
+ for(int i = 0; i<folders.length; i++) {
+ list[i] = new File(dirPath+"/"+folders[i]);
+ }
+
+ return list;
+ }
+
+ public static boolean getMount(String mount) {
+ String[] mounts = getMounts("/system");
+ if (mounts != null && mounts.length >= 3) {
+ String device = mounts[0];
+ String path = mounts[1];
+ String point = mounts[2];
+ String preferredMountCmd = new String("mount -o " + mount + ",remount -t " + point + ' ' + device + ' ' + path);
+ if (CMDProcessor.runSuCommand(preferredMountCmd).success()) {
+ return true;
+ }
+ }
+ String fallbackMountCmd = new String("busybox mount -o remount," + mount + " /system");
+ return CMDProcessor.runSuCommand(fallbackMountCmd).success();
+ }
+
+ public static String[] getMounts(CharSequence path) {
+ BufferedReader bufferedReader = null;
+ try {
+ bufferedReader = new BufferedReader(new FileReader("/proc/mounts"), 256);
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ if (line.contains(path)) {
+ return line.split(" ");
+ }
+ }
+ } catch (FileNotFoundException ignored) {
+ Log.d("TAG", "/proc/mounts does not exist");
+ } catch (IOException ignored) {
+ Log.d("TAG", "Error reading /proc/mounts");
+ } finally {
+ if (bufferedReader != null) {
+ try {
+ bufferedReader.close();
+ } catch (IOException ignored) {
+ // ignored
+ }
+ }
+ }
+ return null;
+ }
+
+ public static boolean isSystemApp(Context c) {
+ boolean mIsSystemApp;
+ return mIsSystemApp = c.getResources().getBoolean(R.bool.config_isSystemApp);
+ }
+
+ /*
+ * Find value of build.prop item (/system can be ro or rw)
+ *
+ * @param prop /system/build.prop property name to find value of
+ *
+ * @returns String value of @param:prop
+ */
+ public static String findBuildPropValueOf(String prop) {
+ String mBuildPath = "/system/build.prop";
+ String DISABLE = "disable";
+ String value = null;
+ try {
+ //create properties construct and load build.prop
+ Properties mProps = new Properties();
+ mProps.load(new FileInputStream(mBuildPath));
+ //get the property
+ value = mProps.getProperty(prop, DISABLE);
+ Log.d("TAG", String.format("Helpers:findBuildPropValueOf found {%s} with the value (%s)", prop, value));
+ } catch (IOException ioe) {
+ Log.d("TAG", "failed to load input stream");
+ } catch (NullPointerException npe) {
+ //swallowed thrown by ill formatted requests
+ }
+
+ if (value != null) {
+ return value;
+ } else {
+ return DISABLE;
+ }
+ }
+
+ public static void debugger(Context mContext,String message ) {
+ SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ String FILE_NAME = "KernelTweaker_log.txt";
+ if(mPrefs.getBoolean(SettingsFragment.KEY_DEBUG, false)){
+ String command = new String("echo \""+ message + "\" >> " + Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+FILE_NAME);
+ CMDProcessor.runShellCommand(command);
+ }
+ }
+
+ public static void checkApply(Context mContext, String name, String curValue, String filepath) {
+ String filevalue = readFileViaShell(filepath, true);
+ if(!filevalue.contains(curValue)) {
+ debugger(mContext, "\n-------------\n"+name + " " + "value: "+ curValue + " Not Applied --- File value is: "+ filevalue+"\n-------------\n");
+ }else {
+ debugger(mContext, "\n-------------\n"+name + " " + "value: "+ curValue + " Applied"+"\n-------------\n");
+ }
+ }
+
+}
+
diff --git a/src/com/dsht/kerneltweaker/ListViewMultiChoiceModeListener.java b/src/com/dsht/kerneltweaker/ListViewMultiChoiceModeListener.java
new file mode 100644
index 0000000..0302d7c
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/ListViewMultiChoiceModeListener.java
@@ -0,0 +1,344 @@
+package com.dsht.kerneltweaker;
+
+import java.util.List;
+
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.kerneltweaker.database.VddDatabaseHandler;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Build;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+import android.util.SparseBooleanArray;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.AbsListView;
+import android.widget.ListView;
+
+@TargetApi(Build.VERSION_CODES.HONEYCOMB)
+
+public class ListViewMultiChoiceModeListener implements
+AbsListView.MultiChoiceModeListener {
+ Activity host;
+ ActionMode activeMode;
+ ListView lv;
+ Context mContext;
+ PreferenceScreen mRoot;
+ PreferenceCategory mCpu;
+ PreferenceCategory mGpu;
+ PreferenceCategory mUv;
+ PreferenceCategory mKernel;
+ PreferenceCategory mLmk;
+ PreferenceCategory mGov;
+ PreferenceCategory mSched;
+ PreferenceCategory mQuiet;
+ PreferenceCategory mVm;
+ DatabaseHandler db;
+ VddDatabaseHandler VddDb;
+ boolean delete;
+ MenuItem mDelete;
+ MenuItem mAdd;
+
+ private static final String cpuCat = "cpu";
+ private static final String gpuCat = "gpu";
+ private static final String uvCat ="uv";
+ private static final String kernelCat = "kernel";
+ private static final String LmkCat = "lmk";
+ private static final String GovCat = "governor";
+ private static final String SchedCat ="scheduler";
+ private static final String QuietCat ="cpuquiet";
+ private static final String vmCat ="vm";
+
+ public ListViewMultiChoiceModeListener(Context mContext,Activity host, ListView lv,
+ PreferenceScreen mRoot,
+ PreferenceCategory mCpu,
+ PreferenceCategory mGpu,
+ PreferenceCategory mUv,
+ PreferenceCategory mKernel,
+ PreferenceCategory mLmk,
+ PreferenceCategory mGov,
+ PreferenceCategory mSched,
+ PreferenceCategory mQuiet,
+ PreferenceCategory mVm,
+ DatabaseHandler db,
+ VddDatabaseHandler vddDb,
+ boolean delete) {
+ this.host=host;
+ this.lv=lv;
+ this.mRoot = mRoot;
+ this.mCpu = mCpu;
+ this.mGpu = mGpu;
+ this.mUv = mUv;
+ this.mKernel = mKernel;
+ this.mLmk = mLmk;
+ this.db = db;
+ this.VddDb = vddDb;
+ this.delete = delete;
+ this.mGov = mGov;
+ this.mSched = mSched;
+ this.mQuiet = mQuiet;
+ this.mVm = mVm;
+ this.mContext = mContext;
+
+ }
+
+ public ListViewMultiChoiceModeListener(Context mContext,
+ Activity host, ListView lv,
+ PreferenceScreen mRoot, boolean delete,
+ DatabaseHandler db, VddDatabaseHandler VddDb) {
+ this.mContext = mContext;
+ this.host = host;
+ this.lv = lv;
+ this.mRoot = mRoot;
+ this.delete = delete;
+ this.db = db;
+ this.VddDb = VddDb;
+ }
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ MenuInflater inflater=host.getMenuInflater();
+ inflater.inflate(R.menu.main, menu);
+ mDelete = (MenuItem) menu.findItem(R.id.action_delete);
+ mAdd = (MenuItem) menu.findItem(R.id.action_add);
+
+ if(delete) {
+ mode.setTitle("Delete items");
+ mAdd.setVisible(false);
+ }else {
+ mDelete.setVisible(false);
+ mode.setTitle("Add on boot");
+ }
+ mode.setSubtitle("1 Item Selected");
+ activeMode=mode;
+
+ return(true);
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return(false);
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+
+ updateSubtitle(activeMode);
+
+ switch(item.getItemId()) {
+ case R.id.action_delete:
+ SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ SharedPreferences.Editor editor = mPrefs.edit();
+ int len = lv.getCount();
+ SparseBooleanArray checked = lv.getCheckedItemPositions();
+ for (int i = 0; i < len; i++)
+ if (checked.get(i)) {
+ Object o = mRoot.getRootAdapter().getItem(i);
+ if(o instanceof PreferenceCategory) {
+ //do nothing
+ }else if( o instanceof CustomPreference) {
+
+ CustomPreference pref = (CustomPreference) o;
+ editor.remove(pref.getTitle().toString());
+
+ if(pref.getCategory().equals(cpuCat)) {
+ mCpu.removePreference(pref);
+ }
+ if(pref.getCategory().equals(gpuCat)) {
+ mGpu.removePreference(pref);
+ }
+ if(pref.getCategory().equals(uvCat)) {
+ mUv.removePreference(pref);
+ }
+ if(pref.getCategory().equals(kernelCat)) {
+ mKernel.removePreference(pref);
+ }
+ if(pref.getCategory().equals(LmkCat)) {
+ mLmk.removePreference(pref);
+ }
+ if(pref.getCategory().equals(GovCat)) {
+ mGov.removePreference(pref);
+ }
+ if(pref.getCategory().equals(SchedCat)) {
+ mSched.removePreference(pref);
+ }
+ if(pref.getCategory().equals(QuietCat)) {
+ mQuiet.removePreference(pref);
+ }
+ if(pref.getCategory().equals(vmCat)) {
+ mVm.removePreference(pref);
+ }
+ if(pref.getTitle().toString().contains("VDD")) {
+ VddDb.deleteAllItems();
+ }else {
+ String name = pref.getKey();
+ db.deleteItemByName("'"+name+"'");
+ }
+ checkEmpty();
+ }
+ else if( o instanceof CustomListPreference) {
+
+ CustomListPreference pref = (CustomListPreference) o;
+ editor.remove(pref.getTitle().toString());
+ if(pref.getTitle().toString().contains("VDD")) {
+ VddDb.deleteAllItems();
+ }else {
+ String name = pref.getKey();
+ db.deleteItemByName("'"+name+"'");
+ }
+ if(pref.getCategory().equals(cpuCat)) {
+ mCpu.removePreference(pref);
+ }
+ if(pref.getCategory().equals(gpuCat)) {
+ mGpu.removePreference(pref);
+ }
+ if(pref.getCategory().equals(uvCat)) {
+ mUv.removePreference(pref);
+ }
+ if(pref.getCategory().equals(kernelCat)) {
+ mKernel.removePreference(pref);
+ }
+ if(pref.getCategory().equals(LmkCat)) {
+ mLmk.removePreference(pref);
+ }
+ if(pref.getCategory().equals(GovCat)) {
+ mGov.removePreference(pref);
+ }
+ if(pref.getCategory().equals(SchedCat)) {
+ mSched.removePreference(pref);
+ }
+ if(pref.getCategory().equals(QuietCat)) {
+ mQuiet.removePreference(pref);
+ }
+ if(pref.getCategory().equals(vmCat)) {
+ mVm.removePreference(pref);
+ }
+ if(pref.getTitle().toString().contains("VDD")) {
+ VddDb.deleteAllItems();
+ }
+
+ checkEmpty();
+ }
+ editor.commit();
+ }
+ if(mRoot.getPreferenceCount() == 0) {
+ addEmptyView();
+ }
+ break;
+ case R.id.action_add:
+ int length = lv.getCount();
+ SparseBooleanArray check = lv.getCheckedItemPositions();
+ List<DataItem> items = db.getAllItems();
+ for (int i = 0; i < length; i++) {
+ if (check.get(i)) {
+ Object o = mRoot.getRootAdapter().getItem(i);
+ if( o instanceof CustomPreference) {
+ CustomPreference p = (CustomPreference)o;
+ if(p.getTitle().toString().contains("Information")) {
+
+ }else if(p.getTitle().toString().contains("EMPTY")) {
+
+ }else if(!p.getTitle().toString().contains("Tuning")) {
+ for(DataItem it : items) {
+ if(it.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", p.getSummary().toString(), p.getTitle().toString(), p.getCategory()));
+ }
+ }
+ if( o instanceof CustomListPreference) {
+ CustomListPreference p = (CustomListPreference)o;
+ for(DataItem it : items) {
+ if(it.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", p.getSummary().toString(), p.getTitle().toString(), p.getCategory()));
+ }
+ if(o instanceof CustomCheckBoxPreference) {
+ CustomCheckBoxPreference p = (CustomCheckBoxPreference)o;
+ for(DataItem it : items) {
+ if(it.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", p.getValue(), p.getTitle().toString(), p.getCategory()));
+ }
+ }
+ }
+ break;
+ }
+ mode.finish();
+ return true;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ activeMode=null;
+ }
+
+ @Override
+ public void onItemCheckedStateChanged(ActionMode mode, int position,
+ long id, boolean checked) {
+ updateSubtitle(mode);
+
+ }
+
+ private void updateSubtitle(ActionMode mode) {
+ mode.setSubtitle( lv.getCheckedItemCount() + " Items selected");
+ }
+
+ public void addEmptyView() {
+ mRoot.removeAll();
+ CustomPreference pref = new CustomPreference(host, true, "");
+ pref.setTitle(mContext.getResources().getString(R.string.emp_title));
+ pref.setSummary(mContext.getResources().getString(R.string.emp_desc));
+ pref.hideBoot(true);
+ String color = host.getResources().getStringArray(R.array.menu_colors)[6];
+ pref.setTitleColor(color);
+ pref.setSummaryColor(color);
+ mRoot.addPreference(pref);
+ }
+
+
+
+
+ private void checkEmpty() {
+
+ if(mCpu.getPreferenceCount() == 0) {
+ mRoot.removePreference(mCpu);
+ }
+ if(mGpu.getPreferenceCount() == 0) {
+ mRoot.removePreference(mGpu);
+ }
+ if(mUv.getPreferenceCount() == 0) {
+ mRoot.removePreference(mUv);
+ }
+ if(mKernel.getPreferenceCount() == 0) {
+ mRoot.removePreference(mKernel);
+ }
+ if(mLmk.getPreferenceCount() == 0) {
+ mRoot.removePreference(mLmk);
+ }
+ if(mGov.getPreferenceCount() == 0) {
+ mRoot.removePreference(mGov);
+ }
+ if(mQuiet.getPreferenceCount() == 0) {
+ mRoot.removePreference(mQuiet);
+ }
+ if(mSched.getPreferenceCount() == 0) {
+ mRoot.removePreference(mSched);
+ }
+ if(mVm.getPreferenceCount() == 0) {
+ mRoot.removePreference(mVm);
+ }
+ }
+}
diff --git a/src/com/dsht/kerneltweaker/MainActivity.java b/src/com/dsht/kerneltweaker/MainActivity.java
new file mode 100644
index 0000000..735f206
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/MainActivity.java
@@ -0,0 +1,456 @@
+package com.dsht.kerneltweaker;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.glossary.CpuGlossaryFragment;
+import com.dsht.glossary.GpuGlossaryFragment;
+import com.dsht.glossary.KernelGlossaryFragment;
+import com.dsht.glossary.LmkGlossaryFragment;
+import com.dsht.glossary.UvGlossaryFragment;
+import com.dsht.glossary.VmGlossaryFragment;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.kerneltweaker.database.VddDatabaseHandler;
+import com.dsht.kerneltweaker.fragments.BackupFragment;
+import com.dsht.kerneltweaker.fragments.CpuPreferenceFragment;
+import com.dsht.kerneltweaker.fragments.CustomRecoveryCommandFragment;
+import com.dsht.kerneltweaker.fragments.FileManagerFragment;
+import com.dsht.kerneltweaker.fragments.GpuPreferenceFragment;
+import com.dsht.kerneltweaker.fragments.InitD;
+import com.dsht.kerneltweaker.fragments.KernelPreferenceFragment;
+import com.dsht.kerneltweaker.fragments.LowMemoryKillerFragment;
+import com.dsht.kerneltweaker.fragments.PropModder;
+import com.dsht.kerneltweaker.fragments.ReviewBootPreferenceFragment;
+import com.dsht.kerneltweaker.fragments.UvPreferenceFragment;
+import com.dsht.kerneltweaker.fragments.WallpaperEffectsFragment;
+import com.dsht.open.CPUInfo;
+import com.dsht.open.TimeInState;
+import com.dsht.open.VM;
+import com.dsht.settings.SettingsFragment;
+import com.dsht.settings.infos;
+import com.google.analytics.tracking.android.EasyTracker;
+import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.support.v4.app.FragmentActivity;
+import android.text.Html;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.FrameLayout;
+import android.widget.ListView;
+
+public class MainActivity extends FragmentActivity implements OnItemClickListener {
+
+ private static FrameLayout mContainer;
+ public static SlidingMenu menu;
+ private String[] colors;
+ public static DatabaseHandler db;
+ public static VddDatabaseHandler vddDb;
+ public static Context mContext;
+ public static SharedPreferences mPrefs;
+ public static ListView menulist;
+ private static FrameLayout mGlossaryContainer;
+ public static CustomArrayAdapter mAdapter;
+
+ public static final int[] icons = {
+ 0,
+ R.drawable.meter,
+ R.drawable.bar_chart,
+ 0,
+ R.drawable.flash_on,
+ R.drawable.lcd,
+ R.drawable.plus_minus,
+ 0,
+ R.drawable.beaker,
+ R.drawable.life_guard,
+ R.drawable.settings_two,
+ 0,
+ R.drawable.heart,
+ 0,
+ R.drawable.doc_zip,
+ R.drawable.backup,
+ R.drawable.radiation,
+ 0,
+ R.drawable.doc,
+ R.drawable.magic_wand,
+ R.drawable.eye,
+ 0,
+ R.drawable.settings_one,
+ R.drawable.info
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main_container);
+ RootTools.debugMode = false;
+
+ boolean access = RootTools.isAccessGiven();
+ boolean busybox = RootTools.isBusyboxAvailable();
+ if(!access) {
+ showRootWarning();
+ }
+ if(!busybox) {
+ showBusyBoxWarning();
+ }
+
+ mContainer = (FrameLayout) findViewById(R.id.activity_container);
+ mContext = this;
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+ getActionBar().setHomeButtonEnabled(true);
+ View v = this.getLayoutInflater().inflate(R.layout.menu_list, null, false);
+ menulist = (ListView) v.findViewById(R.id.navbarlist);
+ db = new DatabaseHandler(this);
+ vddDb = new VddDatabaseHandler(this);
+
+ menu = new SlidingMenu(this);
+ menu.setMode(SlidingMenu.LEFT_RIGHT);
+ menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
+ menu.setShadowWidthRes(R.dimen.shadow_width);
+ menu.setShadowDrawable(R.drawable.shadow);
+ //menu.setBehindOffsetRes(R.dimen.slidingmenu_offset);
+ menu.setBehindWidthRes(R.dimen.slidingmenu_offset);
+ menu.setFadeDegree(0.35f);
+ menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
+ menu.setMenu(v);
+ View vv = this.getLayoutInflater().inflate(R.layout.menu_glossary, null, false);
+ mGlossaryContainer = (FrameLayout) vv.findViewById(R.id.menu_frame);
+ menu.setSecondaryMenu(vv);
+ menu.setSecondaryShadowDrawable(R.drawable.shadow_right);
+
+ mAdapter = new CustomArrayAdapter(
+ this,
+ R.layout.menu_main_list_item,
+ getResources().getStringArray(R.array.menu_entries),
+ getResources().getStringArray(R.array.menu_descs),
+ getResources().getStringArray(R.array.menu_colors),
+ icons);
+ menulist.setAdapter(mAdapter);
+ menulist.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ menulist.setOnItemClickListener(this);
+
+ colors = getResources().getStringArray(R.array.menu_colors);
+
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ Fragment prefs = new TimeInState();
+ CpuGlossaryFragment glo = new CpuGlossaryFragment();
+ // This adds the newly created Preference fragment to my main layout, shown below
+ ft.replace(R.id.activity_container,prefs);
+ ft.replace(R.id.menu_frame, glo);
+ // By hiding the main fragment, transparency isn't an issue
+ //ft.addToBackStack(null);
+ ft.commit();
+
+
+ setAppTheme();
+ mountPartitions();
+ copyHelpers();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.menu_main_container, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case android.R.id.home:
+ menu.toggle(true);
+ break;
+ case R.id.help:
+ if(menu.isSecondaryMenuShowing()) {
+ menu.toggle(true);
+ } else {
+ menu.showSecondaryMenu(true);
+ }
+ break;
+ }
+ return false;
+ }
+
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ EasyTracker.getInstance(this).activityStart(this); // Add this method.
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ EasyTracker.getInstance(this).activityStop(this); // Add this method.
+ }
+
+
+ @Override
+ public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
+ // TODO Auto-generated method stub
+
+ Fragment f = null;
+ Fragment glo = null;
+ switch(arg2) {
+ case 1:
+ f = new TimeInState();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 2:
+ f = new CPUInfo();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 4:
+ f = new CpuPreferenceFragment();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 5:
+ f = new GpuPreferenceFragment();
+ glo = new GpuGlossaryFragment();
+ break;
+ case 6:
+ f = new UvPreferenceFragment();
+ glo = new UvGlossaryFragment();
+ break;
+ case 8:
+ f = new KernelPreferenceFragment();
+ glo = new KernelGlossaryFragment();
+ break;
+ case 9:
+ f = new LowMemoryKillerFragment();
+ glo = new LmkGlossaryFragment();
+ break;
+ case 10:
+ f = new VM();
+ glo = new VmGlossaryFragment();
+ break;
+ case 12:
+ f = new ReviewBootPreferenceFragment();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 14:
+ f = new FileManagerFragment();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 15:
+ f = new BackupFragment();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 16:
+ f = new CustomRecoveryCommandFragment();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 18:
+ f = new PropModder();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 19:
+ f = new InitD();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 20:
+ f = new WallpaperEffectsFragment();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 22:
+ f = new SettingsFragment();
+ glo = new CpuGlossaryFragment();
+ break;
+ case 23:
+ f = new infos();
+ glo = new CpuGlossaryFragment();
+ //showCredits();
+ break;
+
+ }
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ // This adds the newly created Preference fragment to my main layout, shown below
+ ft.replace(R.id.activity_container,f);
+ ft.replace(R.id.menu_frame, glo);
+ // By hiding the main fragment, transparency isn't an issue
+ ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+ ft.addToBackStack("TAG");
+ ft.commit();
+ //menu.toggle(true);
+ }
+
+ @Override
+ public void onBackPressed(){
+ FragmentManager fm = getFragmentManager();
+ if (fm.getBackStackEntryCount() > 0) {
+ Log.i("MainActivity", "popping backstack");
+ fm.popBackStack();
+
+ } else {
+ Log.i("MainActivity", "nothing on backstack, calling super");
+ super.onBackPressed();
+ }
+ }
+
+
+ public void showRootWarning() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(getResources().getString(R.string.rc_title));
+ builder.setMessage(getResources().getString(R.string.rc_desc));
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ dialog.cancel();
+ MainActivity.this.finish();
+ }
+ });
+ builder.create().show();
+ }
+
+ public void showBusyBoxWarning() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(getResources().getString(R.string.bb_title));
+ builder.setMessage(getResources().getString(R.string.bb_desc));
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ dialog.cancel();
+ MainActivity.this.finish();
+ }
+ });
+ builder.create().show();
+ }
+
+ public void showCredits() {
+ PackageInfo pInfo = null;
+ try {
+ pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
+ } catch (NameNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ String version = pInfo.versionName;
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(getResources().getString(R.string.app_name) + " V: "+version);
+ builder.setIcon(R.drawable.ic_launcher);
+ builder.setMessage(Html.fromHtml("<p>"+
+ "Some <strong>KernelTweaker</strong> classes and xmls are based on OpenSource projects:</p>"+
+ "<br><p><strong>AOKP</strong> :&nbsp;<a href=\"https://github.com/AOKP\">https://github.com/AOKP</a><br />"+
+ "<strong>OMNI</strong>:&nbsp;<a href=\"https://github.com/omnirom/\">https://github.com/omnirom/</a><br />"+
+ "<strong>Root-Tools&nbsp;</strong>:&nbsp;<a href=\"https://code.google.com/p/roottools/\">https://code.google.com/p/roottools/</a><br />"+
+ "<strong>SlidingMenu by jfeinstein10&nbsp;</strong>:&nbsp;<a href=\"https://github.com/jfeinstein10/SlidingMenu\">https://github.com/jfeinstein10/SlidingMenu</a></p>"+
+ "<p>"+
+ "<u>A HUGE thanks goes to these guys, who makes Android better every day. A lot of thanks also to all our kernel developers, without their work this application has no reason to exist!</u></p>"));
+ builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ dialog.cancel();
+ }
+ });
+ builder.create().show();
+
+ }
+
+ private void mountPartitions() {
+ CommandCapture command = new CommandCapture(0, "busybox mount -o rw,remount /sys");
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public static void setAppTheme() {
+ boolean light = mPrefs.getBoolean(SettingsFragment.KEY_THEME, false);
+ if(light) {
+ mContext.setTheme(R.style.AppLight);
+ menu.setBackground(mContext.getResources().getDrawable(R.drawable.bg_menu_light));
+ mContainer.setBackground(mContext.getResources().getDrawable(R.drawable.bg_light));
+ mGlossaryContainer.setBackground(mContext.getResources().getDrawable(R.drawable.bg_menu_light));
+ menulist.setDivider(new ColorDrawable(Color.parseColor("#bbbbbb")));
+ menulist.setDividerHeight(2);
+ }else {
+ mContext.setTheme(R.style.AppTheme);
+ menu.setBackground(mContext.getResources().getDrawable(R.drawable.bg_menu_dark));;
+ mContainer.setBackground(mContext.getResources().getDrawable(R.drawable.bg_dark));
+ mGlossaryContainer.setBackground(mContext.getResources().getDrawable(R.drawable.bg_menu_dark));
+ }
+
+ }
+
+
+ private void copyHelpers() {
+
+ if(!new File(this.getFilesDir().getPath()+"/helpers.sh").exists()) {
+
+ InputStream stream = null;
+ OutputStream output = null;
+
+ try {
+ stream = this.getAssets().open("helpers.sh");
+ output = new BufferedOutputStream(new FileOutputStream(this.getFilesDir() + "/helpers.sh"));
+
+ byte data[] = new byte[1024];
+ int count;
+
+ while((count = stream.read(data)) != -1)
+ {
+ output.write(data, 0, count);
+ }
+
+ output.flush();
+ output.close();
+ stream.close();
+
+ stream = null;
+ output = null;
+
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/PresetsBaseAdapter.java b/src/com/dsht/kerneltweaker/PresetsBaseAdapter.java
new file mode 100644
index 0000000..61e65fa
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/PresetsBaseAdapter.java
@@ -0,0 +1,73 @@
+package com.dsht.kerneltweaker;
+
+import com.dsht.settings.SettingsFragment;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.preference.PreferenceManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+public class PresetsBaseAdapter extends BaseAdapter {
+
+ String[] presetValues;
+ String[] presetNames;
+ Context mContext;
+ SharedPreferences mPrefs;
+
+ public PresetsBaseAdapter(Context con, String[] values, String[] names) {
+ this.presetValues = values;
+ this.presetNames = names;
+ this.mContext = con;
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ }
+
+ @Override
+ public int getCount() {
+ // TODO Auto-generated method stub
+ return presetValues.length;
+ }
+
+ @Override
+ public Object getItem(int arg0) {
+ // TODO Auto-generated method stub
+ return presetValues[arg0];
+ }
+
+ @Override
+ public long getItemId(int arg0) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View v, ViewGroup parent) {
+ // TODO Auto-generated method stub
+ if(v == null) {
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+ v = inflater.inflate(R.layout.list_item, parent, false);
+ }
+ TextView title = (TextView) v.findViewById(android.R.id.text1);
+ TextView summary = (TextView) v.findViewById(android.R.id.text2);
+ title.setText(presetNames[position]);
+ summary.setText(presetValues[position]);
+ if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int color = mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ title.setTextColor(color);
+ }else if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_LMK, Color.parseColor("#ff0099cc"));
+ title.setTextColor(col);
+ }
+ else {
+ int color = Color.parseColor( mContext.getResources().getStringArray(R.array.menu_colors)[6]);
+ title.setTextColor(color);
+ }
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/RecoveryBaseAdapter.java b/src/com/dsht/kerneltweaker/RecoveryBaseAdapter.java
new file mode 100644
index 0000000..b3f00ce
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/RecoveryBaseAdapter.java
@@ -0,0 +1,111 @@
+package com.dsht.kerneltweaker;
+
+import java.util.ArrayList;
+
+import com.dsht.settings.SettingsFragment;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class RecoveryBaseAdapter extends BaseAdapter {
+
+ Context mContext;
+ ArrayList<String> mNames;
+ ArrayList<String> mValues;
+
+ public RecoveryBaseAdapter(Context context, ArrayList<String> names, ArrayList<String> values) {
+ this.mContext = context;
+ this.mNames = names;
+ this.mValues = values;
+ }
+
+ @Override
+ public int getCount() {
+ // TODO Auto-generated method stub
+ return mNames.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ // TODO Auto-generated method stub
+ return mNames.get(position);
+ }
+
+ public String getNameItem(int position) {
+ // TODO Auto-generated method stub
+ return mNames.get(position);
+ }
+
+ public String getValueItem(int position) {
+ // TODO Auto-generated method stub
+ return mValues.get(position);
+ }
+
+ @Override
+ public long getItemId(int arg0) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public void insert(String name, String value, int nameindex, int valueindex) {
+ if (mNames != null && mValues != null) {
+ mNames.add(nameindex, name);
+ mValues.add(valueindex, value);
+ notifyDataSetChanged();
+
+ } else {
+ mNames.add(nameindex, name);
+ mValues.add(valueindex, value);
+ notifyDataSetChanged();
+ }
+ }
+
+ public void remove(String removename, String removevalue) {
+ if (mNames != null && mValues != null) {
+ mNames.remove(removename);
+ mValues.remove(removevalue);
+ notifyDataSetChanged();
+ } else {
+ mNames.remove(removename);
+ mValues.remove(removevalue);
+ notifyDataSetChanged();
+ }
+ }
+
+
+ @Override
+ public View getView(int position, View v, ViewGroup parent) {
+ // TODO Auto-generated method stub
+ if(v== null) {
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = inflater.inflate(R.layout.dragsort_list_item, parent, false);
+ }
+ TextView title = (TextView) v.findViewById(R.id.name);
+ ImageView image = (ImageView) v.findViewById(R.id.image);
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int color = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ title.setTextColor(color);
+ image.setColorFilter(color);
+ }else if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_RECOVERY, Color.parseColor("#ff0099cc"));
+ title.setTextColor(col);
+ image.setColorFilter(col);
+ }
+ else {
+ int color = Color.parseColor( mContext.getResources().getStringArray(R.array.menu_colors)[position]);
+ title.setTextColor(color);
+ image.setColorFilter(color);
+ }
+ TextView command = (TextView) v.findViewById(R.id.value);
+ title.setText(mNames.get(position));
+ command.setText(mValues.get(position));
+ return v;
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/Startup.java b/src/com/dsht/kerneltweaker/Startup.java
new file mode 100644
index 0000000..1963c96
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/Startup.java
@@ -0,0 +1,118 @@
+package com.dsht.kerneltweaker;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.kerneltweaker.database.VddDatabaseHandler;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+
+public class Startup extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent bootintent) {
+ // TODO Auto-generated method stub
+
+ DatabaseHandler db = new DatabaseHandler(context);
+ VddDatabaseHandler vddDb = new VddDatabaseHandler(context);
+ applyValuesAsync(context, db, vddDb, false);
+ }
+
+ public static void applyValuesAsync(final Context mContext, final DatabaseHandler db, final VddDatabaseHandler vddDb, final boolean debug) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ ProgressDialog pd;
+
+ @Override
+ protected void onPreExecute() {
+ if(debug) {
+ pd = new ProgressDialog(mContext);
+ pd.setIndeterminate(true);
+ pd.setMessage("Applying values...Please wait");
+ pd.setCancelable(false);
+ pd.show();
+ }
+ }
+
+ @Override
+ protected String doInBackground(String... params) {
+ List<DataItem> items = db.getAllItems();
+ List<DataItem> vddItems = vddDb.getAllItems();
+
+ if(items.size() != 0) {
+ for(DataItem item : items) {
+ CommandCapture command = null;
+ if(item.getFileName().contains("TCP Congestion control")) {
+ command = new CommandCapture(0, item.getName().replaceAll("'", ""));
+ Helpers.debugger(mContext, "---TCP---");
+ Helpers.debugger(mContext,item.getName().replaceAll("'", "") );
+
+ }else {
+ String value = item.getValue();
+ String fPath = item.getName().replaceAll("'", "");
+ command = new CommandCapture(0, "echo \""+value+"\" > "+fPath);
+ Helpers.debugger(mContext, item.getFileName());
+ Helpers.debugger(mContext, "echo \""+value+"\" > "+fPath);
+ Helpers.checkApply(mContext, item.getFileName(), value , fPath);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ if(vddItems.size() != 0 ) {
+ Helpers.debugger(mContext, "---VDD---");
+ for(DataItem item : vddItems) {
+ String path = item.getName().replaceAll("'", "");
+ String value = item.getValue().replaceAll("'", "");
+ CommandCapture command = new CommandCapture(0, "echo \""+value+"\" > "+path);
+ try {
+ RootTools.getShell(true).add(command);
+ Helpers.debugger(mContext, "echo \""+value+"\" > "+path);
+ Helpers.checkApply(mContext, item.getFileName(), value , path);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ return "executed";
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ if(debug) {
+ pd.dismiss();
+ }
+ }
+ }
+ new LongOperation().execute();
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/SwipeDismissListViewTouchListener.java b/src/com/dsht/kerneltweaker/SwipeDismissListViewTouchListener.java
new file mode 100644
index 0000000..8a37f75
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/SwipeDismissListViewTouchListener.java
@@ -0,0 +1,370 @@
+package com.dsht.kerneltweaker;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.graphics.Rect;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
+import android.widget.AbsListView;
+import android.widget.ListView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A {@link View.OnTouchListener} that makes the list items in a {@link ListView}
+ * dismissable. {@link ListView} is given special treatment because by default it handles touches
+ * for its list items... i.e. it's in charge of drawing the pressed state (the list selector),
+ * handling list item clicks, etc.
+ *
+ * <p>After creating the listener, the caller should also call
+ * {@link ListView#setOnScrollListener(AbsListView.OnScrollListener)}, passing
+ * in the scroll listener returned by {@link #makeScrollListener()}. If a scroll listener is
+ * already assigned, the caller should still pass scroll changes through to this listener. This will
+ * ensure that this {@link SwipeDismissListViewTouchListener} is paused during list view
+ * scrolling.</p>
+ *
+ * <p>Example usage:</p>
+ *
+ * <pre>
+ * SwipeDismissListViewTouchListener touchListener =
+ * new SwipeDismissListViewTouchListener(
+ * listView,
+ * new SwipeDismissListViewTouchListener.OnDismissCallback() {
+ * public void onDismiss(ListView listView, int[] reverseSortedPositions) {
+ * for (int position : reverseSortedPositions) {
+ * adapter.remove(adapter.getItem(position));
+ * }
+ * adapter.notifyDataSetChanged();
+ * }
+ * });
+ * listView.setOnTouchListener(touchListener);
+ * listView.setOnScrollListener(touchListener.makeScrollListener());
+ * </pre>
+ *
+ * <p>This class Requires API level 12 or later due to use of {@link
+ * ViewPropertyAnimator}.</p>
+ *
+ * <p>For a generalized {@link View.OnTouchListener} that makes any view dismissable,
+ * see {@link SwipeDismissTouchListener}.</p>
+ *
+ * @see SwipeDismissTouchListener
+ */
+public class SwipeDismissListViewTouchListener implements View.OnTouchListener {
+ // Cached ViewConfiguration and system-wide constant values
+ private int mSlop;
+ private int mMinFlingVelocity;
+ private int mMaxFlingVelocity;
+ private long mAnimationTime;
+
+ // Fixed properties
+ private ListView mListView;
+ private DismissCallbacks mCallbacks;
+ private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero
+
+ // Transient properties
+ private List<PendingDismissData> mPendingDismisses = new ArrayList<PendingDismissData>();
+ private int mDismissAnimationRefCount = 0;
+ private float mDownX;
+ private boolean mSwiping;
+ private VelocityTracker mVelocityTracker;
+ private int mDownPosition;
+ private View mDownView;
+ private boolean mPaused;
+
+ /**
+ * The callback interface used by {@link SwipeDismissListViewTouchListener} to inform its client
+ * about a successful dismissal of one or more list item positions.
+ */
+ public interface DismissCallbacks {
+ /**
+ * Called to determine whether the given position can be dismissed.
+ */
+ boolean canDismiss(int position);
+
+ /**
+ * Called when the user has indicated they she would like to dismiss one or more list item
+ * positions.
+ *
+ * @param listView The originating {@link ListView}.
+ * @param reverseSortedPositions An array of positions to dismiss, sorted in descending
+ * order for convenience.
+ */
+ void onDismiss(ListView listView, int[] reverseSortedPositions);
+ }
+
+ /**
+ * Constructs a new swipe-to-dismiss touch listener for the given list view.
+ *
+ * @param listView The list view whose items should be dismissable.
+ * @param callbacks The callback to trigger when the user has indicated that she would like to
+ * dismiss one or more list items.
+ */
+ public SwipeDismissListViewTouchListener(ListView listView, DismissCallbacks callbacks) {
+ ViewConfiguration vc = ViewConfiguration.get(listView.getContext());
+ mSlop = vc.getScaledTouchSlop();
+ mMinFlingVelocity = vc.getScaledMinimumFlingVelocity() * 16;
+ mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
+ mAnimationTime = listView.getContext().getResources().getInteger(
+ android.R.integer.config_shortAnimTime);
+ mListView = listView;
+ mCallbacks = callbacks;
+ }
+
+ /**
+ * Enables or disables (pauses or resumes) watching for swipe-to-dismiss gestures.
+ *
+ * @param enabled Whether or not to watch for gestures.
+ */
+ public void setEnabled(boolean enabled) {
+ mPaused = !enabled;
+ }
+
+ /**
+ * Returns an {@link AbsListView.OnScrollListener} to be added to the {@link
+ * ListView} using {@link ListView#setOnScrollListener(AbsListView.OnScrollListener)}.
+ * If a scroll listener is already assigned, the caller should still pass scroll changes through
+ * to this listener. This will ensure that this {@link SwipeDismissListViewTouchListener} is
+ * paused during list view scrolling.</p>
+ *
+ * @see SwipeDismissListViewTouchListener
+ */
+ public AbsListView.OnScrollListener makeScrollListener() {
+ return new AbsListView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(AbsListView absListView, int scrollState) {
+ setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+ }
+
+ @Override
+ public void onScroll(AbsListView absListView, int i, int i1, int i2) {
+ }
+ };
+ }
+
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (mViewWidth < 2) {
+ mViewWidth = mListView.getWidth();
+ }
+
+ switch (motionEvent.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN: {
+ if (mPaused) {
+ return false;
+ }
+
+ // TODO: ensure this is a finger, and set a flag
+
+ // Find the child view that was touched (perform a hit test)
+ Rect rect = new Rect();
+ int childCount = mListView.getChildCount();
+ int[] listViewCoords = new int[2];
+ mListView.getLocationOnScreen(listViewCoords);
+ int x = (int) motionEvent.getRawX() - listViewCoords[0];
+ int y = (int) motionEvent.getRawY() - listViewCoords[1];
+ View child;
+ for (int i = 0; i < childCount; i++) {
+ child = mListView.getChildAt(i);
+ child.getHitRect(rect);
+ if (rect.contains(x, y)) {
+ mDownView = child;
+ break;
+ }
+ }
+
+ if (mDownView != null) {
+ mDownX = motionEvent.getRawX();
+ mDownPosition = mListView.getPositionForView(mDownView);
+ if (mCallbacks.canDismiss(mDownPosition)) {
+ mVelocityTracker = VelocityTracker.obtain();
+ mVelocityTracker.addMovement(motionEvent);
+ } else {
+ mDownView = null;
+ }
+ }
+ return false;
+ }
+
+ case MotionEvent.ACTION_CANCEL: {
+ if (mVelocityTracker == null) {
+ break;
+ }
+
+ if (mDownView != null && mSwiping) {
+ // cancel
+ mDownView.animate()
+ .translationX(0)
+ .alpha(1)
+ .setDuration(mAnimationTime)
+ .setListener(null);
+ }
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ mDownX = 0;
+ mDownView = null;
+ mDownPosition = ListView.INVALID_POSITION;
+ mSwiping = false;
+ break;
+ }
+
+ case MotionEvent.ACTION_UP: {
+ if (mVelocityTracker == null) {
+ break;
+ }
+
+ float deltaX = motionEvent.getRawX() - mDownX;
+ mVelocityTracker.addMovement(motionEvent);
+ mVelocityTracker.computeCurrentVelocity(1000);
+ float velocityX = mVelocityTracker.getXVelocity();
+ float absVelocityX = Math.abs(velocityX);
+ float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
+ boolean dismiss = false;
+ boolean dismissRight = false;
+ if (Math.abs(deltaX) > mViewWidth / 2) {
+ dismiss = true;
+ dismissRight = deltaX > 0;
+ } else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity
+ && absVelocityY < absVelocityX) {
+ // dismiss only if flinging in the same direction as dragging
+ dismiss = (velocityX < 0) == (deltaX < 0);
+ dismissRight = mVelocityTracker.getXVelocity() > 0;
+ }
+ if (dismiss) {
+ // dismiss
+ final View downView = mDownView; // mDownView gets null'd before animation ends
+ final int downPosition = mDownPosition;
+ ++mDismissAnimationRefCount;
+ mDownView.animate()
+ .translationX(dismissRight ? mViewWidth : -mViewWidth)
+ .alpha(0)
+ .setDuration(mAnimationTime)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ performDismiss(downView, downPosition);
+ }
+ });
+ } else {
+ // cancel
+ mDownView.animate()
+ .translationX(0)
+ .alpha(1)
+ .setDuration(mAnimationTime)
+ .setListener(null);
+ }
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ mDownX = 0;
+ mDownView = null;
+ mDownPosition = ListView.INVALID_POSITION;
+ mSwiping = false;
+ break;
+ }
+
+ case MotionEvent.ACTION_MOVE: {
+ if (mVelocityTracker == null || mPaused) {
+ break;
+ }
+
+ mVelocityTracker.addMovement(motionEvent);
+ float deltaX = motionEvent.getRawX() - mDownX;
+ if (Math.abs(deltaX) > mSlop) {
+ mSwiping = true;
+ mListView.requestDisallowInterceptTouchEvent(true);
+
+ // Cancel ListView's touch (un-highlighting the item)
+ MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
+ cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
+ (motionEvent.getActionIndex()
+ << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
+ mListView.onTouchEvent(cancelEvent);
+ cancelEvent.recycle();
+ }
+
+ if (mSwiping) {
+ mDownView.setTranslationX(deltaX);
+ mDownView.setAlpha(Math.max(0f, Math.min(1f,
+ 1f - 2f * Math.abs(deltaX) / mViewWidth)));
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+ }
+
+ class PendingDismissData implements Comparable<PendingDismissData> {
+ public int position;
+ public View view;
+
+ public PendingDismissData(int position, View view) {
+ this.position = position;
+ this.view = view;
+ }
+
+ @Override
+ public int compareTo(PendingDismissData other) {
+ // Sort by descending position
+ return other.position - position;
+ }
+ }
+
+ private void performDismiss(final View dismissView, final int dismissPosition) {
+ // Animate the dismissed list item to zero-height and fire the dismiss callback when
+ // all dismissed list item animations have completed. This triggers layout on each animation
+ // frame; in the future we may want to do something smarter and more performant.
+
+ final ViewGroup.LayoutParams lp = dismissView.getLayoutParams();
+ final int originalHeight = dismissView.getHeight();
+
+ ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime);
+
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ --mDismissAnimationRefCount;
+ if (mDismissAnimationRefCount == 0) {
+ // No active animations, process all pending dismisses.
+ // Sort by descending position
+ Collections.sort(mPendingDismisses);
+
+ int[] dismissPositions = new int[mPendingDismisses.size()];
+ for (int i = mPendingDismisses.size() - 1; i >= 0; i--) {
+ dismissPositions[i] = mPendingDismisses.get(i).position;
+ }
+ mCallbacks.onDismiss(mListView, dismissPositions);
+
+ ViewGroup.LayoutParams lp;
+ for (PendingDismissData pendingDismiss : mPendingDismisses) {
+ // Reset view presentation
+ pendingDismiss.view.setAlpha(1f);
+ pendingDismiss.view.setTranslationX(0);
+ lp = pendingDismiss.view.getLayoutParams();
+ lp.height = originalHeight;
+ pendingDismiss.view.setLayoutParams(lp);
+ }
+
+ mPendingDismisses.clear();
+ }
+ }
+ });
+
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ lp.height = (Integer) valueAnimator.getAnimatedValue();
+ dismissView.setLayoutParams(lp);
+ }
+ });
+
+ mPendingDismisses.add(new PendingDismissData(dismissPosition, dismissView));
+ animator.start();
+ }
+} \ No newline at end of file
diff --git a/src/com/dsht/kerneltweaker/SwipeDismissTouchListener.java b/src/com/dsht/kerneltweaker/SwipeDismissTouchListener.java
new file mode 100644
index 0000000..d58f0e4
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/SwipeDismissTouchListener.java
@@ -0,0 +1,255 @@
+package com.dsht.kerneltweaker;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.app.ListActivity;
+import android.app.ListFragment;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+/**
+ * A {@link View.OnTouchListener} that makes any {@link View} dismissable when the
+ * user swipes (drags her finger) horizontally across the view.
+ *
+ * <p><em>For {@link ListView} list items that don't manage their own touch events
+ * (i.e. you're using
+ * {@link ListView#setOnItemClickListener(AdapterView.OnItemClickListener)}
+ * or an equivalent listener on {@link ListActivity} or
+ * {@link ListFragment}, use {@link SwipeDismissListViewTouchListener} instead.</em></p>
+ *
+ * <p>Example usage:</p>
+ *
+ * <pre>
+ * view.setOnTouchListener(new SwipeDismissTouchListener(
+ * view,
+ * null, // Optional token/cookie object
+ * new SwipeDismissTouchListener.OnDismissCallback() {
+ * public void onDismiss(View view, Object token) {
+ * parent.removeView(view);
+ * }
+ * }));
+ * </pre>
+ *
+ * <p>This class Requires API level 12 or later due to use of {@link
+ * android.view.ViewPropertyAnimator}.</p>
+ *
+ * @see SwipeDismissListViewTouchListener
+ */
+public class SwipeDismissTouchListener implements View.OnTouchListener {
+ // Cached ViewConfiguration and system-wide constant values
+ private int mSlop;
+ private int mMinFlingVelocity;
+ private int mMaxFlingVelocity;
+ private long mAnimationTime;
+
+ // Fixed properties
+ private View mView;
+ private DismissCallbacks mCallbacks;
+ private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero
+
+ // Transient properties
+ private float mDownX;
+ private boolean mSwiping;
+ private Object mToken;
+ private VelocityTracker mVelocityTracker;
+ private float mTranslationX;
+
+ /**
+ * The callback interface used by {@link SwipeDismissTouchListener} to inform its client
+ * about a successful dismissal of the view for which it was created.
+ */
+ public interface DismissCallbacks {
+ /**
+ * Called to determine whether the view can be dismissed.
+ */
+ boolean canDismiss(Object token);
+
+ /**
+ * Called when the user has indicated they she would like to dismiss the view.
+ *
+ * @param view The originating {@link View} to be dismissed.
+ * @param token The optional token passed to this object's constructor.
+ */
+ void onDismiss(View view, Object token);
+ }
+
+ /**
+ * Constructs a new swipe-to-dismiss touch listener for the given view.
+ *
+ * @param view The view to make dismissable.
+ * @param token An optional token/cookie object to be passed through to the callback.
+ * @param callbacks The callback to trigger when the user has indicated that she would like to
+ * dismiss this view.
+ */
+ public SwipeDismissTouchListener(View view, Object token, DismissCallbacks callbacks) {
+ ViewConfiguration vc = ViewConfiguration.get(view.getContext());
+ mSlop = vc.getScaledTouchSlop();
+ mMinFlingVelocity = vc.getScaledMinimumFlingVelocity() * 16;
+ mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
+ mAnimationTime = view.getContext().getResources().getInteger(
+ android.R.integer.config_shortAnimTime);
+ mView = view;
+ mToken = token;
+ mCallbacks = callbacks;
+ }
+
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ // offset because the view is translated during swipe
+ motionEvent.offsetLocation(mTranslationX, 0);
+
+ if (mViewWidth < 2) {
+ mViewWidth = mView.getWidth();
+ }
+
+ switch (motionEvent.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN: {
+ // TODO: ensure this is a finger, and set a flag
+ mDownX = motionEvent.getRawX();
+ if (mCallbacks.canDismiss(mToken)) {
+ mVelocityTracker = VelocityTracker.obtain();
+ mVelocityTracker.addMovement(motionEvent);
+ }
+ return false;
+ }
+
+ case MotionEvent.ACTION_UP: {
+ if (mVelocityTracker == null) {
+ break;
+ }
+
+ float deltaX = motionEvent.getRawX() - mDownX;
+ mVelocityTracker.addMovement(motionEvent);
+ mVelocityTracker.computeCurrentVelocity(1000);
+ float velocityX = mVelocityTracker.getXVelocity();
+ float absVelocityX = Math.abs(velocityX);
+ float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
+ boolean dismiss = false;
+ boolean dismissRight = false;
+ if (Math.abs(deltaX) > mViewWidth / 2) {
+ dismiss = true;
+ dismissRight = deltaX > 0;
+ } else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity
+ && absVelocityY < absVelocityX) {
+ // dismiss only if flinging in the same direction as dragging
+ dismiss = (velocityX < 0) == (deltaX < 0);
+ dismissRight = mVelocityTracker.getXVelocity() > 0;
+ }
+ if (dismiss) {
+ // dismiss
+ mView.animate()
+ .translationX(dismissRight ? mViewWidth : -mViewWidth)
+ .alpha(0)
+ .setDuration(mAnimationTime)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ performDismiss();
+ }
+ });
+ } else if (mSwiping) {
+ // cancel
+ mView.animate()
+ .translationX(0)
+ .alpha(1)
+ .setDuration(mAnimationTime)
+ .setListener(null);
+ }
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ mTranslationX = 0;
+ mDownX = 0;
+ mSwiping = false;
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL: {
+ if (mVelocityTracker == null) {
+ break;
+ }
+
+ mView.animate()
+ .translationX(0)
+ .alpha(1)
+ .setDuration(mAnimationTime)
+ .setListener(null);
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ mTranslationX = 0;
+ mDownX = 0;
+ mSwiping = false;
+ break;
+ }
+
+ case MotionEvent.ACTION_MOVE: {
+ if (mVelocityTracker == null) {
+ break;
+ }
+
+ mVelocityTracker.addMovement(motionEvent);
+ float deltaX = motionEvent.getRawX() - mDownX;
+ if (Math.abs(deltaX) > mSlop) {
+ mSwiping = true;
+ mView.getParent().requestDisallowInterceptTouchEvent(true);
+
+ // Cancel listview's touch
+ MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
+ cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
+ (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
+ mView.onTouchEvent(cancelEvent);
+ cancelEvent.recycle();
+ }
+
+ if (mSwiping) {
+ mTranslationX = deltaX;
+ mView.setTranslationX(deltaX);
+ // TODO: use an ease-out interpolator or such
+ mView.setAlpha(Math.max(0f, Math.min(1f,
+ 1f - 2f * Math.abs(deltaX) / mViewWidth)));
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+ }
+
+ private void performDismiss() {
+ // Animate the dismissed view to zero-height and then fire the dismiss callback.
+ // This triggers layout on each animation frame; in the future we may want to do something
+ // smarter and more performant.
+
+ final ViewGroup.LayoutParams lp = mView.getLayoutParams();
+ final int originalHeight = mView.getHeight();
+
+ ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime);
+
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mCallbacks.onDismiss(mView, mToken);
+ // Reset view presentation
+ mView.setAlpha(1f);
+ mView.setTranslationX(0);
+ lp.height = originalHeight;
+ mView.setLayoutParams(lp);
+ }
+ });
+
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ lp.height = (Integer) valueAnimator.getAnimatedValue();
+ mView.setLayoutParams(lp);
+ }
+ });
+
+ animator.start();
+ }
+}
diff --git a/src/com/dsht/kerneltweaker/ZoomOutPageTransformer.java b/src/com/dsht/kerneltweaker/ZoomOutPageTransformer.java
new file mode 100644
index 0000000..7288c83
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/ZoomOutPageTransformer.java
@@ -0,0 +1,43 @@
+package com.dsht.kerneltweaker;
+
+import android.view.View;
+import android.support.v4.view.ViewPager;
+
+public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
+ private static float MIN_SCALE = 0.85f;
+ private static float MIN_ALPHA = 0.5f;
+
+ public void transformPage(View view, float position) {
+ int pageWidth = view.getWidth();
+ int pageHeight = view.getHeight();
+
+ if (position < -1) { // [-Infinity,-1)
+ // This page is way off-screen to the left.
+ view.setAlpha(0);
+
+ } else if (position <= 1) { // [-1,1]
+ // Modify the default slide transition to shrink the page as well
+ float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
+ float vertMargin = pageHeight * (1 - scaleFactor) / 2;
+ float horzMargin = pageWidth * (1 - scaleFactor) / 2;
+ if (position < 0) {
+ view.setTranslationX(horzMargin - vertMargin / 2);
+ } else {
+ view.setTranslationX(-horzMargin + vertMargin / 2);
+ }
+
+ // Scale the page down (between MIN_SCALE and 1)
+ view.setScaleX(scaleFactor);
+ view.setScaleY(scaleFactor);
+
+ // Fade the page relative to its size.
+ view.setAlpha(MIN_ALPHA +
+ (scaleFactor - MIN_SCALE) /
+ (1 - MIN_SCALE) * (1 - MIN_ALPHA));
+
+ } else { // (1,+Infinity]
+ // This page is way off-screen to the right.
+ view.setAlpha(0);
+ }
+ }
+}
diff --git a/src/com/dsht/kerneltweaker/database/DataItem.java b/src/com/dsht/kerneltweaker/database/DataItem.java
new file mode 100644
index 0000000..c510bd1
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/database/DataItem.java
@@ -0,0 +1,82 @@
+package com.dsht.kerneltweaker.database;
+
+public class DataItem {
+
+ //private variables
+ int _id;
+ String _name;
+ String _filename;
+ String _value;
+ String _category;
+
+ // Empty constructor
+ public DataItem(){
+
+ }
+ // constructor
+ public DataItem(int id, String name, String _value, String filename, String category){
+ this._id = id;
+ this._name = name;
+ this._value = _value;
+ this._filename = filename;
+ this._category = category;
+ }
+
+ // constructor
+ public DataItem(String name, String _value, String filename, String category){
+ this._name = name;
+ this._value = _value;
+ this._filename = filename;
+ this._category = category;
+ }
+ // getting ID
+ public int getID(){
+ return this._id;
+ }
+
+ // setting id
+ public void setID(int id){
+ this._id = id;
+ }
+
+ // getting name
+ public String getName(){
+ return this._name;
+ }
+
+ // setting name
+ public void setName(String name){
+ this._name = name;
+ }
+
+ // getting value
+ public String getValue(){
+ return this._value;
+ }
+
+ // setting value
+ public void setValue(String value){
+ this._value = value;
+ }
+
+ // getting value
+ public String getFileName(){
+ return this._filename;
+ }
+
+ // setting value
+ public void setFileName(String filename){
+ this._filename = filename;
+ }
+
+ // getting value
+ public String getCategory(){
+ return this._category;
+ }
+
+ // setting value
+ public void setCategory(String category){
+ this._category = category;
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/database/DatabaseHandler.java b/src/com/dsht/kerneltweaker/database/DatabaseHandler.java
new file mode 100644
index 0000000..d33d65a
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/database/DatabaseHandler.java
@@ -0,0 +1,173 @@
+package com.dsht.kerneltweaker.database;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class DatabaseHandler extends SQLiteOpenHelper {
+
+ // All Static variables
+ // Database Version
+ private static final int DATABASE_VERSION = 1;
+
+ // Database Name
+ private static final String DATABASE_NAME = "kernelTweaker";
+
+ // Contacts table name
+ private static final String TABLE_CONTACTS = "bootValues";
+
+ // Contacts Table Columns names
+ private static final String KEY_ID = "id";
+ private static final String KEY_NAME = "name";
+ private static final String KEY_VALUE = "value";
+ private static final String KEY_FILENAME = "filename";
+ private static final String KEY_CAT = "category";
+
+
+ public DatabaseHandler(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ // Creating Tables
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ + KEY_VALUE + " TEXT," + KEY_FILENAME + " TEXT," + KEY_CAT + " TEXT" + ")";
+ db.execSQL(CREATE_CONTACTS_TABLE);
+ }
+
+ // Upgrading database
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // Drop older table if existed
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);
+
+ // Create tables again
+ onCreate(db);
+ }
+
+ /**
+ * All CRUD(Create, Read, Update, Delete) Operations
+ */
+
+ // Adding new contact
+ public void addItem(DataItem item) {
+ SQLiteDatabase db = this.getWritableDatabase();
+
+ ContentValues values = new ContentValues();
+ values.put(KEY_NAME, item.getName()); // Contact Name
+ values.put(KEY_VALUE, item.getValue()); // Contact Phone
+ values.put(KEY_FILENAME, item.getFileName());
+ values.put(KEY_CAT, item.getCategory());
+
+ // Inserting Row
+ db.insert(TABLE_CONTACTS, null, values);
+ db.close(); // Closing database connection
+ }
+
+ // Getting single contact
+ DataItem getItem(int id) {
+ SQLiteDatabase db = this.getReadableDatabase();
+
+ Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
+ KEY_NAME, KEY_VALUE, KEY_FILENAME, KEY_CAT }, KEY_ID + "=?",
+ new String[] { String.valueOf(id) }, null, null, null, null);
+ if (cursor != null)
+ cursor.moveToFirst();
+
+ DataItem item = new DataItem(Integer.parseInt(cursor.getString(0)),
+ cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4));
+ // return contact
+ return item;
+ }
+
+ // Getting All Contacts
+ public List<DataItem> getAllItems() {
+ List<DataItem> contactList = new ArrayList<DataItem>();
+ // Select All Query
+ String selectQuery = "SELECT * FROM " + TABLE_CONTACTS;
+
+ SQLiteDatabase db = this.getWritableDatabase();
+ Cursor cursor = db.rawQuery(selectQuery, null);
+
+ // looping through all rows and adding to list
+ if (cursor.moveToFirst()) {
+ do {
+ DataItem item = new DataItem();
+ item.setID(Integer.parseInt(cursor.getString(0)));
+ item.setName(cursor.getString(1));
+ item.setValue(cursor.getString(2));
+ item.setFileName(cursor.getString(3));
+ item.setCategory(cursor.getString(4));
+ // Adding contact to list
+ contactList.add(item);
+ } while (cursor.moveToNext());
+ }
+
+ // return contact list
+ return contactList;
+ }
+
+ // Updating single contact
+ public int updateItem(DataItem item) {
+ SQLiteDatabase db = this.getWritableDatabase();
+
+ ContentValues values = new ContentValues();
+ values.put(KEY_NAME, item.getName());
+ values.put(KEY_VALUE, item.getValue());
+ values.put(KEY_FILENAME, item.getFileName());
+ values.put(KEY_CAT, item.getCategory());
+
+ // updating row
+ return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",
+ new String[] { String.valueOf(item.getID()) });
+ }
+
+ // Deleting single item by ID
+ public void deleteItem(DataItem item) {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(TABLE_CONTACTS, KEY_ID + " = ?",
+ new String[] { String.valueOf(item.getID()) });
+ db.close();
+ }
+
+ public void deleteItemByName(String name)
+ {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(TABLE_CONTACTS, KEY_NAME + " = ?" , new String[] {name});
+ db.close();
+ }
+
+ public void deleteItemById(int ID)
+ {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(TABLE_CONTACTS, KEY_ID + " = ?" , new String[] {String.valueOf(ID)});
+ db.close();
+ }
+
+
+ // Getting contacts Count
+ public int getContactsCount() {
+ String countQuery = "SELECT * FROM " + TABLE_CONTACTS;
+ SQLiteDatabase db = this.getReadableDatabase();
+ Cursor cursor = db.rawQuery(countQuery, null);
+ int count = cursor.getCount();
+ cursor.close();
+
+ // return count
+ return count;
+ }
+
+
+ public void deleteAllItems() {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(TABLE_CONTACTS, null, null);
+ db.close();
+ }
+}
diff --git a/src/com/dsht/kerneltweaker/database/VddDatabaseHandler.java b/src/com/dsht/kerneltweaker/database/VddDatabaseHandler.java
new file mode 100644
index 0000000..a781b67
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/database/VddDatabaseHandler.java
@@ -0,0 +1,173 @@
+package com.dsht.kerneltweaker.database;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class VddDatabaseHandler extends SQLiteOpenHelper {
+
+ // All Static variables
+ // Database Version
+ private static final int DATABASE_VERSION = 1;
+
+ // Database Name
+ private static final String DATABASE_NAME = "kernelTweakerVdd";
+
+ // Contacts table name
+ private static final String TABLE_CONTACTS = "VddBootValues";
+
+ // Contacts Table Columns names
+ private static final String KEY_ID = "id";
+ private static final String KEY_NAME = "name";
+ private static final String KEY_VALUE = "value";
+ private static final String KEY_FILENAME = "filename";
+ private static final String KEY_CAT = "category";
+
+
+ public VddDatabaseHandler(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ // Creating Tables
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ + KEY_VALUE + " TEXT," + KEY_FILENAME + " TEXT," + KEY_CAT + " TEXT" + ")";
+ db.execSQL(CREATE_CONTACTS_TABLE);
+ }
+
+ // Upgrading database
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // Drop older table if existed
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);
+
+ // Create tables again
+ onCreate(db);
+ }
+
+ /**
+ * All CRUD(Create, Read, Update, Delete) Operations
+ */
+
+ // Adding new contact
+ public void addItem(DataItem item) {
+ SQLiteDatabase db = this.getWritableDatabase();
+
+ ContentValues values = new ContentValues();
+ values.put(KEY_NAME, item.getName()); // Contact Name
+ values.put(KEY_VALUE, item.getValue()); // Contact Phone
+ values.put(KEY_FILENAME, item.getFileName());
+ values.put(KEY_CAT, item.getCategory());
+
+ // Inserting Row
+ db.insert(TABLE_CONTACTS, null, values);
+ db.close(); // Closing database connection
+ }
+
+ // Getting single contact
+ DataItem getItem(int id) {
+ SQLiteDatabase db = this.getReadableDatabase();
+
+ Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
+ KEY_NAME, KEY_VALUE, KEY_FILENAME, KEY_CAT }, KEY_ID + "=?",
+ new String[] { String.valueOf(id) }, null, null, null, null);
+ if (cursor != null)
+ cursor.moveToFirst();
+
+ DataItem item = new DataItem(Integer.parseInt(cursor.getString(0)),
+ cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4));
+ // return contact
+ return item;
+ }
+
+ // Getting All Contacts
+ public List<DataItem> getAllItems() {
+ List<DataItem> contactList = new ArrayList<DataItem>();
+ // Select All Query
+ String selectQuery = "SELECT * FROM " + TABLE_CONTACTS;
+
+ SQLiteDatabase db = this.getWritableDatabase();
+ Cursor cursor = db.rawQuery(selectQuery, null);
+
+ // looping through all rows and adding to list
+ if (cursor.moveToFirst()) {
+ do {
+ DataItem item = new DataItem();
+ item.setID(Integer.parseInt(cursor.getString(0)));
+ item.setName(cursor.getString(1));
+ item.setValue(cursor.getString(2));
+ item.setFileName(cursor.getString(3));
+ item.setCategory(cursor.getString(4));
+ // Adding contact to list
+ contactList.add(item);
+ } while (cursor.moveToNext());
+ }
+
+ // return contact list
+ return contactList;
+ }
+
+ // Updating single contact
+ public int updateItem(DataItem item) {
+ SQLiteDatabase db = this.getWritableDatabase();
+
+ ContentValues values = new ContentValues();
+ values.put(KEY_NAME, item.getName());
+ values.put(KEY_VALUE, item.getValue());
+ values.put(KEY_FILENAME, item.getFileName());
+ values.put(KEY_CAT, item.getCategory());
+
+ // updating row
+ return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",
+ new String[] { String.valueOf(item.getID()) });
+ }
+
+ // Deleting single item by ID
+ public void deleteItem(DataItem item) {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(TABLE_CONTACTS, KEY_ID + " = ?",
+ new String[] { String.valueOf(item.getID()) });
+ db.close();
+ }
+
+ public void deleteItemByName(String name)
+ {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(TABLE_CONTACTS, KEY_NAME + " = ?" , new String[] {name});
+ db.close();
+ }
+
+ public void deleteItemById(int ID)
+ {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(TABLE_CONTACTS, KEY_ID + " = ?" , new String[] {String.valueOf(ID)});
+ db.close();
+ }
+
+
+ // Getting contacts Count
+ public int getContactsCount() {
+ String countQuery = "SELECT * FROM " + TABLE_CONTACTS;
+ SQLiteDatabase db = this.getReadableDatabase();
+ Cursor cursor = db.rawQuery(countQuery, null);
+ int count = cursor.getCount();
+ cursor.close();
+
+ // return count
+ return count;
+ }
+
+ public void deleteAllItems() {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(TABLE_CONTACTS, null, null);
+ db.close();
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/BackupFragment.java b/src/com/dsht/kerneltweaker/fragments/BackupFragment.java
new file mode 100644
index 0000000..6049aaf
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/BackupFragment.java
@@ -0,0 +1,279 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.BackupBaseAdapter;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.SwipeDismissListViewTouchListener;
+import com.dsht.kerneltweaker.SwipeDismissListViewTouchListener.DismissCallbacks;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.Environment;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class BackupFragment extends Fragment implements OnClickListener, OnItemClickListener {
+
+ private Context mContext;
+ private LinearLayout mBackupBoot;
+ private LinearLayout mBackupRecovery;
+ private ListView mList;
+ private List<File> listFiles;
+ private BackupBaseAdapter mAdapter;
+ private File backupDir;
+ private SwipeDismissListViewTouchListener touchListener;
+ private TextView mBoot;
+ private TextView mRecovery;
+ private ImageView mBootImage;
+ private ImageView mRecoveryImage;
+ private View mSepar1;
+ private View mSepar2;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ setRetainInstance(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.backup_list, container,false);
+ mList = (ListView) v.findViewById(R.id.navbarlist);
+ mBackupBoot = (LinearLayout) v.findViewById(R.id.backup_boot);
+ mBackupRecovery = (LinearLayout) v.findViewById(R.id.backup_recovery);
+ LinearLayout mEmpty = (LinearLayout) v.findViewById(R.id.empty);
+ mList.setEmptyView(mEmpty);
+
+ mBoot = (TextView) v.findViewById(R.id.titleboot);
+ mRecovery = (TextView) v.findViewById(R.id.titlerecovery);
+ mBootImage = (ImageView) v.findViewById(R.id.image);
+ mRecoveryImage = (ImageView) v.findViewById(R.id.image2);
+ mSepar1 = (View) v.findViewById(R.id.view1);
+ mSepar2 = (View) v.findViewById(R.id.View2);
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int color = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ mBoot.setTextColor(color);
+ mRecovery.setTextColor(color);
+ mBootImage.setColorFilter(color);
+ mRecoveryImage.setColorFilter(color);
+ mSepar1.setBackgroundColor(color);
+ mSepar2.setBackgroundColor(color);
+ }else if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int color = MainActivity.mPrefs.getInt(SettingsFragment.KEY_BAK, 0);
+ mBoot.setTextColor(color);
+ mRecovery.setTextColor(color);
+ mBootImage.setColorFilter(color);
+ mRecoveryImage.setColorFilter(color);
+ mSepar1.setBackgroundColor(color);
+ mSepar2.setBackgroundColor(color);
+ }
+
+
+ backupDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/K-BACKUPS");
+ if(!backupDir.exists()) {
+ backupDir.mkdirs();
+ }
+ listFiles = list(backupDir.listFiles());
+ mAdapter = new BackupBaseAdapter(mContext, listFiles);
+ mList.setAdapter(mAdapter);
+ mBackupBoot.setOnClickListener(this);
+ mBackupRecovery.setOnClickListener(this);
+
+ touchListener =
+ new SwipeDismissListViewTouchListener(
+ mList,
+ new DismissCallbacks() {
+ public void onDismiss(ListView listView, int[] reverseSortedPositions) {
+ for (int position : reverseSortedPositions) {
+ File f = listFiles.get(position);
+ f.delete();
+ mAdapter.remove(mAdapter.getItem(position));
+
+ }
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public boolean canDismiss(int position) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+ });
+ mList.setOnTouchListener(touchListener);
+ mList.setOnScrollListener(touchListener.makeScrollListener());
+ mList.setOnItemClickListener(this);
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle(true);
+ }
+
+ return v;
+ }
+
+ @Override
+ public void onClick(View v) {
+ // TODO Auto-generated method stub
+ switch(v.getId()) {
+ case R.id.backup_boot:
+ doBackup(true);
+ break;
+ case R.id.backup_recovery:
+ doBackup(false);
+ break;
+ }
+
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
+ // TODO Auto-generated method stub
+ showDialog(arg2);
+ }
+
+
+ private void doBackup(final boolean boot) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LinearLayout ll = new LinearLayout(mContext);
+ ll.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
+ final EditText et = new EditText(mContext);
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ params.setMargins(40, 40, 40, 40);
+ params.gravity = Gravity.CENTER;
+ et.setLayoutParams(params);
+ et.setGravity(Gravity.CENTER_HORIZONTAL);
+ et.setHint("backup name...");;
+ ll.addView(et);
+ builder.setView(ll);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ String value = et.getText().toString();
+ if(!value.contains(".img")){
+ value +=".img";
+ }
+ CommandCapture command = null;
+ if(boot) {
+ command = new CommandCapture(0,"dd if=/dev/block/platform/msm_sdcc.1/by-name/boot of="+backupDir.getAbsolutePath()+"/"+value);
+ }else {
+ command = new CommandCapture(0,"dd if=/dev/block/platform/msm_sdcc.1/by-name/recovery of="+backupDir.getAbsolutePath()+"/"+value);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ mAdapter.add(new File(backupDir.getAbsolutePath()+"/"+value));
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ } );
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ }
+
+ public List<File> list(File[] files) {
+ List<File> newList = new ArrayList<File>();
+ for(File file : files) {
+ newList.add(file);
+ }
+ return newList;
+ }
+
+ private void showDialog(final int position) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ builder.setTitle(listFiles.get(position).getName());
+ builder.setItems(R.array.install_image_dialog, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ switch(which) {
+ case 0:
+ installBoot(listFiles.get(position).getAbsolutePath());
+ break;
+ case 1:
+ installRecovery(listFiles.get(position).getAbsolutePath());
+ break;
+ }
+ }
+ });
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ }
+
+ public void installBoot(String bootPath) {
+ CommandCapture cmd = new CommandCapture(0,"dd if="+bootPath+" of=/dev/block/platform/msm_sdcc.1/by-name/boot", "reboot");
+ try {
+ RootTools.getShell(true).add(cmd);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void installRecovery(String recoveryPath) {
+ CommandCapture cmd = new CommandCapture(0,"dd if="+recoveryPath+" of=/dev/block/platform/msm_sdcc.1/by-name/recovery", "reboot");
+ try {
+ RootTools.getShell(true).add(cmd);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/CpuGovernorPreferenceFragment.java b/src/com/dsht/kerneltweaker/fragments/CpuGovernorPreferenceFragment.java
new file mode 100644
index 0000000..9300bb0
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/CpuGovernorPreferenceFragment.java
@@ -0,0 +1,250 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.glossary.ConservativeGlossaryFragment;
+import com.dsht.glossary.CpuGlossaryFragment;
+import com.dsht.glossary.InteractiveGlossaryFragment;
+import com.dsht.glossary.OndemandGlossaryFragment;
+import com.dsht.kerneltweaker.CustomPreference;
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.ListViewMultiChoiceModeListener;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.text.InputType;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+
+public class CpuGovernorPreferenceFragment extends PreferenceFragment {
+
+ private static PreferenceCategory mCategory;
+ private static Context mContext;
+ private static final String category = "governor";
+ private PreferenceScreen mRoot;
+ private static DatabaseHandler db = MainActivity.db;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.pref_screen_governor);
+ mRoot = (PreferenceScreen) findPreference("key_root");
+ mCategory = (PreferenceCategory) findPreference("key_gov_category");
+ mContext = getActivity();
+ setRetainInstance(true);
+
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list, container,false);
+ String curGov = Helpers.getCurrentGovernor();
+ ListView listView = (ListView) v.findViewById(android.R.id.list);
+
+/* listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ registerForContextMenu(listView);
+ listView.setMultiChoiceModeListener(new ListViewMultiChoiceModeListener(
+ mContext,getActivity(),
+ listView,mRoot,
+ false,
+ db,
+ MainActivity.vddDb));
+*/
+ File f = new File("/sys/devices/system/cpu/cpufreq/"+curGov);
+ if(f.exists()) {
+ MainActivity.menu.setEnabled(false);
+ mCategory.setTitle(curGov + " Tweakable values");
+ addPreferences();
+
+ if(curGov.equalsIgnoreCase("ondemand")||
+ curGov.equalsIgnoreCase("interactive") ||
+ curGov.equalsIgnoreCase("conservative")) {
+ Fragment glo = null;
+ if(curGov.equalsIgnoreCase("ondemand")) {
+ glo = new OndemandGlossaryFragment();
+ }else if( curGov.equalsIgnoreCase("interactive")) {
+ glo = new InteractiveGlossaryFragment();
+ }else if( curGov.equalsIgnoreCase("conservative")) {
+ glo = new ConservativeGlossaryFragment();
+ }
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ // This adds the newly created Preference fragment to my main layout, shown below
+ ft.replace(R.id.menu_frame, glo);
+ // By hiding the main fragment, transparency isn't an issue
+ ft.addToBackStack("TAG");
+ ft.commit();
+ }
+ }
+ else {
+ CustomPreference pref = new CustomPreference(mContext, true, category);
+ pref.setTitle("No tweakable values");
+ pref.setSummary(curGov + " Doesn\'t have tweakable values");
+ pref.setTitleColor("#ff4444");
+ pref.setSummaryColor("#ff4444");
+ mCategory.addPreference(pref);
+ }
+
+
+
+ return v;
+ }
+
+ public static void addPreferences() {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+ if(mCategory.getPreferenceCount() != 0) {
+ mCategory.removeAll();
+ }
+ String currentGovernor = Helpers.getCurrentGovernor();
+ File f = new File("/sys/devices/system/cpu/cpufreq/"+currentGovernor);
+ if(f.exists()) {
+ File[] files = f.listFiles();
+ for(File file : files) {
+ String fileName = file.getName();
+ String filePath = file.getAbsolutePath();
+ Helpers.runRootCommand("chmod 655 "+file.getAbsolutePath());
+ final String fileContent = Helpers.readFileViaShell(filePath, false).trim().replaceAll("\n", "");
+ CustomPreference pref = new CustomPreference(mContext,true,category);
+ pref.setTitle(fileName);
+ String color = "#ff0099cc";
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#ff0099cc"));
+ color = "#"+Integer.toHexString(col);
+ pref.setTitleColor(color);
+ }else {
+ pref.setTitleColor(color);
+ }
+ pref.setSummary(fileContent);
+ pref.setKey(filePath);
+ Log.d("CONTENT", fileContent);
+ mCategory.addPreference(pref);
+ pref.setOnPreferenceClickListener(new OnPreferenceClickListener(){
+
+ @Override
+ public boolean onPreferenceClick(final Preference p) {
+ // TODO Auto-generated method stub
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LinearLayout ll = new LinearLayout(mContext);
+ ll.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
+ final EditText et = new EditText(mContext);
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ params.setMargins(40, 40, 40, 40);
+ params.gravity = Gravity.CENTER;
+ String val = p.getSummary().toString();
+ et.setLayoutParams(params);
+ et.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+ et.setGravity(Gravity.CENTER_HORIZONTAL);
+ et.setText(val);
+ ll.addView(et);
+ builder.setView(ll);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ String value = et.getText().toString();
+ p.setSummary(value);
+ Log.d("TEST", "echo "+value+" > "+ p.getKey());
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+p.getKey());
+ try {
+ RootTools.getShell(true).add(command);
+ updateListDb(p,value);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ } );
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ return true;
+ }
+
+ });
+ }
+ }
+
+ return "Executed";
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+
+ @Override
+ protected void onPreExecute() {}
+
+ }
+ new LongOperation().execute();
+ }
+
+ private static void updateListDb(final Preference p, final String value) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+ }
+ new LongOperation().execute();
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/CpuPreferenceFragment.java b/src/com/dsht/kerneltweaker/fragments/CpuPreferenceFragment.java
new file mode 100644
index 0000000..842ddb9
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/CpuPreferenceFragment.java
@@ -0,0 +1,409 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.CustomListPreference;
+import com.dsht.kerneltweaker.CustomPreference;
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.ListViewMultiChoiceModeListener;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+import android.text.InputType;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.EditText;
+import android.widget.ListView;
+
+public class CpuPreferenceFragment extends PreferenceFragment implements OnPreferenceChangeListener, OnPreferenceClickListener {
+ private Context mContext;
+ private SharedPreferences mPrefs;
+ private CustomListPreference mCpuMaxFreq;
+ private CustomListPreference mCpuMinFreq;
+ private CustomListPreference mCpuGovernor;
+ private CustomPreference mAdvancedGovernor;
+ private PreferenceCategory mHotPlugCategory;
+ private CustomListPreference mCpuquiet;
+ private CustomPreference mAdvancedCpuquiet;
+ private PreferenceCategory mAdvancedCategory;
+ private PreferenceScreen mRoot;
+ private static final String MAX_FREQ_FILE = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq";
+ private static final String GOVERNOR_FILE = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor";
+ private static final String MIN_FREQ_FILE = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq";
+ private static final String HOTPLUG_FILE ="/sys/devices/virtual/misc/mako_hotplug_control/";
+ private static final String CPUQUIET_DIR = "/sys/devices/system/cpu/cpuquiet";
+ private static final String CPUQUIET_FILE = "/sys/devices/system/cpu/cpuquiet/current_governor";
+ private static final String CPUQUIET_GOVERNORS = "/sys/devices/system/cpu/cpuquiet/available_governors";
+ private static final String category = "cpu";
+ private DatabaseHandler db = MainActivity.db;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.pref_screen_cpu);
+ mContext = getActivity();
+
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle();
+ }
+ RootTools.isRootAvailable();
+
+ Helpers.setPermissions(MAX_FREQ_FILE);
+ Helpers.setPermissions(MIN_FREQ_FILE);
+ Helpers.setPermissions(GOVERNOR_FILE);
+ Helpers.setPermissions(HOTPLUG_FILE);
+ Helpers.setPermissions(CPUQUIET_FILE);
+ Helpers.setPermissions(CPUQUIET_DIR);
+ Helpers.setPermissions(CPUQUIET_GOVERNORS);
+
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ mRoot = (PreferenceScreen) findPreference("key_root");
+ mHotPlugCategory = (PreferenceCategory) findPreference("key_hotplug_category");
+ mCpuMaxFreq = (CustomListPreference) findPreference("key_cpu_max");
+ mCpuMinFreq = (CustomListPreference) findPreference("key_cpu_min");
+ mCpuGovernor = (CustomListPreference) findPreference("key_cpu_governor");
+ mAdvancedGovernor = (CustomPreference) findPreference("key_advanced_governor");
+ mAdvancedCpuquiet = (CustomPreference) findPreference("key_advanced_cpuquiet");
+ mCpuquiet = (CustomListPreference) findPreference("key_cpuquiet");
+ mAdvancedCategory = (PreferenceCategory) findPreference("key_advanced");
+ mAdvancedGovernor.setOnPreferenceClickListener(this);
+ mAdvancedCpuquiet.setOnPreferenceClickListener(this);
+
+ if(!new File(CPUQUIET_DIR).exists()) {
+ mAdvancedCategory.removePreference(mAdvancedCpuquiet);
+ }
+
+ String color = "";
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ color = "#"+Integer.toHexString(col);
+ }else if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_CPU, Color.parseColor("#ff0099cc"));
+ color = "#"+Integer.toHexString(col);
+ }
+ else {
+ String col = mContext.getResources().getStringArray(R.array.menu_colors)[2];
+ color = col;
+ }
+ mCpuMaxFreq.setTitleColor(color);
+ mCpuMinFreq.setTitleColor(color);
+ mCpuGovernor.setTitleColor(color);
+ mAdvancedGovernor.setTitleColor(color);
+ mCpuquiet.setTitleColor(color);
+ mAdvancedCpuquiet.setTitleColor(color);
+
+ mCpuMaxFreq.setCategory(category);
+ mCpuMinFreq.setCategory(category);
+ mCpuGovernor.setCategory(category);
+ mCpuquiet.setCategory(category);
+
+ mCpuMaxFreq.setKey(MAX_FREQ_FILE);
+ mCpuMinFreq.setKey(MIN_FREQ_FILE);
+ mCpuGovernor.setKey(GOVERNOR_FILE);
+ mCpuquiet.setKey(CPUQUIET_FILE);
+
+
+ String[] frequencies = Helpers.getFrequencies();
+ String[] governors = Helpers.getGovernors();
+ String[] names = Helpers.getFrequenciesNames();
+
+ mCpuMaxFreq.setEntries(names);
+ mCpuMaxFreq.setEntryValues(frequencies);
+ mCpuMinFreq.setEntries(names);
+ mCpuMinFreq.setEntryValues(frequencies);
+ mCpuGovernor.setEntries(governors);
+ mCpuGovernor.setEntryValues(governors);
+
+ if(new File(CPUQUIET_DIR).exists()) {
+ String cpuquiet = Helpers.getFileContent(new File(CPUQUIET_GOVERNORS));
+ String[] cpuquiet_govs = cpuquiet.trim().replaceAll("\n", "").split(" ");
+ String currQuiet = Helpers.getFileContent(new File(CPUQUIET_FILE)).trim().replace("\n", "");
+ mCpuquiet.setSummary(currQuiet);
+ mCpuquiet.setEntries(cpuquiet_govs);
+ mCpuquiet.setEntryValues(cpuquiet_govs);
+ mCpuquiet.setValue(currQuiet);
+
+ } else {
+ mHotPlugCategory.removePreference(mCpuquiet);
+ }
+
+
+ if(new File(MAX_FREQ_FILE).exists()) {
+ mCpuMaxFreq.setSummary(Helpers.readOneLine(MAX_FREQ_FILE));
+ mCpuMaxFreq.setValue(mCpuMaxFreq.getSummary().toString());
+ }
+ if(new File(MIN_FREQ_FILE).exists()) {
+ mCpuMinFreq.setSummary(Helpers.readOneLine(MIN_FREQ_FILE));
+ mCpuMinFreq.setValue(mCpuMinFreq.getSummary().toString());
+ }
+ if(new File(GOVERNOR_FILE).exists()) {
+ Helpers.runRootCommand("chmod 655 /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
+ mCpuGovernor.setSummary(Helpers.getCurrentGovernor());
+ mCpuGovernor.setValue(mCpuGovernor.getSummary().toString());
+ }
+
+ mCpuMaxFreq.setOnPreferenceChangeListener(this);
+ mCpuMinFreq.setOnPreferenceChangeListener(this);
+ mCpuGovernor.setOnPreferenceChangeListener(this);
+ mAdvancedGovernor.excludeFromDialog(true);
+ mCpuquiet.setOnPreferenceChangeListener(this);
+
+ if(new File(HOTPLUG_FILE).exists()) {
+ createPreference(mHotPlugCategory,new File(HOTPLUG_FILE+"cores_on_touch"), color );
+ createPreference(mHotPlugCategory,new File(HOTPLUG_FILE+"first_level"), color );
+ }
+
+ if(mHotPlugCategory.getPreferenceCount() == 0) {
+ mRoot.removePreference(mHotPlugCategory);
+ }
+
+ mAdvancedCpuquiet.hideBoot(true);
+ mAdvancedGovernor.hideBoot(true);
+ setRetainInstance(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list, container,false);
+
+/* ListView listView = (ListView) v.findViewById(android.R.id.list);
+
+ listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ registerForContextMenu(listView);
+ listView.setMultiChoiceModeListener(new ListViewMultiChoiceModeListener(
+ mContext,getActivity(),
+ listView,mRoot,
+ false,
+ db,
+ MainActivity.vddDb));
+*/
+ return v;
+ }
+
+
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object newValue) {
+ // TODO Auto-generated method stub
+ if(pref == mCpuMaxFreq) {
+ String value = (String) newValue;
+ mCpuMaxFreq.setSummary(value);
+ mCpuMaxFreq.setValue(value);
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+MAX_FREQ_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+ updateListDb(pref, value);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ if(pref == mCpuMinFreq) {
+ String value = (String) newValue;
+ mCpuMinFreq.setSummary(value);
+ mCpuMinFreq.setValue(value);
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+MIN_FREQ_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+ updateListDb(pref, value);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ if(pref == mCpuGovernor) {
+ String value = ((String)newValue).trim().replaceAll(" ", "").replaceAll("\n", "");
+ mCpuGovernor.setSummary(value);
+ mCpuGovernor.setValue(value);
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+GOVERNOR_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+ updateListDb(pref, value);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+ if(pref == mCpuquiet) {
+ String value = (String) newValue;
+ mCpuquiet.setSummary(value);
+ mCpuquiet.setValue(value);
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+CPUQUIET_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+ updateListDb(pref, value);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference pref) {
+ // TODO Auto-generated method stub
+ Fragment f = null;
+ if(pref == mAdvancedGovernor) {
+ f = new CpuGovernorPreferenceFragment();
+ }
+ if(pref == mAdvancedCpuquiet) {
+ f = new CpuquietGovernorPreferenceFragment();
+ }
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ // This adds the newly created Preference fragment to my main layout, shown below
+ ft.replace(R.id.activity_container,f);
+ // By hiding the main fragment, transparency isn't an issue
+ ft.addToBackStack("TAG");
+ ft.commit();
+
+
+ return false;
+ }
+
+
+ private void createPreference(PreferenceCategory mCategory, File file, String color) {
+ String fileName = file.getName();
+ String filePath = file.getAbsolutePath();
+ final String fileContent = Helpers.getFileContent(file);
+ final CustomPreference pref = new CustomPreference(mContext, false, category);
+ pref.setTitle(fileName);
+ pref.setTitleColor(color);
+ pref.setSummary(fileContent);
+ pref.setKey(filePath);
+ Log.d("CONTENT", fileContent);
+ mCategory.addPreference(pref);
+ pref.setOnPreferenceClickListener(new OnPreferenceClickListener(){
+
+ @Override
+ public boolean onPreferenceClick(final Preference p) {
+ // TODO Auto-generated method stub
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View v = inflater.inflate(R.layout.dialog_layout, null, false);
+ final EditText et = (EditText) v.findViewById(R.id.et);
+ String val = p.getSummary().toString();
+ et.setText(val);
+ et.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+ et.setGravity(Gravity.CENTER_HORIZONTAL);
+ builder.setView(v);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ String value = et.getText().toString();
+ p.setSummary(value);
+ Log.d("TEST", "echo "+value+" > "+ p.getKey());
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+p.getKey());
+ try {
+ RootTools.getShell(true).add(command);
+ updateListDb(pref, value);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ } );
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ return true;
+ }
+
+ });
+ }
+
+ private void updateListDb(final Preference p, final String value) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+ }
+ new LongOperation().execute();
+ }
+
+
+
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/CpuSchedulerPreferenceFragment.java b/src/com/dsht/kerneltweaker/fragments/CpuSchedulerPreferenceFragment.java
new file mode 100644
index 0000000..691ba0c
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/CpuSchedulerPreferenceFragment.java
@@ -0,0 +1,216 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.CustomPreference;
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.ListViewMultiChoiceModeListener;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.text.InputType;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+
+public class CpuSchedulerPreferenceFragment extends PreferenceFragment {
+
+ private static PreferenceCategory mCategory;
+ private static Context mContext;
+ private PreferenceScreen mRoot;
+ private static String category = "scheduler";
+ private static DatabaseHandler db = MainActivity.db;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.pref_screen_scheduler);
+ mRoot = (PreferenceScreen) findPreference("key_root");
+ mCategory = (PreferenceCategory) findPreference("key_sched_category");
+ mContext = getActivity();
+ setRetainInstance(true);
+
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list, container,false);
+ ListView listView = (ListView) v.findViewById(android.R.id.list);
+
+/* listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ registerForContextMenu(listView);
+ listView.setMultiChoiceModeListener(new ListViewMultiChoiceModeListener(
+ mContext,getActivity(),
+ listView,mRoot,
+ false,
+ MainActivity.db,
+ MainActivity.vddDb));
+*/
+ File f = new File("/sys/block/mmcblk0/queue/iosched");
+ String curSched = Helpers.getCurrentScheduler();
+ File[] files = f.listFiles();
+ if(files.length != 0) {
+ MainActivity.menu.setEnabled(false);
+ addPreferences();
+ mCategory.setTitle(curSched + " Tweakable values");
+ }else {
+ Preference pref = new Preference(mContext);
+ pref.setTitle("No tweakable values");
+ pref.setSummary(curSched + " Doesn\'t have tweakable values");
+ mCategory.addPreference(pref);
+ }
+
+ return v;
+ }
+
+ public static void addPreferences() {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+ if(mCategory.getPreferenceCount() != 0) {
+ mCategory.removeAll();
+ }
+
+ File f = new File("/sys/block/mmcblk0/queue/iosched");
+ File[] files = f.listFiles();
+ for(File file : files) {
+ String fileName = file.getName();
+ String filePath = file.getAbsolutePath();
+ final String fileContent = Helpers.getFileContent(file);
+ CustomPreference pref = new CustomPreference(mContext, true, category);
+ pref.setTitle(fileName);
+ String color = "#ff0099cc";
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#ff0099cc"));
+ color = "#"+Integer.toHexString(col);
+ pref.setTitleColor(color);
+ }else {
+ pref.setTitleColor(color);
+ }
+ pref.setSummary(fileContent);
+ pref.setKey(filePath);
+ mCategory.addPreference(pref);
+ pref.setOnPreferenceClickListener(new OnPreferenceClickListener(){
+
+ @Override
+ public boolean onPreferenceClick(final Preference p) {
+ // TODO Auto-generated method stub
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LinearLayout ll = new LinearLayout(mContext);
+ ll.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
+ final EditText et = new EditText(mContext);
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ params.setMargins(40, 40, 40, 40);
+ params.gravity = Gravity.CENTER;
+ String val = p.getSummary().toString();
+ et.setLayoutParams(params);
+ et.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+ et.setGravity(Gravity.CENTER_HORIZONTAL);
+ et.setText(val);
+ ll.addView(et);
+ builder.setView(ll);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ String value = et.getText().toString();
+ p.setSummary(value);
+ //Log.d("TEST", "echo "+value+" > "+ p.getKey());
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+p.getKey());
+ try {
+ RootTools.getShell(true).add(command);
+ updateListDb(p, value);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ } );
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ return true;
+ }
+
+ });
+ }
+
+ return "Executed";
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+
+ @Override
+ protected void onPreExecute() {}
+
+ }
+ new LongOperation().execute();
+ }
+
+ private static void updateListDb(final Preference p, final String value) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+ }
+ new LongOperation().execute();
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/CpuquietGovernorPreferenceFragment.java b/src/com/dsht/kerneltweaker/fragments/CpuquietGovernorPreferenceFragment.java
new file mode 100644
index 0000000..0038669
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/CpuquietGovernorPreferenceFragment.java
@@ -0,0 +1,223 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.CustomPreference;
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.ListViewMultiChoiceModeListener;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.text.InputType;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+
+public class CpuquietGovernorPreferenceFragment extends PreferenceFragment {
+
+ private static PreferenceCategory mCategory;
+ private static Context mContext;
+ private static final String CPUQUIET_FILE = "/sys/devices/system/cpu/cpuquiet/current_governor";
+ private static final String category = "cpuquiet";
+ private PreferenceScreen mRoot;
+ private static DatabaseHandler db = MainActivity.db;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.pref_screen_governor);
+ mCategory = (PreferenceCategory) findPreference("key_gov_category");
+ mRoot = (PreferenceScreen) findPreference("key_root");
+ mContext = getActivity();
+ setRetainInstance(true);
+
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list, container,false);
+ ListView listView = (ListView) v.findViewById(android.R.id.list);
+
+/* listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ registerForContextMenu(listView);
+ listView.setMultiChoiceModeListener(new ListViewMultiChoiceModeListener(
+ mContext,getActivity(),
+ listView,mRoot,
+ false,
+ MainActivity.db,
+ MainActivity.vddDb));
+*/
+ String curGov = Helpers.getFileContent(new File(CPUQUIET_FILE)).trim().replaceAll("\n", "");
+ if(curGov.equals("runnable")) {
+ curGov +="_threads";
+ }
+ File f = new File("/sys/devices/system/cpu/cpuquiet/"+curGov);
+ if(f.exists()) {
+ MainActivity.menu.setEnabled(false);
+ mCategory.setTitle(curGov + " Tweakable values");
+ addPreferences();
+ }
+ else {
+ CustomPreference pref = new CustomPreference(mContext, true, category);
+ pref.setTitle("No tweakable values");
+ pref.setSummary(curGov + " Doesn\'t have tweakable values");
+ pref.setTitleColor("#ff4444");
+ pref.setSummaryColor("#ff4444");
+ mCategory.addPreference(pref);
+ }
+
+ return v;
+ }
+
+ public static void addPreferences() {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+ if(mCategory.getPreferenceCount() != 0) {
+ mCategory.removeAll();
+ }
+ String currentGovernor = Helpers.readFileViaShell(CPUQUIET_FILE, true).split("\n")[0];
+ File f = new File("/sys/devices/system/cpu/cpuquiet/"+currentGovernor);
+ if(f.exists()) {
+ File[] files = f.listFiles();
+ for(File file : files) {
+ String fileName = file.getName();
+ String filePath = file.getAbsolutePath();
+ final String fileContent = Helpers.getFileContent(file);
+ CustomPreference pref = new CustomPreference(mContext,true,category);
+ pref.setTitle(fileName);
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#ff0099cc"));
+ String color = "#"+Integer.toHexString(col);
+ pref.setTitleColor(color);
+ }
+ pref.setSummary(fileContent);
+ pref.setKey(filePath);
+ Log.d("CONTENT", fileContent);
+ mCategory.addPreference(pref);
+ pref.setOnPreferenceClickListener(new OnPreferenceClickListener(){
+
+ @Override
+ public boolean onPreferenceClick(final Preference p) {
+ // TODO Auto-generated method stub
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LinearLayout ll = new LinearLayout(mContext);
+ ll.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
+ final EditText et = new EditText(mContext);
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ params.setMargins(40, 40, 40, 40);
+ params.gravity = Gravity.CENTER;
+ String val = p.getSummary().toString();
+ et.setLayoutParams(params);
+ et.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+ et.setGravity(Gravity.CENTER_HORIZONTAL);
+ et.setText(val);
+ ll.addView(et);
+ builder.setView(ll);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ String value = et.getText().toString();
+ p.setSummary(value);
+ Log.d("TEST", "echo "+value+" > "+ p.getKey());
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+p.getKey());
+ try {
+ RootTools.getShell(true).add(command);
+ updateListDb(p, value);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ } );
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ return true;
+ }
+
+ });
+ }
+ }
+
+ return "Executed";
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+
+ @Override
+ protected void onPreExecute() {}
+
+ }
+ new LongOperation().execute();
+ }
+
+ private static void updateListDb(final Preference p, final String value) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+ }
+ new LongOperation().execute();
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/CustomRecoveryCommandFragment.java b/src/com/dsht/kerneltweaker/fragments/CustomRecoveryCommandFragment.java
new file mode 100644
index 0000000..568d57e
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/CustomRecoveryCommandFragment.java
@@ -0,0 +1,477 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.RecoveryBaseAdapter;
+import com.mobeta.android.dslv.DragSortController;
+import com.mobeta.android.dslv.DragSortListView;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.EditText;
+
+public class CustomRecoveryCommandFragment extends Fragment implements OnClickListener, OnCheckedChangeListener {
+
+ private Context mContext;
+ private DragSortListView mList;
+ private ArrayList<String> list;
+ //private ArrayAdapter<String> adapter;
+ private String[] dialogEntries = {"Wipe Cache","Wipe Dalvik","Wipe Data/Factory reset","Install package", "Nandroid Backup"};
+ private String[] dialogValues = {"wipe cache", "wipe dalvik", "wipe data"};
+ private ArrayList<String> names;
+ private ArrayList<String> values;
+ private static final String COMMAND_FILE = "/cache/recovery/openrecoveryscript";
+ private RecoveryBaseAdapter mAdapter;
+ private static final int READ_REQUEST_CODE = 42;
+ private Button mReboot;
+ private Button mCancel;
+ private ArrayList<String> backupString;
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ mContext = getActivity();
+
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle(true);
+ }
+ setRetainInstance(true);
+
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.dragsort_list, container,false);
+ mList = (DragSortListView) v.findViewById(R.id.dslist);
+ mReboot = (Button) v.findViewById(R.id.reboot);
+ mCancel = (Button) v.findViewById(R.id.cancel);
+ mReboot.setOnClickListener(this);
+ mCancel.setOnClickListener(this);
+ mList.setEmptyView(v.findViewById(R.id.empty));
+ list = new ArrayList<String>();
+ names = new ArrayList<String>();
+ values = new ArrayList<String>();
+ backupString = new ArrayList<String>();
+
+ for(int i=0; i<10; i++) {
+ list.add("TEST "+i);
+ }
+
+ mAdapter = new RecoveryBaseAdapter(mContext, names, values);
+
+ mList.setAdapter(mAdapter);
+ mList.setDropListener(onDrop);
+ mList.setRemoveListener(onRemove);
+
+ DragSortController controller = new DragSortController(mList);
+ controller.setDragHandleId(R.id.image);
+ //controller.setClickRemoveId(R.id.);
+ controller.setRemoveEnabled(true);
+ controller.setSortEnabled(true);
+ controller.setDragInitMode(1);
+ controller.setFlingHandleId(R.id.item_container);
+ //controller.setRemoveMode(removeMode);
+
+ mList.setFloatViewManager(controller);
+ mList.setOnTouchListener(controller);
+ mList.setDragEnabled(true);
+ checkEmptyList();
+ return v;
+ }
+
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.menu_recovery, menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_plus:
+ showDialog();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode,
+ Intent resultData) {
+ if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
+ Uri uri = null;
+ if (resultData != null) {
+ uri = resultData.getData();
+ String path = uri.getPath();
+ if(path.endsWith(".zip")) {
+ names.add(dialogEntries[3]);
+ values.add("install "+path);
+ mAdapter.notifyDataSetChanged();
+ buildFile();
+ checkEmptyList();
+ } else {
+ notZip();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ // TODO Auto-generated method stub
+ switch(v.getId()) {
+ case R.id.cancel:
+ onCancelPressed();
+ break;
+ case R.id.reboot:
+ onRebootPressed();
+ break;
+ }
+ }
+
+ private DragSortListView.DropListener onDrop = new DragSortListView.DropListener()
+ {
+ @Override
+ public void drop(int from, int to)
+ {
+ if (from != to)
+ {
+ String nameItem = mAdapter.getNameItem(from);
+ String valueItem = mAdapter.getValueItem(from);
+ mAdapter.remove(nameItem, valueItem);
+ mAdapter.insert(nameItem, valueItem, to, to);
+ buildFile();
+ }
+ }
+ };
+
+ private DragSortListView.RemoveListener onRemove = new DragSortListView.RemoveListener()
+ {
+ @Override
+ public void remove(int which)
+ {
+ String nameItem = mAdapter.getNameItem(which);
+ String valueItem = mAdapter.getValueItem(which);
+ mAdapter.remove(nameItem, valueItem);
+ buildFile();
+ if(names.size() == 0) {
+ removeFile();
+ checkEmptyList();
+ }
+ }
+ };
+
+
+ private void showDialog() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ builder.setTitle("Add action");
+ builder.setItems(dialogEntries, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ switch(which) {
+ case 0:
+ addCommand(0);
+ break;
+ case 1:
+ addCommand(1);
+ break;
+ case 2:
+ addCommand(2);
+ break;
+ case 3:
+ performFileSearch();
+ break;
+ case 4:
+ backupDialog();
+ break;
+ }
+ }
+ });
+ builder.create().show();
+ }
+
+
+ private void addCommand(int position) {
+
+ names.add(dialogEntries[position]);
+ values.add(dialogValues[position]);
+ mAdapter.notifyDataSetChanged();
+ buildFile();
+ checkEmptyList();
+ }
+
+ private boolean alreadyAdded(int position) {
+ if(names.contains(dialogEntries[position])) {
+ return true;
+ }
+ return false;
+ }
+
+ private void buildFile() {
+ removeFile();
+ for(String str : values) {
+ CommandCapture command = new CommandCapture(0, "echo \"" + str + "\" >> "+ COMMAND_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void removeFile() {
+ CommandCapture command = new CommandCapture(0, "rm -f "+COMMAND_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void performFileSearch() {
+
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.setType("file/*");
+ startActivityForResult(intent, READ_REQUEST_CODE);
+ }
+
+ private void checkEmptyList() {
+ if(names.size() == 0) {
+ mReboot.setEnabled(false);
+ mCancel.setEnabled(false);
+ } else {
+ mReboot.setEnabled(true);
+ mCancel.setEnabled(true);
+ }
+ }
+
+ private void onCancelPressed() {
+ values.clear();
+ names.clear();
+ removeFile();
+ mAdapter.notifyDataSetChanged();
+ checkEmptyList();
+ }
+
+ private void onRebootPressed() {
+ CommandCapture command = new CommandCapture(0, "reboot recovery");
+ try {
+ RootTools.getShell(true).add(command);
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+
+ private void notZip() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ builder.setMessage("Selected File is not a Zip!!");
+ builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int arg1) {
+ // TODO Auto-generated method stub
+ dialog.cancel();
+ }
+ });
+ builder.create().show();
+ }
+
+ private String buildBackupString() {
+ String composed = "backup ";
+ for(String str : backupString) {
+ composed +=str;
+ }
+ return composed;
+ }
+
+ private void backupDialog() {
+ backupString.clear();
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View v = inflater.inflate(R.layout.backup_dialog_layout, null, false);
+ final CheckBox mSystem = (CheckBox) v.findViewById(R.id.cb_system);
+ final CheckBox mData = (CheckBox) v.findViewById(R.id.cb_data);
+ final CheckBox mCache = (CheckBox) v.findViewById(R.id.cb_cache);
+ final CheckBox mBoot = (CheckBox) v.findViewById(R.id.cb_boot);
+ final CheckBox mRecovery = (CheckBox) v.findViewById(R.id.cb_recovery);
+ final CheckBox mMd5 = (CheckBox) v.findViewById(R.id.cb_md5);
+ final CheckBox mSecure = (CheckBox) v.findViewById(R.id.cb_secure);
+ final CheckBox mCompression = (CheckBox) v.findViewById(R.id.cb_compression);
+ final EditText mName = (EditText) v.findViewById(R.id.et_name);
+ mName.setHint(Build.DISPLAY);
+ mSystem.setOnCheckedChangeListener(this);
+ mData.setOnCheckedChangeListener(this);
+ mCache.setOnCheckedChangeListener(this);
+ mBoot.setOnCheckedChangeListener(this);
+ mRecovery.setOnCheckedChangeListener(this);
+ mMd5.setOnCheckedChangeListener(this);
+ mSecure.setOnCheckedChangeListener(this);
+ mCompression.setOnCheckedChangeListener(this);
+ builder.setView(v);
+ builder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int arg1) {
+ // TODO Auto-generated method stub
+ String name = "";
+ if(mName.getText().toString().equals("")) {
+ name = Build.DISPLAY;
+ }else {
+ name = mName.getText().toString();
+ }
+ String command = buildBackupString() + " "+name;
+ names.add(dialogEntries[4]);
+ values.add(command);
+ mAdapter.notifyDataSetChanged();
+ buildFile();
+ checkEmptyList();
+
+ }
+ })
+ .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ builder.create().show();
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
+ // TODO Auto-generated method stub
+ switch(arg0.getId()) {
+ case R.id.cb_system:
+ if(isChecked) {
+ backupString.add("S");
+ }else {
+ if(backupString.contains("S")) {
+ backupString.remove("S");
+ }
+ }
+ break;
+ case R.id.cb_data:
+ if(isChecked) {
+ backupString.add("D");
+ }else {
+ if(backupString.contains("D")) {
+ backupString.remove("D");
+ }
+ }
+ break;
+ case R.id.cb_cache:
+ if(isChecked) {
+ backupString.add("C");
+ }else {
+ if(backupString.contains("C")) {
+ backupString.remove("C");
+ }
+ }
+ break;
+ case R.id.cb_boot:
+ if(isChecked) {
+ backupString.add("B");
+ }else {
+ if(backupString.contains("B")) {
+ backupString.remove("B");
+ }
+ }
+ break;
+ case R.id.cb_recovery:
+ if(isChecked) {
+ backupString.add("R");
+ }else {
+ if(backupString.contains("R")) {
+ backupString.remove("R");
+ }
+ }
+ break;
+ case R.id.cb_md5:
+ if(isChecked) {
+ backupString.add("M");
+ }else {
+ if(backupString.contains("M")) {
+ backupString.remove("M");
+ }
+ }
+ break;
+ case R.id.cb_secure:
+ if(isChecked) {
+ backupString.add("A");
+ }else {
+ if(backupString.contains("A")) {
+ backupString.remove("A");
+ }
+ }
+ break;
+ case R.id.cb_compression:
+ if(isChecked) {
+ backupString.add("O");
+ }else {
+ if(backupString.contains("O")) {
+ backupString.remove("O");
+ }
+ }
+ break;
+ }
+
+ }
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/DialogCreatable.java b/src/com/dsht/kerneltweaker/fragments/DialogCreatable.java
new file mode 100644
index 0000000..a46e34e
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/DialogCreatable.java
@@ -0,0 +1,29 @@
+package com.dsht.kerneltweaker.fragments;
+
+/*
+ * Copyright (C) 2010 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.
+ */
+
+import android.app.Dialog;
+
+/**
+ * Letting the class, assumed to be Fragment, create a Dialog on it. Should be useful
+ * you want to utilize some capability in {@link SettingsPreferenceFragment} but don't want
+ * the class inherit the class itself (See {@link ProxySelector} for example).
+ */
+public interface DialogCreatable {
+
+ public Dialog onCreateDialog(int dialogId);
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/FileManagerFragment.java b/src/com/dsht/kerneltweaker/fragments/FileManagerFragment.java
new file mode 100644
index 0000000..d6615a4
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/FileManagerFragment.java
@@ -0,0 +1,203 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.FileBaseAdapter;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class FileManagerFragment extends Fragment implements OnItemClickListener{
+
+ private ListView mList;
+ private FileBaseAdapter mAdapter;
+ private Context mContext;
+ private String SdPath;
+ private File[] filesList;
+ private static File RECOVERY_DIR = new File("/cache/recovery");
+ private static File COMMAND_FILE = new File(RECOVERY_DIR, "command");
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ SdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
+
+ Bundle bundle = this.getArguments();
+ if(bundle != null) {
+ String fPath = bundle.getString("FILEPATH","none");
+ if(fPath.equals("none")) {
+ filesList = new File(SdPath).listFiles();
+ } else {
+ filesList = new File(fPath).listFiles();
+ }
+ }else {
+ filesList = new File(SdPath).listFiles();
+ }
+ Arrays.sort(filesList);
+
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle(true);
+ }
+ setRetainInstance(true);
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list_file, container,false);
+ mList = (ListView) v.findViewById(R.id.list);
+ TextView emptyView = (TextView) v.findViewById(R.id.empty);
+ mAdapter = new FileBaseAdapter(mContext, filesList);
+ mList.setAdapter(mAdapter);
+ mList.setEmptyView(emptyView);
+ mList.setOnItemClickListener(this);
+ return v;
+ }
+
+
+ @Override
+ public void onItemClick(AdapterView<?> arg0, View parent, final int position, long id) {
+ // TODO Auto-generated method stub
+ if(filesList[position].isDirectory()) {
+ File[] childs = filesList[position].listFiles();
+ Arrays.sort(childs);
+ Fragment fragment = new FileManagerFragment();
+ Bundle bundle = new Bundle();
+ bundle.putString("FILEPATH", filesList[position].getAbsolutePath());
+ fragment.setArguments(bundle);
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ // This adds the newly created Preference fragment to my main layout, shown below
+ ft.replace(R.id.activity_container,fragment);
+ // By hiding the main fragment, transparency isn't an issue
+ ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
+ ft.addToBackStack("TAG");
+ ft.commit();
+ }else if(filesList[position].getName().endsWith(".apk")) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setDataAndType(Uri.fromFile(filesList[position]), "application/vnd.android.package-archive");
+ startActivity(intent);
+ }else if(filesList[position].getName().endsWith(".zip")) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ builder.setTitle(filesList[position].getName());
+ builder.setItems(R.array.flash_dialog, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ bootCommand("--update_package="+filesList[position].getAbsolutePath());
+ }
+ });
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+
+ }else if(filesList[position].getName().endsWith(".img")) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ builder.setTitle(filesList[position].getName());
+ builder.setItems(R.array.install_image_dialog, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ switch(which) {
+ case 0:
+ installBoot(filesList[position].getAbsolutePath());
+ break;
+ case 1:
+ installRecovery(filesList[position].getAbsolutePath());
+ break;
+ }
+ }
+ });
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ }
+ }
+
+
+ public void bootCommand(String command) {
+ if(!RECOVERY_DIR.exists()) {
+ RECOVERY_DIR.mkdirs();
+ }
+ if(COMMAND_FILE.exists()) {
+ COMMAND_FILE.delete();
+ }
+ CommandCapture cmd = new CommandCapture(0,"echo "+command+" > "+COMMAND_FILE.getAbsolutePath(), "reboot recovery");
+ try {
+ RootTools.getShell(true).add(cmd);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void installBoot(String bootPath) {
+ CommandCapture cmd = new CommandCapture(0,"dd if="+bootPath+" of=/dev/block/platform/msm_sdcc.1/by-name/boot", "reboot");
+ try {
+ RootTools.getShell(true).add(cmd);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void installRecovery(String recoveryPath) {
+ CommandCapture cmd = new CommandCapture(0,"dd if="+recoveryPath+" of=/dev/block/platform/msm_sdcc.1/by-name/recovery", "reboot");
+ try {
+ RootTools.getShell(true).add(cmd);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/GpuPreferenceFragment.java b/src/com/dsht/kerneltweaker/fragments/GpuPreferenceFragment.java
new file mode 100644
index 0000000..22354a1
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/GpuPreferenceFragment.java
@@ -0,0 +1,302 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.CustomListPreference;
+import com.dsht.kerneltweaker.CustomPreference;
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.ListViewMultiChoiceModeListener;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+import android.text.InputType;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.EditText;
+import android.widget.ListView;
+
+public class GpuPreferenceFragment extends PreferenceFragment implements OnPreferenceChangeListener {
+ private Context mContext;
+ private SharedPreferences mPrefs;
+ private CustomListPreference mGpuFrequency;
+ private PreferenceCategory mCategory;
+ private static final String GPU_FREQUENCIES_FILE = "/sys/class/kgsl/kgsl-3d0/gpu_available_frequencies";
+ private static final String GPU_FOLDER = "/sys/class/kgsl/";
+ private static final String GPU_MAX_FREQ_FILE = "/sys/class/kgsl/kgsl-3d0/max_gpuclk";
+ private String color;
+ private PreferenceScreen mRoot;
+ private DatabaseHandler db = MainActivity.db;
+ private static final String category = "gpu";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.pref_screen_gpu);
+ mContext = getActivity();
+
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle();
+ }
+
+ Helpers.setPermissions(GPU_FREQUENCIES_FILE);
+ Helpers.setPermissions(GPU_MAX_FREQ_FILE);
+ Helpers.setPermissions(GPU_FOLDER);
+
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ mCategory = (PreferenceCategory) findPreference("key_gpu_category");
+ mGpuFrequency = (CustomListPreference) findPreference("key_gpu_frequency");
+ mRoot = (PreferenceScreen) findPreference("key_root");
+ mGpuFrequency.setOnPreferenceChangeListener(this);
+ //mGpuFrequency.setSummary(mPrefs.getString(mGpuFrequency.getKey(), "Set GPU maximum frequency"));
+ color = "";
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ color = "#"+Integer.toHexString(col);
+ }else if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GPU, Color.parseColor("#ff0099cc"));
+ color = "#"+Integer.toHexString(col);
+ }
+ else {
+ color = getResources().getStringArray(R.array.menu_colors)[3];
+ }
+ mGpuFrequency.setTitleColor(color);
+ mGpuFrequency.setCategory(category);
+ mGpuFrequency.setKey(GPU_MAX_FREQ_FILE);
+
+ if(new File(GPU_FOLDER).exists()) {
+ addPreferences();
+ String gpuFrequencies = Helpers.getFileContent(new File(GPU_FREQUENCIES_FILE));
+ String[] frequencies = gpuFrequencies.split(" ");
+ String[] gpuNames = Helpers.getFreqToMhz(GPU_FREQUENCIES_FILE);
+ mGpuFrequency.setEntries(gpuNames);
+ mGpuFrequency.setEntryValues(frequencies);
+ mGpuFrequency.setSummary(Helpers.getFileContent(new File(GPU_MAX_FREQ_FILE)));
+ } else {
+ mCategory.removePreference(mGpuFrequency);
+ CustomPreference pref = new CustomPreference(mContext, true, category);
+ pref.setTitle("No Tweakable Values");
+ pref.setSummary("This kernel doesn\'t support GPU Tweaks");
+ pref.setTitleColor("#ff4444");
+ pref.setSummaryColor("#ff4444");
+ pref.excludeFromDialog(true);
+ mCategory.addPreference(pref);
+ }
+
+ setRetainInstance(true);
+
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list, container,false);
+ ListView listView = (ListView) v.findViewById(android.R.id.list);
+
+/* listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ registerForContextMenu(listView);
+ listView.setMultiChoiceModeListener(new ListViewMultiChoiceModeListener(
+ mContext,getActivity(),
+ listView,mRoot,
+ false,
+ db,
+ MainActivity.vddDb));
+*/
+ return v;
+ }
+
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object newValue) {
+ // TODO Auto-generated method stub
+ if(pref == mGpuFrequency) {
+ String value = ((String) newValue).trim();
+ mGpuFrequency.setSummary(value);
+ mGpuFrequency.setValue(value);
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+GPU_MAX_FREQ_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+ updateListDb(pref, value);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return false;
+ }
+
+
+ private void addPreferences() {
+ File f = new File("/sys/module/msm_kgsl_core/parameters/down_threshold");
+ File f2 = new File("/sys/module/msm_kgsl_core/parameters/sample_time_ms");
+ File f3 = new File("/sys/module/msm_kgsl_core/parameters/up_threshold");
+ File f4 = new File("/sys/module/msm_kgsl_core/parameters/simple_laziness");
+ File f5 = new File("/sys/module/msm_kgsl_core/parameters/simple_ramp_threshold");
+ if(f.exists())
+ createPreference(f, color);
+ if(f2.exists())
+ createPreference(f2, color);
+ if(f3.exists())
+ createPreference(f3, color);
+ if(f4.exists())
+ createPreference(f4, color);
+ if(f5.exists())
+ createPreference(f5, color);
+
+ }
+
+ private void createPreference(File file, String color) {
+ String fileName = file.getName();
+ String filePath = file.getAbsolutePath();
+ final String fileContent = Helpers.getFileContent(file);
+ final CustomPreference pref = new CustomPreference(mContext, false, category);
+ pref.setTitle(fileName);
+ pref.setTitleColor(color);
+ pref.setSummary(fileContent);
+ pref.setKey(filePath);
+ Log.d("CONTENT", fileContent);
+ mCategory.addPreference(pref);
+ pref.setOnPreferenceClickListener(new OnPreferenceClickListener(){
+
+ @Override
+ public boolean onPreferenceClick(final Preference p) {
+ // TODO Auto-generated method stub
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View v = inflater.inflate(R.layout.dialog_layout, null, false);
+ final EditText et = (EditText) v.findViewById(R.id.et);
+ String val = p.getSummary().toString();
+ et.setText(val);
+ et.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+ et.setGravity(Gravity.CENTER_HORIZONTAL);
+ List<DataItem> items = db.getAllItems();
+ builder.setView(v);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ String value = et.getText().toString();
+ p.setSummary(value);
+ Log.d("TEST", "echo "+value+" > "+ p.getKey());
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+p.getKey());
+ try {
+ RootTools.getShell(true).add(command);
+ updateDb(p, value, pref.getCheckBoxState());
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ } );
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ return true;
+ }
+
+ });
+ }
+
+
+
+ private void updateDb(final Preference p, final String value,final boolean isChecked) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ if(isChecked) {
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+ } else {
+ if(db.getContactsCount() != 0) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+ }
+ new LongOperation().execute();
+ }
+
+ private void updateListDb(final Preference p, final String value) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+ }
+ new LongOperation().execute();
+ }
+
+}
+
+
diff --git a/src/com/dsht/kerneltweaker/fragments/InitD.java b/src/com/dsht/kerneltweaker/fragments/InitD.java
new file mode 100644
index 0000000..bd763c4
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/InitD.java
@@ -0,0 +1,346 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kernetweaker.cmdprocessor.CMDProcessor;
+
+import android.app.ProgressDialog;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+
+public class InitD extends PreferenceFragment implements OnPreferenceChangeListener {
+
+ private static final String KEY_ZIPALIGN_APKS = "zipalign_apks";
+ private static final String KEY_FIX_PERMISSIONS = "fix_permissions";
+ private static final String KEY_CLEAR_DATA_CACHE = "clear_data_cache";
+ private static final String KEY_ENABLE_CRON = "enable_cron";
+ private static final String KEY_FILE_SYSTEM_SPEEDUPS = "file_system_speedups";
+ private static final String REMOUNT_CMD = "busybox mount -o %s,remount /dev/block/platform/msm_sdcc.1/by-name/system /system";
+
+ private static final String[] KEYS = {
+ KEY_ZIPALIGN_APKS, //0
+ KEY_FIX_PERMISSIONS, //1
+ KEY_CLEAR_DATA_CACHE, //2
+ KEY_ENABLE_CRON, //3
+ KEY_FILE_SYSTEM_SPEEDUPS, //4
+ };
+
+ protected SharedPreferences mPrefs;
+ private CheckBoxPreference mZipAlign;
+ private CheckBoxPreference mFixPermissions;
+ private CheckBoxPreference mClearCache;
+ private CheckBoxPreference mEnableCron;
+ private CheckBoxPreference mSysSpeedup;
+
+ private static InitD sActivity;
+ private static final String SCRIPT_HEAD = "#!/system/bin/sh";
+ private static final String SCRIPT_HELPERS = ". /system/etc/helpers.sh";
+ private static final String SCRIPT_PERMS = "chmod 755";
+ private static final String ZIPALIGN_FILE = "01zipalign";
+ private static final String INIT_PATH = "/system/etc/init.d/";
+ private static final String CLEAR_CACHE_COMMAND = "busybox find /data/data -type d -iname \"*cache*\" -maxdepth 2 -mindepth 2 -exec busybox rm -rf {} ';' ";
+ private static final String CACHE_FILE = "06removecache";
+ private static final String FIXPERMS_FILE = "07fixperms";
+ private static final String CRON_FILE = "09cron";
+ private static final String TWEAKS_FILE = "98tweaks";
+
+ public static InitD whatActivity() {
+ return sActivity;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ sActivity = this;
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ addPreferencesFromResource(R.xml.init_d);
+
+ mZipAlign = (CheckBoxPreference) findPreference(KEYS[0]);
+ mFixPermissions = (CheckBoxPreference) findPreference(KEYS[1]);
+ mClearCache = (CheckBoxPreference) findPreference(KEYS[2]);
+ mEnableCron = (CheckBoxPreference) findPreference(KEYS[3]);
+ mSysSpeedup = (CheckBoxPreference) findPreference(KEYS[4]);
+
+ mZipAlign.setOnPreferenceChangeListener(this);
+ mFixPermissions.setOnPreferenceChangeListener(this);
+ mClearCache.setOnPreferenceChangeListener(this);
+ mEnableCron.setOnPreferenceChangeListener(this);
+ mSysSpeedup.setOnPreferenceChangeListener(this);
+
+ loadValues();
+ copyHelpers();
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle(true);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object newValue) {
+ // TODO Auto-generated method stub
+ boolean value = (Boolean)newValue;
+ if(pref == mZipAlign) {
+ if(value) {
+ createInitD(ZIPALIGN_FILE, "zipalign_apks");
+ } else {
+ deleteInitD(INIT_PATH+ZIPALIGN_FILE);
+ }
+ return true;
+ }
+ if(pref == mFixPermissions) {
+ if(value) {
+ createInitD(FIXPERMS_FILE,"fix_permissions");
+ } else {
+ deleteInitD(INIT_PATH+FIXPERMS_FILE);
+ }
+ return true;
+ }
+ if(pref == mClearCache) {
+ if(value) {
+ createInitD(CACHE_FILE, CLEAR_CACHE_COMMAND);
+ }else {
+ deleteInitD(INIT_PATH+CACHE_FILE);
+ }
+ return true;
+ }
+ if(pref == mEnableCron) {
+ if(value) {
+ copyScript(CRON_FILE);
+ }else {
+ deleteInitD(INIT_PATH+CRON_FILE);
+ }
+ return true;
+ }
+ if(pref == mSysSpeedup) {
+ if(value) {
+ copyScript(TWEAKS_FILE);
+ }else {
+ deleteInitD(INIT_PATH+TWEAKS_FILE);
+ }
+ return true;
+ }
+ loadValues();
+
+ return false;
+ }
+
+
+ private void createInitD(final String filename, final String filecontent) {
+
+ class AsyncCreateInitTask extends AsyncTask<Void, Void, Boolean> {
+
+ ProgressDialog pd;
+
+ @Override
+ protected void onPreExecute() {
+ pd = new ProgressDialog(getActivity());
+ pd.setIndeterminate(true);
+ pd.setMessage("Creating script...Please wait");
+ pd.setCancelable(false);
+ pd.show();
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+
+ mount("rw");
+ new CMDProcessor().su.runWaitFor("echo \""+SCRIPT_HEAD+"\" >> " + INIT_PATH + filename);
+ new CMDProcessor().su.runWaitFor("echo \""+SCRIPT_HELPERS+"\" >> "+ INIT_PATH + filename );
+ new CMDProcessor().su.runWaitFor("echo \""+ filecontent + "\" >> " + INIT_PATH + filename);
+ new CMDProcessor().su.runWaitFor(SCRIPT_PERMS+" " + INIT_PATH + filename);
+ mount("ro");
+ return true;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean res) {
+ // result holds what you return from doInBackground
+ super.onPostExecute(res);
+ pd.dismiss();
+ }
+ }
+ new AsyncCreateInitTask().execute();
+ }
+
+ private void deleteInitD(final String filepath) {
+
+ class AsyncDeleteInitTask extends AsyncTask<Void, Void, Boolean> {
+
+ ProgressDialog pd;
+
+ @Override
+ protected void onPreExecute() {
+ pd = new ProgressDialog(getActivity());
+ pd.setIndeterminate(true);
+ pd.setMessage("Deleting script...Please wait");
+ pd.setCancelable(false);
+ pd.show();
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+
+ mount("rw");
+ new CMDProcessor().su.runWaitFor("rm -f "+filepath);
+ mount("ro");
+ return true;
+ }
+ @Override
+ protected void onPostExecute(Boolean res) {
+ // result holds what you return from doInBackground
+ super.onPostExecute(res);
+ pd.dismiss();
+ }
+ }
+ new AsyncDeleteInitTask().execute();
+ }
+
+
+ private void loadValues() {
+ if(new File(INIT_PATH+ZIPALIGN_FILE).exists()) {
+ mZipAlign.setChecked(true);
+ }
+ if(new File(INIT_PATH+FIXPERMS_FILE).exists()) {
+ mFixPermissions.setChecked(true);
+ }
+ if(new File(INIT_PATH+CACHE_FILE).exists()) {
+ mClearCache.setChecked(true);
+ }
+ if(new File(INIT_PATH+CRON_FILE).exists()) {
+ mEnableCron.setChecked(true);
+ }
+ if(new File(INIT_PATH+TWEAKS_FILE).exists()) {
+ mSysSpeedup.setChecked(true);
+ }
+ }
+
+ public boolean mount(String read_value) {
+ Log.d("TAG", "Remounting /system " + read_value);
+ return new CMDProcessor().su.runWaitFor(String.format(REMOUNT_CMD, read_value)).success();
+ }
+
+ private void copyHelpers() {
+ if(!new File("/system/etc/helpers.sh").exists()) {
+ class AsyncCopyHelpersTask extends AsyncTask<Void, Void, Boolean> {
+
+ ProgressDialog pd;
+
+ @Override
+ protected void onPreExecute() {
+ pd = new ProgressDialog(getActivity());
+ pd.setIndeterminate(true);
+ pd.setMessage("Copying Helpers...Please wait");
+ pd.setCancelable(false);
+ pd.show();
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+
+
+ mount("rw");
+ new CMDProcessor().su.runWaitFor("cp /data/data/com.dsht.kerneltweaker/files/helpers.sh " + "/system/etc");
+ new CMDProcessor().su.runWaitFor("chmod 644 /system/etc/helpers.sh");
+ mount("ro");
+
+ return true;
+ }
+ @Override
+ protected void onPostExecute(Boolean res) {
+ // result holds what you return from doInBackground
+ super.onPostExecute(res);
+ pd.dismiss();
+ }
+ }
+ new AsyncCopyHelpersTask().execute();
+ }
+ }
+
+ private void copyScript(final String name) {
+ class AsyncCopyScriptTask extends AsyncTask<Void, Void, Boolean> {
+
+ ProgressDialog pd;
+
+ @Override
+ protected void onPreExecute() {
+ pd = new ProgressDialog(getActivity());
+ pd.setIndeterminate(true);
+ pd.setMessage("Copying script...Please wait");
+ pd.setCancelable(false);
+ pd.show();
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+
+ copyAsset(name);
+ mount("rw");
+ new CMDProcessor().su.runWaitFor("cp /data/data/com.dsht.kerneltweaker/files/"+name+" " + "/system/etc/init.d");
+ new CMDProcessor().su.runWaitFor("chmod 644 /system/etc/init.d/"+name);
+ mount("ro");
+
+ return true;
+ }
+ @Override
+ protected void onPostExecute(Boolean res) {
+ // result holds what you return from doInBackground
+ super.onPostExecute(res);
+ pd.dismiss();
+ }
+ }
+ new AsyncCopyScriptTask().execute();
+ }
+
+ private void copyAsset(String name) {
+
+ if(!new File(getActivity().getFilesDir().getPath(),name).exists()) {
+
+ InputStream stream = null;
+ OutputStream output = null;
+
+ try {
+ stream = getActivity().getAssets().open(name);
+ output = new BufferedOutputStream(new FileOutputStream(getActivity().getFilesDir()+"/"+name));
+
+ byte data[] = new byte[1024];
+ int count;
+
+ while((count = stream.read(data)) != -1)
+ {
+ output.write(data, 0, count);
+ }
+
+ output.flush();
+ output.close();
+ stream.close();
+
+ stream = null;
+ output = null;
+
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/KernelPreferenceFragment.java b/src/com/dsht/kerneltweaker/fragments/KernelPreferenceFragment.java
new file mode 100644
index 0000000..fb3141c
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/KernelPreferenceFragment.java
@@ -0,0 +1,944 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.CustomCheckBoxPreference;
+import com.dsht.kerneltweaker.CustomListPreference;
+import com.dsht.kerneltweaker.CustomPreference;
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.ListViewMultiChoiceModeListener;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.kernetweaker.cmdprocessor.CMDProcessor;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+import android.text.InputType;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.EditText;
+import android.widget.ListView;
+
+public class KernelPreferenceFragment extends PreferenceFragment implements OnPreferenceChangeListener, OnPreferenceClickListener {
+
+ private CustomCheckBoxPreference mKernelFsync;
+ private CustomCheckBoxPreference mKernelDynFsync;
+ private CustomCheckBoxPreference mKernelF2s;
+ private CustomCheckBoxPreference mKernelF2w;
+ private CustomCheckBoxPreference mKernelFcharge;
+ private CustomCheckBoxPreference mDoubleTap;
+ private CustomCheckBoxPreference mSweep2wake;
+ private CustomCheckBoxPreference mSweep2sleep;
+ private CustomCheckBoxPreference mIntelliPlug;
+ private CustomCheckBoxPreference mEcoMode;
+ private CustomPreference mVibration;
+ private CustomPreference mAdvancedScheduler;
+ private CustomListPreference mCpuScheduler;
+ private CustomListPreference mCpuReadAhead;
+ private PreferenceCategory mSoundCategory;
+ private CustomPreference mSoundInfo;
+ private SharedPreferences mPrefs;
+ private PreferenceCategory mKernelCategory;
+ private Context mContext;
+ private PreferenceScreen mRootScreen;
+ private PreferenceCategory mSchedCategory;
+ private static final String FSYNC_FILE = "/sys/module/sync/parameters/fsync_enabled";
+ private static final String SCHEDULER_FILE = "/sys/block/mmcblk0/queue/scheduler";
+ private static final String READ_AHEAD_FILE = "/sys/block/mmcblk0/queue/read_ahead_kb";
+ private static final String FCHARGE_FILE = "/sys/kernel/fast_charge/force_fast_charge";
+ private static final String TEMP_FILE = "/sys/module/msm_thermal/parameters/temp_threshold";
+
+ private static final String SOUNDCONTROL_FILE = "/sys/kernel/sound_control_3";
+ private static final String HEADSET_BOOST_FILE = "/sys/devices/virtual/misc/soundcontrol/headset_boost";
+ private static final String MIC_BOOST_FILE = "/sys/devices/virtual/misc/soundcontrol/mic_boost";
+ private static final String SPEAKER_BOOST_FILE = "/sys/devices/virtual/misc/soundcontrol/speaker_boost";
+ private static final String VOLUME_BOOST_FILE = "/sys/devices/virtual/misc/soundcontrol/volume_boost";
+ private static final String category = "kernel";
+ private static final String TCP_OPTIONS = "sysctl net.ipv4.tcp_available_congestion_control";
+ private static final String TCP_CURRENT = "sysctl net.ipv4.tcp_congestion_control";
+ private static final String DT2W_FILE = "/sys/android_touch/doubletap2wake";
+ private static final String S2W_FILE = "/sys/android_touch/sweep2wake";
+ private static final String S2W_SLEEPONLY_FILE = "/sys/android_touch/s2w_s2sonly";
+ private static final String INTELLIPLUG_FILE = "/sys/module/intelli_plug/parameters/intelli_plug_active";
+ private static final String ECOMODE_FILE = "/sys/module/intelli_plug/parameters/eco_mode_active";
+ private static final String DYNFSYNC_FILE = "/sys/kernel/dyn_fsync/Dyn_fsync_active";
+ private static final String FAUXSOUND_FILE = "/sys/kernel/sound_control_3";
+ private static final String VIBRATION_FILE = "/sys/class/timed_output/vibrator/amp";
+ private static final String F2S_FILE = "sys/devices/virtual/htc_g_sensor/g_sensor/flick2sleep";
+ private static final String F2W_FILE = "sys/devices/virtual/htc_g_sensor/g_sensor/flick2wake";
+
+
+ private String color;
+ private DatabaseHandler db;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.pref_screen_kernel);
+ mContext = getActivity();
+
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle();
+ }
+
+ Helpers.setPermissions(DT2W_FILE);
+ Helpers.setPermissions(DYNFSYNC_FILE);
+ Helpers.setPermissions(ECOMODE_FILE);
+ Helpers.setPermissions(FAUXSOUND_FILE);
+ Helpers.setPermissions(FCHARGE_FILE);
+ Helpers.setPermissions(FSYNC_FILE);
+ Helpers.setPermissions(HEADSET_BOOST_FILE);
+ Helpers.setPermissions(INTELLIPLUG_FILE);
+ Helpers.setPermissions(MIC_BOOST_FILE);
+ Helpers.setPermissions(READ_AHEAD_FILE);
+ Helpers.setPermissions(S2W_FILE);
+ Helpers.setPermissions(S2W_SLEEPONLY_FILE);
+ Helpers.setPermissions(SCHEDULER_FILE);
+ Helpers.setPermissions(SPEAKER_BOOST_FILE);
+ Helpers.setPermissions(TEMP_FILE);
+ Helpers.setPermissions(VIBRATION_FILE);
+ Helpers.setPermissions(VOLUME_BOOST_FILE);
+ Helpers.setPermissions(TCP_CURRENT);
+ Helpers.setPermissions(TCP_OPTIONS);
+ Helpers.setPermissions(F2S_FILE);
+ Helpers.setPermissions(F2W_FILE);
+
+
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ mSoundCategory = (PreferenceCategory) findPreference("key_sound_category");
+ mSchedCategory = (PreferenceCategory) findPreference("key_sched_cat");
+ mKernelFsync = (CustomCheckBoxPreference) findPreference("key_fsync_switch");
+ mKernelDynFsync = (CustomCheckBoxPreference) findPreference("key_dynfsync_switch");
+ mKernelF2s = (CustomCheckBoxPreference) findPreference("key_f2s_switch");
+ mKernelF2w = (CustomCheckBoxPreference) findPreference("key_f2w_switch");
+ mKernelFcharge = (CustomCheckBoxPreference) findPreference("key_fcharge_switch");
+ mCpuScheduler = (CustomListPreference) findPreference("key_cpu_sched");
+ mAdvancedScheduler = (CustomPreference) findPreference("key_advanced_scheduler");
+ mCpuReadAhead = (CustomListPreference) findPreference("key_cpu_readahead");
+ mSoundInfo = (CustomPreference) findPreference("key_kernel_info");
+ mKernelCategory = (PreferenceCategory) findPreference("key_kernel_tweaks");
+ mRootScreen = (PreferenceScreen) findPreference("key_pref_screen");
+ mDoubleTap = (CustomCheckBoxPreference) findPreference("key_dt2w_switch");
+ mSweep2wake = (CustomCheckBoxPreference) findPreference("key_s2w_switch");
+ mSweep2sleep = (CustomCheckBoxPreference) findPreference("key_s2ws_switch");
+ mIntelliPlug = (CustomCheckBoxPreference) findPreference("key_intelliplug_switch");
+ mEcoMode = (CustomCheckBoxPreference) findPreference("key_ecomode_switch");
+ mVibration = (CustomPreference) findPreference("key_vibration");
+ db = MainActivity.db;
+
+ mKernelFsync.setKey(FSYNC_FILE);
+ mKernelDynFsync.setKey(DYNFSYNC_FILE);
+ mKernelFcharge.setKey(FCHARGE_FILE);
+ mCpuScheduler.setKey(SCHEDULER_FILE);
+ mCpuReadAhead.setKey(READ_AHEAD_FILE);
+ mDoubleTap.setKey(DT2W_FILE);
+ mSweep2wake.setKey(S2W_FILE);
+ mSweep2sleep.setKey(S2W_SLEEPONLY_FILE);
+ mIntelliPlug.setKey(INTELLIPLUG_FILE);
+ mEcoMode.setKey(ECOMODE_FILE);
+ mVibration.setKey(VIBRATION_FILE);
+ mKernelF2s.setKey(F2S_FILE);
+ mKernelF2w.setKey(F2W_FILE);
+
+ mCpuScheduler.setKey(SCHEDULER_FILE);
+ mCpuReadAhead.setKey(READ_AHEAD_FILE);
+
+ mCpuScheduler.setCategory(category);
+ mCpuReadAhead.setCategory(category);
+ mKernelFsync.setCategory(category);
+ mKernelDynFsync.setCategory(category);
+ mKernelFcharge.setCategory(category);
+ mDoubleTap.setCategory(category);
+ mSweep2wake.setCategory(category);
+ mSweep2sleep.setCategory(category);
+ mIntelliPlug.setCategory(category);
+ mEcoMode.setCategory(category);
+ mVibration.setCategory(category);
+ mKernelF2s.setCategory(category);
+ mKernelF2w.setCategory(category);
+
+ String[] schedulers = Helpers.getAvailableSchedulers();
+ String[] readAheadKb = {"128","256","384","512","640","768","896","1024","1152",
+ "1280","1408","1536","1664","1792","1920","2048", "2176", "2304", "2432", "2560",
+ "2688", "2816", "2944", "3072", "3200", "3328", "3456", "3584", "3712", "3840", "3968", "4096"};
+ color = "";
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ color = "#"+Integer.toHexString(col);
+ }else if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_KERNEL, Color.parseColor("#ff0099cc"));
+ color = "#"+Integer.toHexString(col);
+ }
+ else {
+ color = getResources().getStringArray(R.array.menu_colors)[5];
+ }
+
+ mKernelFsync.setTitleColor(color);
+ mKernelDynFsync.setTitleColor(color);
+ mKernelFcharge.setTitleColor(color);
+ mCpuScheduler.setTitleColor(color);
+ mAdvancedScheduler.setTitleColor(color);
+ mCpuReadAhead.setTitleColor(color);
+ mSoundInfo.setTitleColor("#ff4444");
+ mSoundInfo.setSummaryColor("#ff4444");
+ mSoundInfo.excludeFromDialog(true);
+ mSoundInfo.hideBoot(true);
+ mAdvancedScheduler.excludeFromDialog(true);
+ mAdvancedScheduler.hideBoot(true);
+ mDoubleTap.setTitleColor(color);
+ mSweep2wake.setTitleColor(color);
+ mSweep2sleep.setTitleColor(color);
+ mIntelliPlug.setTitleColor(color);
+ mEcoMode.setTitleColor(color);
+ mVibration.setTitleColor(color);
+ mKernelF2s.setTitleColor(color);
+ mKernelF2w.setTitleColor(color);
+
+ mCpuScheduler.setEntries(schedulers);
+ mCpuScheduler.setEntryValues(schedulers);
+ mCpuReadAhead.setEntries(readAheadKb);
+ mCpuReadAhead.setEntryValues(readAheadKb);
+
+ mCpuScheduler.setSummary(Helpers.getCurrentScheduler());
+ mCpuReadAhead.setSummary(Helpers.getFileContent(new File(READ_AHEAD_FILE)));
+
+ mAdvancedScheduler.setOnPreferenceClickListener(this);
+ mCpuScheduler.setOnPreferenceChangeListener(this);
+ mCpuReadAhead.setOnPreferenceChangeListener(this);
+ mVibration.setOnPreferenceClickListener(this);
+
+ mKernelFsync.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ CommandCapture command = null;
+ if (newValue.toString().equals("true")) {
+ command = new CommandCapture(0,"echo Y > "+FSYNC_FILE);
+ } else {
+ command = new CommandCapture(0,"echo N > "+FSYNC_FILE);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+
+ mKernelDynFsync.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ CommandCapture command = null;
+ if (newValue.toString().equals("true")) {
+ command = new CommandCapture(0,"echo 1 > "+DYNFSYNC_FILE);
+ } else {
+ command = new CommandCapture(0,"echo 0 > "+DYNFSYNC_FILE);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+
+ mDoubleTap.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ CommandCapture command = null;
+ if (newValue.toString().equals("true")) {
+ command = new CommandCapture(0,"echo 1 > "+DT2W_FILE);
+ } else {
+ command = new CommandCapture(0,"echo 0 > "+DT2W_FILE);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+
+ mSweep2wake.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ CommandCapture command = null;
+ if (newValue.toString().equals("true")) {
+ command = new CommandCapture(0,"echo 1 > "+S2W_FILE);
+ } else {
+ command = new CommandCapture(0,"echo 0 > "+S2W_FILE);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+
+ mSweep2sleep.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ CommandCapture command = null;
+ if (newValue.toString().equals("true")) {
+ command = new CommandCapture(0,"echo 1 > "+S2W_SLEEPONLY_FILE);
+ } else {
+ command = new CommandCapture(0,"echo 0 > "+S2W_SLEEPONLY_FILE);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+
+
+ mKernelF2s.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ CommandCapture command = null;
+ if (newValue.toString().equals("true")) {
+ command = new CommandCapture(0,"echo 1 > "+F2S_FILE);
+ } else {
+ command = new CommandCapture(0,"echo 0 > "+F2S_FILE);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+
+ mKernelF2w.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ CommandCapture command = null;
+ if (newValue.toString().equals("true")) {
+ command = new CommandCapture(0,"echo 1 > "+F2W_FILE);
+ } else {
+ command = new CommandCapture(0,"echo 0 > "+F2W_FILE);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+
+ mIntelliPlug.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ CommandCapture command = null;
+ if (newValue.toString().equals("true")) {
+ command = new CommandCapture(0,"echo 1 > "+INTELLIPLUG_FILE);
+ } else {
+ command = new CommandCapture(0,"echo 0 > "+INTELLIPLUG_FILE);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+
+ mEcoMode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ SharedPreferences.Editor editor = mPrefs.edit();
+ CommandCapture command = null;
+ if (newValue.toString().equals("true")) {
+ command = new CommandCapture(0,"echo 1 > "+ECOMODE_FILE);
+ } else {
+ command = new CommandCapture(0,"echo 0 > "+ECOMODE_FILE);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ editor.commit();
+ return true;
+ }
+ });
+
+ mKernelFcharge.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ CommandCapture command = null;
+ if (newValue.toString().equals("true")) {
+ command = new CommandCapture(0,"echo 1 > "+FCHARGE_FILE);
+ } else {
+ command = new CommandCapture(0,"echo 0 > "+FCHARGE_FILE);
+ }
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+
+ if(!new File(FSYNC_FILE).exists()) {
+ mKernelCategory.removePreference(mKernelFsync);
+ } else {
+ String fsyncState = Helpers.getFileContent(new File(FSYNC_FILE));
+ if(fsyncState.equals("Y")) {
+ mKernelFsync.setChecked(true);
+ mKernelFsync.setValue("Y");
+ }else if(fsyncState.equals("N")) {
+ mKernelFsync.setChecked(false);
+ mKernelFsync.setValue("N");
+ }
+ }
+
+ if(!new File(DYNFSYNC_FILE).exists()) {
+ mKernelCategory.removePreference(mKernelDynFsync);
+ } else {
+ String fsyncState = Helpers.getFileContent(new File(DYNFSYNC_FILE));
+ if(fsyncState.equals("1")) {
+ mKernelDynFsync.setChecked(true);
+ mKernelDynFsync.setValue("1");
+ }else if(fsyncState.equals("0")) {
+ mKernelDynFsync.setChecked(false);
+ mKernelDynFsync.setValue("0");
+ }
+ }
+
+ if(!new File(DT2W_FILE).exists()) {
+ mKernelCategory.removePreference(mDoubleTap);
+ } else {
+ String dtState = Helpers.getFileContent(new File(DT2W_FILE));
+ if(dtState.equals("1")) {
+ mDoubleTap.setChecked(true);
+ mDoubleTap.setValue("1");
+ }else if(dtState.equals("0")) {
+ mDoubleTap.setChecked(false);
+ mDoubleTap.setValue("0");
+ }
+ }
+
+ if(!new File(S2W_FILE).exists()) {
+ mKernelCategory.removePreference(mSweep2wake);
+ } else {
+ String s2wState = Helpers.getFileContent(new File(S2W_FILE));
+ if(s2wState.equals("1")) {
+ mSweep2wake.setChecked(true);
+ mSweep2wake.setValue("1");
+ }else if(s2wState.equals("0")) {
+ mSweep2wake.setChecked(false);
+ mSweep2wake.setValue("0");
+ }
+ }
+
+
+ if(!new File(F2S_FILE).exists()) {
+ mKernelCategory.removePreference(mKernelF2s);
+ } else {
+ String dtState = Helpers.getFileContent(new File(F2S_FILE));
+ if(dtState.equals("1")) {
+ mKernelF2s.setChecked(true);
+ mKernelF2s.setValue("1");
+ }else if(dtState.equals("0")) {
+ mKernelF2s.setChecked(false);
+ mKernelF2s.setValue("0");
+ }
+ }
+
+ if(!new File(F2W_FILE).exists()) {
+ mKernelCategory.removePreference(mKernelF2w);
+ } else {
+ String dtState = Helpers.getFileContent(new File(F2W_FILE));
+ if(dtState.equals("1")) {
+ mKernelF2w.setChecked(true);
+ mKernelF2w.setValue("1");
+ }else if(dtState.equals("0")) {
+ mKernelF2w.setChecked(false);
+ mKernelF2w.setValue("0");
+ }
+ }
+
+
+ if(!new File(S2W_SLEEPONLY_FILE).exists()) {
+ mKernelCategory.removePreference(mSweep2sleep);
+ } else {
+ String s2wsState = Helpers.getFileContent(new File(S2W_SLEEPONLY_FILE));
+ if(s2wsState.equals("1")) {
+ mSweep2sleep.setChecked(true);
+ mSweep2sleep.setValue("1");
+ }else if(s2wsState.equals("0")) {
+ mSweep2sleep.setChecked(false);
+ mSweep2sleep.setValue("0");
+ }
+ }
+
+ if(!new File(FCHARGE_FILE).exists()) {
+ mKernelCategory.removePreference(mKernelFcharge);
+ } else {
+ String fchargeState = Helpers.getFileContent(new File(FCHARGE_FILE));
+ if(fchargeState.equals("0")) {
+ mKernelFcharge.setChecked(false);
+ mKernelFcharge.setValue("0");
+ } else if(fchargeState.equals("1")) {
+ mKernelFcharge.setChecked(true);
+ mKernelFcharge.setValue("1");
+ }
+ }
+
+ if(!new File(INTELLIPLUG_FILE).exists()) {
+ mKernelCategory.removePreference(mIntelliPlug);
+ } else {
+ String fchargeState = Helpers.getFileContent(new File(INTELLIPLUG_FILE));
+ if(fchargeState.equals("0")) {
+ mIntelliPlug.setChecked(false);
+ mIntelliPlug.setValue("0");
+ } else if(fchargeState.equals("1")) {
+ mIntelliPlug.setChecked(true);
+ mIntelliPlug.setValue("1");
+ }
+ }
+
+ if(!new File(ECOMODE_FILE).exists()) {
+ mKernelCategory.removePreference(mEcoMode);
+ } else {
+ String fchargeState = Helpers.getFileContent(new File(ECOMODE_FILE));
+ if(fchargeState.equals("0")) {
+ mEcoMode.setChecked(false);
+ mEcoMode.setValue("0");
+ } else if(fchargeState.equals("1")) {
+ mEcoMode.setChecked(true);
+ mEcoMode.setValue("1");
+ }
+ }
+
+ if(mKernelCategory.getPreferenceCount() == 0) {
+ mRootScreen.removePreference(mKernelCategory);
+ }
+
+ File f = new File(HEADSET_BOOST_FILE);
+ File f1 = new File(MIC_BOOST_FILE);
+ File f2 = new File(SPEAKER_BOOST_FILE);
+ File f3 = new File(VOLUME_BOOST_FILE);
+ File f4 = new File(TEMP_FILE);
+ if(f.exists())
+ createPreference(mSoundCategory,f, color, true);
+ if(f1.exists())
+ createPreference(mSoundCategory,f1, color, true);
+ if(f2.exists())
+ createPreference(mSoundCategory,f2, color, true);
+ if(f3.exists())
+ createPreference(mSoundCategory,f3, color, true);
+ if(f4.exists()) {
+ createPreference(mKernelCategory,f4, color, true);
+ }
+ if(new File(VIBRATION_FILE).exists()){
+ mVibration.setSummary(Helpers.getFileContent(new File(VIBRATION_FILE)));
+ }else {
+ mKernelCategory.removePreference(mVibration);
+ }
+ /*
+ if(new File(FAUXSOUND_FILE).exists()) {
+ File[] files = new File(FAUXSOUND_FILE).listFiles();
+ Arrays.sort(files);
+ for(File file: files) {
+ if(!file.getName().contains("version")) {
+ createPreference(mSoundCategory,file, color, false);
+ }
+ }
+ }
+ */
+ if(mSoundCategory.getPreferenceCount() == 1) {
+ mRootScreen.removePreference(mSoundCategory);
+ }
+
+ if(RootTools.isBusyboxAvailable()) {
+ String[] availTCP = Helpers.readCommandStrdOut(TCP_OPTIONS, false).replaceAll("net.ipv4.tcp_available_congestion_control = ", "").replaceAll("\n", "").split(" ");
+ CustomListPreference pref = new CustomListPreference(mContext, category);
+ pref.setTitle("TCP Congestion control");
+ pref.setTitleColor(color);
+ pref.setEntries(availTCP);
+ pref.setEntryValues(availTCP);
+ pref.setSummary(Helpers.readCommandStrdOut(TCP_CURRENT, false).replaceAll("net.ipv4.tcp_congestion_control = ","").replaceAll("\n", ""));
+ String key = "sysctl -w net.ipv4.tcp_congestion_control=" +pref.getSummary();
+ pref.setKey(key);
+ pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object newValue) {
+ // TODO Auto-generated method stub
+ String value = (String) newValue;
+ String command = "sysctl -w net.ipv4.tcp_congestion_control=" +value;
+ pref.setKey(command);
+ pref.setSummary(value);
+ CMDProcessor.runSuCommand(command);
+ return true;
+ }
+
+ });
+
+ mSchedCategory.addPreference(pref);
+ }
+ setRetainInstance(true);
+
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list, container,false);
+ ListView listView = (ListView) v.findViewById(android.R.id.list);
+
+/* listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ registerForContextMenu(listView);
+ listView.setMultiChoiceModeListener(new ListViewMultiChoiceModeListener(
+ mContext,getActivity(),
+ listView,mRootScreen,
+ false,
+ db,
+ MainActivity.vddDb));
+*/
+ return v;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object newValue) {
+ // TODO Auto-generated method stub
+ if(pref == mCpuScheduler) {
+ String value = (String) newValue;
+ mCpuScheduler.setSummary(value);
+ mCpuScheduler.setValue(value);
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+SCHEDULER_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+ updateDb(pref, value, ((CustomListPreference) pref).isBootChecked());
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ if(pref == mCpuReadAhead) {
+ String value = (String) newValue;
+ mCpuReadAhead.setSummary(value);
+ mCpuReadAhead.setValue(value);
+ updateDb(pref, value, ((CustomListPreference) pref).isBootChecked());
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+READ_AHEAD_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onPreferenceClick(final Preference pref) {
+ // TODO Auto-generated method stub
+ if(pref == mAdvancedScheduler) {
+ Fragment f = new CpuSchedulerPreferenceFragment();
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ // This adds the newly created Preference fragment to my main layout, shown below
+ ft.replace(R.id.activity_container,f);
+ // By hiding the main fragment, transparency isn't an issue
+ ft.addToBackStack("TAG");
+ ft.commit();
+ }
+ if(pref == mVibration) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View v = inflater.inflate(R.layout.dialog_layout, null, false);
+ final EditText et = (EditText) v.findViewById(R.id.et);
+ String val = pref.getSummary().toString();
+ et.setText(val);
+ et.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+ et.setGravity(Gravity.CENTER_HORIZONTAL);
+ List<DataItem> items = db.getAllItems();
+ builder.setView(v);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ String value = et.getText().toString();
+ pref.setSummary(value);
+ CommandCapture command = new CommandCapture(0,"echo \""+value+"\" > "+pref.getKey());
+ try {
+ RootTools.getShell(true).add(command);
+ updateDb(pref, value, ((CustomPreference) pref).isBootChecked());
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ } );
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ }
+
+ return false;
+ }
+
+ private void createPreference(PreferenceCategory mCategory, File file, String color,final boolean numbers) {
+ String fileName = file.getName();
+ String filePath = file.getAbsolutePath();
+ final String fileContent = Helpers.getFileContent(file);
+ final CustomPreference pref = new CustomPreference(mContext, false, category);
+ pref.setTitle(fileName);
+ pref.setTitleColor(color);
+ pref.setSummary(fileContent);
+ pref.setKey(filePath);
+ Log.d("CONTENT", fileContent);
+ mCategory.addPreference(pref);
+ pref.setOnPreferenceClickListener(new OnPreferenceClickListener(){
+
+ @Override
+ public boolean onPreferenceClick(final Preference p) {
+ // TODO Auto-generated method stub
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View v = inflater.inflate(R.layout.dialog_layout, null, false);
+ final EditText et = (EditText) v.findViewById(R.id.et);
+ String val = p.getSummary().toString();
+ et.setText(val);
+ if(numbers) {
+ et.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+ }
+ et.setGravity(Gravity.CENTER_HORIZONTAL);
+ List<DataItem> items = db.getAllItems();
+ builder.setView(v);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ String value = et.getText().toString();
+ p.setSummary(value);
+ Log.d("TEST", "echo \""+value+"\" > "+ p.getKey());
+ CommandCapture command = new CommandCapture(0,"echo \""+value+"\" > "+p.getKey());
+ try {
+ RootTools.getShell(true).add(command);
+ updateDb(p, value, pref.isBootChecked());
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ } );
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ return true;
+ }
+
+ });
+ }
+
+
+
+ private void updateDb(final Preference p, final String value,final boolean isChecked) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ if(isChecked) {
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+ } else {
+ if(db.getContactsCount() != 0) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+ }
+ new LongOperation().execute();
+ }
+
+ private void updateListDb(final Preference p, final String value) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+ }
+ new LongOperation().execute();
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/LowMemoryKillerFragment.java b/src/com/dsht/kerneltweaker/fragments/LowMemoryKillerFragment.java
new file mode 100644
index 0000000..4479273
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/LowMemoryKillerFragment.java
@@ -0,0 +1,214 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.dsht.kerneltweaker.CustomBaseAdapter;
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.PresetsBaseAdapter;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+public class LowMemoryKillerFragment extends Fragment {
+
+ private static final String MINFREE_FILE = "/sys/module/lowmemorykiller/parameters/minfree";
+ private String[] values;
+ private CustomBaseAdapter mAdapter;
+ private Context mContext;
+ private MenuItem boot;
+ private DatabaseHandler db = MainActivity.db;
+ private List<DataItem> items;
+ private String category = "lmk";
+ private String color;
+ private ListView list;
+ private String[] names;
+ private String[] summaries;
+
+ private final static String[] presets = {
+ "512,1024,1280,2048,3072,4096",
+ "1024,2048,2560,4096,6144,8192",
+ "1024,2048,4096,8192,12288,16384",
+ "2048,4096,8192,16384,24576,32768",
+ "2048,4096,8192,16384,24576,32768"
+ };
+ private static final String[] presetsNames = {
+ "Very Light",
+ "Light",
+ "Medium",
+ "Aggressive",
+ "Very Aggressive"
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getActivity();
+ setHasOptionsMenu(true);
+ items = db.getAllItems();
+ color = getResources().getStringArray(R.array.menu_colors)[4];
+ Helpers.setPermissions(MINFREE_FILE);
+ setRetainInstance(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.lmk_layout, container,false);
+ list = (ListView) v.findViewById(R.id.list);
+ values = getMinFreeValues();
+ names = mContext.getResources().getStringArray(R.array.lmk_titles);
+ summaries = mContext.getResources().getStringArray(R.array.lmk_descs);
+ mAdapter = new CustomBaseAdapter(mContext,
+ values,
+ names,
+ summaries,
+ MINFREE_FILE,
+ color,
+ db);
+
+ list.setAdapter(mAdapter);
+ View footer = inflater.inflate(R.layout.lmk_footer, null, false);
+ LinearLayout ll = (LinearLayout) footer.findViewById(R.id.preset_layout);
+ addPresets(ll, inflater);
+
+ list.addFooterView(footer);
+ MainActivity.menu.toggle(true);
+ return v;
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.menu_lmk, menu);
+ boot = (MenuItem) menu.findItem(R.id.action_boot);
+ for (DataItem item : items) {
+ if(item.getName().contains(MINFREE_FILE)) {
+ boot.setChecked(true);
+ break;
+ }
+ boot.setChecked(false);
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+
+ case R.id.action_boot:
+ if(item.isChecked()) {
+ db.deleteItemByName("'"+MINFREE_FILE+"'");
+ item.setChecked(false);
+ }else {
+ db.deleteItemByName("'"+MINFREE_FILE+"'");
+ db.addItem(new DataItem("'"+MINFREE_FILE+"'",
+ buildString(mAdapter.getValues()),
+ "LOW MEMORY KILLER",
+ category));
+
+ item.setChecked(true);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private String[] getMinFreeValues() {
+ String content = Helpers.readFileViaShell(MINFREE_FILE, false);
+ Log.d("CONTENT", content);
+ String[] vals = content.trim().replace("\n", "").split(",");
+ return vals;
+ }
+
+ public String buildString(String[] values) {
+ String builded = "";
+ for(int i = 0; i<values.length; i++) {
+ if(i!=values.length-1) {
+ builded+=values[i]+",";
+ }else {
+ builded+=values[i];
+ }
+ }
+ return builded;
+ }
+
+ private void addPresets(LinearLayout ll, LayoutInflater inflater) {
+ for(int i = 0; i < presetsNames.length; i++) {
+ SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ View child = inflater.inflate(R.layout.list_item, null, false);
+ TextView title = (TextView) child.findViewById(android.R.id.text1);
+ final TextView summary = (TextView) child.findViewById(android.R.id.text2);
+ title.setText(presetsNames[i]);
+ summary.setText(presets[i]);
+
+ if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int color = mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ title.setTextColor(color);
+ }else if(mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_LMK, Color.parseColor("#ff0099cc"));
+ title.setTextColor(col);
+ }
+ else {
+ int color = Color.parseColor( mContext.getResources().getStringArray(R.array.menu_colors)[6]);
+ title.setTextColor(color);
+ }
+
+ child.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ // TODO Auto-generated method stub
+ CommandCapture command = new CommandCapture(0, "echo \""+ summary.getText().toString() + "\" > "+ MINFREE_FILE );
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ values = getMinFreeValues();
+ mAdapter = new CustomBaseAdapter(mContext,
+ values,
+ names,
+ summaries,
+ MINFREE_FILE,
+ color,
+ db);
+ list.setAdapter(mAdapter);
+ }
+
+ });
+ ll.addView(child);
+ }
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/PropModder.java b/src/com/dsht/kerneltweaker/fragments/PropModder.java
new file mode 100644
index 0000000..c975060
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/PropModder.java
@@ -0,0 +1,487 @@
+package com.dsht.kerneltweaker.fragments;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.text.InputFilter;
+import android.text.InputFilter.LengthFilter;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import java.io.BufferedOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileWriter;
+
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kernetweaker.cmdprocessor.CMDProcessor;
+
+
+public class PropModder extends PreferenceFragment implements
+Preference.OnPreferenceChangeListener {
+
+ private static final String TAG = "PropModder";
+ private static final String APPEND_CMD = "echo \"%s=%s\" >> /system/build.prop";
+ private static final String KILL_PROP_CMD = "busybox sed -i \"/%s/D\" /system/build.prop";
+ private static final String REPLACE_CMD = "busybox sed -i \"/%s/ c %<s=%s\" /system/build.prop";
+ private static final String REMOUNT_CMD = "busybox mount -o %s,remount -t yaffs2 /dev/block/mtdblock1 /system";
+ private static final String PROP_EXISTS_CMD = "grep -q %s /system/build.prop";
+ private static final String DISABLE = "disable";
+ private static final String SHOWBUILD_PATH = "/system/tmp/showbuild";
+ private static final String WIFI_SCAN_PREF = "pref_wifi_scan_interval";
+ private static final String WIFI_SCAN_PROP = "wifi.supplicant_scan_interval";
+ private static final String WIFI_SCAN_PERSIST_PROP = "persist.wifi_scan_interval";
+ private static final String WIFI_SCAN_DEFAULT = System.getProperty(WIFI_SCAN_PROP);
+ private static final String MAX_EVENTS_PREF = "pref_max_events";
+ private static final String MAX_EVENTS_PROP = "windowsmgr.max_events_per_sec";
+ private static final String MAX_EVENTS_PERSIST_PROP = "persist.max_events";
+ private static final String MAX_EVENTS_DEFAULT = System.getProperty(MAX_EVENTS_PROP);
+ private static final String USB_MODE_PROP = "ro.default_usb_mode";
+ private static final String USB_MODE_DEFAULT = System.getProperty(USB_MODE_PROP);
+ private static final String RING_DELAY_PREF = "pref_ring_delay";
+ private static final String RING_DELAY_PROP = "ro.telephony.call_ring.delay";
+ private static final String RING_DELAY_PERSIST_PROP = "persist.call_ring.delay";
+ private static final String RING_DELAY_DEFAULT = System.getProperty(RING_DELAY_PROP);
+ private static final String VM_HEAPSIZE_PREF = "pref_vm_heapsize";
+ private static final String VM_HEAPSIZE_PROP = "dalvik.vm.heapsize";
+ private static final String VM_HEAPSIZE_PERSIST_PROP = "persist.vm_heapsize";
+ private static final String VM_HEAPSIZE_DEFAULT = System.getProperty(VM_HEAPSIZE_PROP);
+ private static final String FAST_UP_PREF = "pref_fast_up";
+ private static final String FAST_UP_PROP = "ro.ril.hsxpa";
+ private static final String FAST_UP_PERSIST_PROP = "persist.fast_up";
+ private static final String FAST_UP_DEFAULT = System.getProperty(FAST_UP_PROP);
+ private static final String PROX_DELAY_PREF = "pref_prox_delay";
+ private static final String PROX_DELAY_PROP = "mot.proximity.delay";
+ private static final String PROX_DELAY_PERSIST_PROP = "persist.prox.delay";
+ private static final String PROX_DELAY_DEFAULT = System.getProperty(PROX_DELAY_PROP);
+ private static final String MOD_VERSION_PREF = "pref_mod_version";
+ private static final String MOD_VERSION_PROP = "ro.build.display.id";
+ private static final String MOD_VERSION_PERSIST_PROP = "persist.build.display.id";
+ private static final String MOD_VERSION_DEFAULT = System.getProperty(MOD_VERSION_PROP);
+
+ private static final String MOD_LCD_PROP = "ro.sf.lcd_density";
+ private static final String MOD_LCD_PREF = "pref_lcd_density";
+ private static final String MOD_LCD_PERSIST_PROP = "persist.lcd_density";
+
+ private static final String SLEEP_PREF = "pref_sleep";
+ private static final String SLEEP_PROP = "pm.sleep_mode";
+ private static final String SLEEP_PERSIST_PROP = "persist.sleep";
+ private static final String SLEEP_DEFAULT = System.getProperty(SLEEP_PROP);
+ private static final String TCP_STACK_PREF = "pref_tcp_stack";
+ private static final String TCP_STACK_PERSIST_PROP = "persist_tcp_stack";
+ private static final String TCP_STACK_PROP_0 = "net.tcp.buffersize.default";
+ private static final String TCP_STACK_PROP_1 = "net.tcp.buffersize.wifi";
+ private static final String TCP_STACK_PROP_2 = "net.tcp.buffersize.umts";
+ private static final String TCP_STACK_PROP_3 = "net.tcp.buffersize.gprs";
+ private static final String TCP_STACK_PROP_4 = "net.tcp.buffersize.edge";
+ private static final String TCP_STACK_BUFFER = "4096,87380,256960,4096,16384,256960";
+ private static final String JIT_PREF = "pref_jit";
+ private static final String JIT_PERSIST_PROP = "persist_jit";
+ private static final String JIT_PROP = "dalvik.vm.execution-mode";
+ private static final String THREE_G_PREF = "pref_g_speed";
+ private static final String THREE_G_PERSIST_PROP = "persist_3g_speed";
+ private static final String THREE_G_PROP_0 = "ro.ril.enable.3g.prefix";
+ private static final String THREE_G_PROP_1 = "ro.ril.hep";
+ private static final String THREE_G_PROP_2 = FAST_UP_PROP;
+ private static final String THREE_G_PROP_3 = "ro.ril.enable.dtm";
+ private static final String THREE_G_PROP_4 = "ro.ril.gprsclass";
+ private static final String THREE_G_PROP_5 = "ro.ril.hsdpa.category";
+ private static final String THREE_G_PROP_6 = "ro.ril.enable.a53";
+ private static final String THREE_G_PROP_7 = "ro.ril.hsupa.category";
+ private static final String GPU_PREF = "pref_gpu";
+ private static final String GPU_PERSIST_PROP = "persist_gpu";
+ private static final String GPU_PROP = "debug.sf.hw";
+
+ private ListPreference mWifiScanPref;
+ private ListPreference mMaxEventsPref;
+ private ListPreference mRingDelayPref;
+ private ListPreference mVmHeapsizePref;
+ private ListPreference mFastUpPref;
+ private ListPreference mProxDelayPref;
+ private EditTextPreference mModVersionPref;
+ private EditTextPreference mLcdPref;
+ private ListPreference mSleepPref;
+ private CheckBoxPreference mTcpStackPref;
+ private CheckBoxPreference mJitPref;
+ private CheckBoxPreference m3gSpeedPref;
+ private CheckBoxPreference mGpuPref;
+ private File tmpDir = new File("/system/tmp");
+ private File init_d = new File("/system/etc/init.d");
+
+ private boolean result = false;
+
+ //handler for command processor
+ private final CMDProcessor cmd = new CMDProcessor();
+ private PreferenceScreen prefSet;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.propmodder);
+ prefSet = getPreferenceScreen();
+
+ mWifiScanPref = (ListPreference) prefSet.findPreference(WIFI_SCAN_PREF);
+ mWifiScanPref.setOnPreferenceChangeListener(this);
+
+ mMaxEventsPref = (ListPreference) prefSet.findPreference(MAX_EVENTS_PREF);
+ mMaxEventsPref.setOnPreferenceChangeListener(this);
+
+ mRingDelayPref = (ListPreference) prefSet.findPreference(RING_DELAY_PREF);
+ mRingDelayPref.setOnPreferenceChangeListener(this);
+
+ mVmHeapsizePref = (ListPreference) prefSet.findPreference(VM_HEAPSIZE_PREF);
+ mVmHeapsizePref.setOnPreferenceChangeListener(this);
+
+ mFastUpPref = (ListPreference) prefSet.findPreference(FAST_UP_PREF);
+ mFastUpPref.setOnPreferenceChangeListener(this);
+
+ mProxDelayPref = (ListPreference) prefSet.findPreference(PROX_DELAY_PREF);
+ mProxDelayPref.setOnPreferenceChangeListener(this);
+
+ mSleepPref = (ListPreference) prefSet.findPreference(SLEEP_PREF);
+ mSleepPref.setOnPreferenceChangeListener(this);
+
+ mTcpStackPref = (CheckBoxPreference) prefSet.findPreference(TCP_STACK_PREF);
+
+ mJitPref = (CheckBoxPreference) prefSet.findPreference(JIT_PREF);
+
+ mModVersionPref = (EditTextPreference) prefSet.findPreference(MOD_VERSION_PREF);
+ String mod = Helpers.findBuildPropValueOf(MOD_VERSION_PROP);
+ if (mModVersionPref != null) {
+ EditText modET = mModVersionPref.getEditText();
+ if (modET != null){
+ InputFilter lengthFilter = new InputFilter.LengthFilter(100);
+ modET.setFilters(new InputFilter[]{lengthFilter});
+ modET.setSingleLine(true);
+ }
+ mModVersionPref.setSummary(String.format(getString(R.string.pref_mod_version_alt_summary), mod));
+ mModVersionPref.setText(mod);
+ }
+ //Log.d(TAG, String.format("ModPrefHoler = '%s' found build number = '%s'", mod));
+ mModVersionPref.setOnPreferenceChangeListener(this);
+
+ mLcdPref = (EditTextPreference) prefSet.findPreference(MOD_LCD_PREF);
+ String lcd = Helpers.findBuildPropValueOf(MOD_LCD_PROP);
+ if (mLcdPref != null) {
+ EditText lcdET = mLcdPref.getEditText();
+ if (lcdET != null){
+ InputFilter lengthFilter = new InputFilter.LengthFilter(3);
+ lcdET.setFilters(new InputFilter[]{lengthFilter});
+ lcdET.setSingleLine(true);
+ }
+ mLcdPref.setSummary(String.format(getString(R.string.pref_lcd_alt_summary), lcd));
+ mLcdPref.setText(lcd);
+ }
+ //Log.d(TAG, String.format("ModPrefHoler = '%s' found build number = '%s'", mod));
+ mLcdPref.setOnPreferenceChangeListener(this);
+
+ m3gSpeedPref = (CheckBoxPreference) prefSet.findPreference(THREE_G_PREF);
+
+ mGpuPref = (CheckBoxPreference) prefSet.findPreference(GPU_PREF);
+
+ updateScreen();
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle(true);
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ /* handle CheckBoxPreference clicks */
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+ boolean value;
+ if (preference == mTcpStackPref) {
+ Log.d(TAG, "mTcpStackPref.onPreferenceTreeClick()");
+ value = mTcpStackPref.isChecked();
+ return doMod(null, TCP_STACK_PROP_0, String.valueOf(value ? TCP_STACK_BUFFER : DISABLE))
+ && doMod(null, TCP_STACK_PROP_1, String.valueOf(value ? TCP_STACK_BUFFER : DISABLE))
+ && doMod(null, TCP_STACK_PROP_2, String.valueOf(value ? TCP_STACK_BUFFER : DISABLE))
+ && doMod(null, TCP_STACK_PROP_3, String.valueOf(value ? TCP_STACK_BUFFER : DISABLE))
+ && doMod(TCP_STACK_PERSIST_PROP, TCP_STACK_PROP_4, String.valueOf(value ? TCP_STACK_BUFFER : DISABLE));
+ } else if (preference == mJitPref) {
+ Log.d(TAG, "mJitPref.onPreferenceTreeClick()");
+ value = mJitPref.isChecked();
+ if(value)
+ //return doMod(JIT_PERSIST_PROP, JIT_PROP, String.valueOf(value ? "int:fast" : "int:jit"));
+ return doMod(JIT_PERSIST_PROP, JIT_PROP, "int:jit");
+ else if(!value) {
+ return doMod(JIT_PERSIST_PROP, JIT_PROP, "int:fast");
+ }
+ } else if (preference == m3gSpeedPref) {
+ value = m3gSpeedPref.isChecked();
+ return doMod(THREE_G_PERSIST_PROP, THREE_G_PROP_0, String.valueOf(value ? 1 : DISABLE))
+ && doMod(THREE_G_PERSIST_PROP, THREE_G_PROP_1, String.valueOf(value ? 1 : DISABLE))
+ && doMod(THREE_G_PERSIST_PROP, THREE_G_PROP_2, String.valueOf(value ? 2 : DISABLE))
+ && doMod(THREE_G_PERSIST_PROP, THREE_G_PROP_3, String.valueOf(value ? 1 : DISABLE))
+ && doMod(THREE_G_PERSIST_PROP, THREE_G_PROP_4, String.valueOf(value ? 12 : DISABLE))
+ && doMod(THREE_G_PERSIST_PROP, THREE_G_PROP_5, String.valueOf(value ? 8 : DISABLE))
+ && doMod(THREE_G_PERSIST_PROP, THREE_G_PROP_6, String.valueOf(value ? 1 : DISABLE))
+ && doMod(THREE_G_PERSIST_PROP, THREE_G_PROP_7, String.valueOf(value ? 5 : DISABLE));
+ } else if (preference == mGpuPref) {
+ value = mGpuPref.isChecked();
+ return doMod(GPU_PERSIST_PROP, GPU_PROP, String.valueOf(value ? 1 : DISABLE));
+ }
+
+ return false;
+ }
+
+ /* handle ListPreferences and EditTextPreferences */
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (newValue != null) {
+ Log.e(TAG, "New preference selected: " + newValue);
+ if (preference == mWifiScanPref) {
+ return doMod(WIFI_SCAN_PERSIST_PROP, WIFI_SCAN_PROP,
+ newValue.toString());
+ } else if (preference == mMaxEventsPref) {
+ return doMod(MAX_EVENTS_PERSIST_PROP, MAX_EVENTS_PROP,
+ newValue.toString());
+ } else if (preference == mRingDelayPref) {
+ return doMod(RING_DELAY_PERSIST_PROP, RING_DELAY_PROP,
+ newValue.toString());
+ } else if (preference == mVmHeapsizePref) {
+ return doMod(VM_HEAPSIZE_PERSIST_PROP, VM_HEAPSIZE_PROP,
+ newValue.toString());
+ } else if (preference == mFastUpPref) {
+ return doMod(FAST_UP_PERSIST_PROP, FAST_UP_PROP,
+ newValue.toString());
+ } else if (preference == mProxDelayPref) {
+ return doMod(PROX_DELAY_PERSIST_PROP, PROX_DELAY_PROP,
+ newValue.toString());
+ } else if (preference == mModVersionPref) {
+ return doMod(MOD_VERSION_PERSIST_PROP, MOD_VERSION_PROP,
+ newValue.toString());
+ }else if (preference == mLcdPref) {
+ return doMod(MOD_LCD_PERSIST_PROP, MOD_LCD_PROP,
+ newValue.toString());
+ } else if (preference == mSleepPref) {
+ return doMod(SLEEP_PERSIST_PROP, SLEEP_PROP,
+ newValue.toString());
+ }
+ }
+
+ return false;
+ }
+
+ /* method to handle mods */
+ private boolean doMod(final String persist, final String key, final String value) {
+
+ result = false;
+
+
+ class AsyncDoModTask extends AsyncTask<Void, Void, Boolean> {
+
+ ProgressDialog pd;
+
+ @Override
+ protected void onPreExecute() {
+ pd = new ProgressDialog(getActivity());
+ pd.setIndeterminate(true);
+ pd.setMessage("Applying values...Please wait");
+ pd.setCancelable(false);
+ pd.show();
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+
+ Log.d(TAG, String.format("Calling script with args '%s' and '%s'", key, value));
+ backupBuildProp();
+ if (!mount("rw")) {
+ throw new RuntimeException("Could not remount /system rw");
+ }
+ boolean success = false;
+ try {
+ if (!propExists(key) && value.equals(DISABLE)) {
+ Log.d(TAG, String.format("We want {%s} DISABLED however it doesn't exist so we do nothing and move on", key));
+ } else if (propExists(key)) {
+ if (value.equals(DISABLE)) {
+ Log.d(TAG, String.format("value == %s", DISABLE));
+ success = cmd.su.runWaitFor(String.format(KILL_PROP_CMD, key)).success();
+ } else {
+ Log.d(TAG, String.format("value != %s", DISABLE));
+ success = cmd.su.runWaitFor(String.format(REPLACE_CMD, key, value)).success();
+ }
+ } else {
+ Log.d(TAG, "append command starting");
+ success = cmd.su.runWaitFor(String.format(APPEND_CMD, key, value)).success();
+ }
+
+ } finally {
+
+ };
+
+ return success;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean res) {
+ // result holds what you return from doInBackground
+ super.onPostExecute(res);
+ result = res;
+ if (!res) {
+ restoreBuildProp();
+ } else {
+ updateScreen();
+ }
+ mount("ro");
+ pd.dismiss();
+ }
+ }
+ new AsyncDoModTask().execute();
+ return result;
+ }
+
+
+
+ public boolean mount(String read_value) {
+ Log.d(TAG, "Remounting /system " + read_value);
+ return cmd.su.runWaitFor(String.format(REMOUNT_CMD, read_value)).success();
+ }
+
+ public boolean propExists(String prop) {
+ Log.d(TAG, "Checking if prop " + prop + " exists in /system/build.prop");
+ return cmd.su.runWaitFor(String.format(PROP_EXISTS_CMD, prop)).success();
+ }
+
+ public void updateShowBuild() {
+ Log.d(TAG, "Setting up /system/tmp/showbuild");
+ try {
+ mount("rw");
+ cmd.su.runWaitFor("cp -f /system/build.prop " + SHOWBUILD_PATH).success();
+ cmd.su.runWaitFor("chmod 777 " + SHOWBUILD_PATH).success();
+ } finally {
+ mount("ro");
+ }
+ }
+
+ public boolean backupBuildProp() {
+ Log.d(TAG, "Backing up build.prop to /system/tmp/pm_build.prop");
+ return cmd.su.runWaitFor("cp /system/build.prop /system/tmp/pm_build.prop").success();
+ }
+
+ public boolean restoreBuildProp() {
+ Log.d(TAG, "Restoring build.prop from /system/tmp/pm_build.prop");
+ return cmd.su.runWaitFor("cp /system/tmp/pm_build.prop /system/build.prop").success();
+ }
+
+ public void updateScreen() {
+ //update all the summaries
+ String wifi = Helpers.findBuildPropValueOf(WIFI_SCAN_PROP);
+ if (!wifi.equals(DISABLE)) {
+ mWifiScanPref.setValue(wifi);
+ mWifiScanPref.setSummary(String.format(getString(R.string.pref_wifi_scan_alt_summary), wifi));
+ } else {
+ mWifiScanPref.setValue(WIFI_SCAN_DEFAULT);
+ }
+ String maxE = Helpers.findBuildPropValueOf(MAX_EVENTS_PROP);
+ if (!maxE.equals(DISABLE)) {
+ mMaxEventsPref.setValue(maxE);
+ mMaxEventsPref.setSummary(String.format(getString(R.string.pref_max_events_alt_summary), maxE));
+ } else {
+ mMaxEventsPref.setValue(MAX_EVENTS_DEFAULT);
+ }
+ String ring = Helpers.findBuildPropValueOf(RING_DELAY_PROP);
+ if (!ring.equals(DISABLE)) {
+ mRingDelayPref.setValue(ring);
+ mRingDelayPref.setSummary(String.format(getString(R.string.pref_ring_delay_alt_summary), ring));
+ } else {
+ mRingDelayPref.setValue(RING_DELAY_DEFAULT);
+ }
+ String vm = Helpers.findBuildPropValueOf(VM_HEAPSIZE_PROP);
+ if (!vm.equals(DISABLE)) {
+ mVmHeapsizePref.setValue(vm);
+ mVmHeapsizePref.setSummary(String.format(getString(R.string.pref_vm_heapsize_alt_summary), vm));
+ } else {
+ mVmHeapsizePref.setValue(VM_HEAPSIZE_DEFAULT);
+ }
+ String fast = Helpers.findBuildPropValueOf(FAST_UP_PROP);
+ if (!fast.equals(DISABLE)) {
+ mFastUpPref.setValue(fast);
+ mFastUpPref.setSummary(String.format(getString(R.string.pref_fast_up_alt_summary), fast));
+ } else {
+ mFastUpPref.setValue(FAST_UP_DEFAULT);
+ }
+ String prox = Helpers.findBuildPropValueOf(PROX_DELAY_PROP);
+ if (!prox.equals(DISABLE)) {
+ mProxDelayPref.setValue(prox);
+ mProxDelayPref.setSummary(String.format(getString(R.string.pref_prox_delay_alt_summary), prox));
+ } else {
+ mProxDelayPref.setValue(PROX_DELAY_DEFAULT);
+ }
+ String sleep = Helpers.findBuildPropValueOf(SLEEP_PROP);
+ if (!sleep.equals(DISABLE)) {
+ mSleepPref.setValue(sleep);
+ mSleepPref.setSummary(String.format(getString(R.string.pref_sleep_alt_summary), sleep));
+ } else {
+ mSleepPref.setValue(SLEEP_DEFAULT);
+ }
+ String tcp = Helpers.findBuildPropValueOf(TCP_STACK_PROP_0);
+ if (tcp.equals(TCP_STACK_BUFFER)) {
+ mTcpStackPref.setChecked(true);
+ } else {
+ mTcpStackPref.setChecked(false);
+ }
+ String jit = Helpers.findBuildPropValueOf(JIT_PROP);
+ if (jit.equals("int:jit")) {
+ mJitPref.setChecked(true);
+ } else {
+ mJitPref.setChecked(false);
+ }
+ String mod = Helpers.findBuildPropValueOf(MOD_VERSION_PROP);
+ mModVersionPref.setSummary(String.format(getString(R.string.pref_mod_version_alt_summary), mod));
+
+ String lcd = Helpers.findBuildPropValueOf(MOD_LCD_PROP);
+ mLcdPref.setSummary(String.format(getString(R.string.pref_lcd_alt_summary), lcd));
+
+ String g0 = Helpers.findBuildPropValueOf(THREE_G_PROP_0);
+ String g3 = Helpers.findBuildPropValueOf(THREE_G_PROP_3);
+ String g6 = Helpers.findBuildPropValueOf(THREE_G_PROP_6);
+ if (g0.equals("1") && g3.equals("1") && g6.equals("1")) {
+ m3gSpeedPref.setChecked(true);
+ } else {
+ m3gSpeedPref.setChecked(false);
+ }
+ String gpu = Helpers.findBuildPropValueOf(GPU_PROP);
+ if (!gpu.equals(DISABLE)) {
+ mGpuPref.setChecked(true);
+ } else {
+ mGpuPref.setChecked(false);
+ }
+ }
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/ReviewBootPreferenceFragment.java b/src/com/dsht/kerneltweaker/fragments/ReviewBootPreferenceFragment.java
new file mode 100644
index 0000000..bfa2f0a
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/ReviewBootPreferenceFragment.java
@@ -0,0 +1,523 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import com.dsht.kerneltweaker.CustomListPreference;
+import com.dsht.kerneltweaker.CustomPreference;
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.ListViewMultiChoiceModeListener;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.SwipeDismissListViewTouchListener;
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.kerneltweaker.database.VddDatabaseHandler;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceScreen;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.EditText;
+import android.widget.ListView;
+
+public class ReviewBootPreferenceFragment extends PreferenceFragment {
+
+ private DatabaseHandler db;
+ private VddDatabaseHandler VddDb;
+ private List<DataItem> items;
+ private List<DataItem> vddItems;
+ private PreferenceScreen mRoot;
+ private Context mContext;
+ private PreferenceCategory mCpu;
+ private PreferenceCategory mGpu;
+ private PreferenceCategory mUv;
+ private PreferenceCategory mKernel;
+ private PreferenceCategory mLmk;
+ private PreferenceCategory mGov;
+ private PreferenceCategory mSched;
+ private PreferenceCategory mQuiet;
+ private PreferenceCategory mVm;
+
+ private static final String cpuCat = "cpu";
+ private static final String gpuCat = "gpu";
+ private static final String uvCat ="uv";
+ private static final String kernelCat = "kernel";
+ private static final String LmkCat = "lmk";
+ private static final String GovCat = "governor";
+ private static final String SchedCat ="scheduler";
+ private static final String QuietCat ="cpuquiet";
+ private static final String vmCat = "vm";
+
+ private ListView listView;
+ private SwipeDismissListViewTouchListener touchListener;
+ private MenuItem edit;
+ String[] frequencies;
+ String[] names;
+ String[] governors;
+ String[] gpuFrequencies;
+ String[] schedulers;
+ String[] cpuquiet_govs;
+ String[] availTCP;
+ String[] readAheadKb = {"128","256","384","512","640","768","896","1024","1152",
+ "1280","1408","1536","1664","1792","1920","2048", "2176", "2304", "2432", "2560",
+ "2688", "2816", "2944", "3072", "3200", "3328", "3456", "3584", "3712", "3840", "3968", "4096"};
+ private static final String GPU_FREQUENCIES_FILE = "/sys/class/kgsl/kgsl-3d0/gpu_available_frequencies";
+ private static final String SCHEDULER_FILE = "/sys/block/mmcblk0/queue/scheduler";
+ private static final String READ_AHEAD_FILE = "/sys/block/mmcblk0/queue/read_ahead_kb";
+ private static final String CPUQUIET_DIR = "/sys/devices/system/cpu/cpuquiet";
+ private static final String CPUQUIET_FILE = "/sys/devices/system/cpu/cpuquiet/current_governor";
+ private static final String CPUQUIET_GOVERNORS = "/sys/devices/system/cpu/cpuquiet/available_governors";
+ private static final String TCP_OPTIONS = "sysctl net.ipv4.tcp_available_congestion_control";
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.pref_screen_review);
+ mRoot = (PreferenceScreen) findPreference("key_pref_screen");
+ mContext = getActivity();
+ mCpu = (PreferenceCategory) findPreference("cat_cpu");
+ mGpu = (PreferenceCategory) findPreference("cat_gpu");
+ mUv = (PreferenceCategory) findPreference("cat_uv");
+ mKernel = (PreferenceCategory) findPreference("cat_kernel");
+ mLmk = (PreferenceCategory) findPreference("cat_lmk");
+ mGov = (PreferenceCategory) findPreference("cat_gov");
+ mSched = (PreferenceCategory) findPreference("cat_sched");
+ mQuiet = (PreferenceCategory) findPreference("cat_quiet");
+ mVm= (PreferenceCategory) findPreference("cat_vm");
+ setHasOptionsMenu(true);
+
+ Helpers.setPermissions(CPUQUIET_FILE);
+ Helpers.setPermissions(GPU_FREQUENCIES_FILE);
+ Helpers.setPermissions(READ_AHEAD_FILE);
+ Helpers.setPermissions(CPUQUIET_DIR);
+ Helpers.setPermissions(CPUQUIET_GOVERNORS);
+
+ frequencies = Helpers.getFrequencies();
+ names = Helpers.getFrequenciesNames();
+ governors = Helpers.getGovernors();
+ String gpu = Helpers.getFileContent(new File(GPU_FREQUENCIES_FILE));
+ gpuFrequencies = gpu.split(" ");
+ String[] gpuNames = Helpers.getFreqToMhz(GPU_FREQUENCIES_FILE);
+ schedulers = Helpers.getAvailableSchedulers();
+ db = new DatabaseHandler(mContext);
+ VddDb = new VddDatabaseHandler(mContext);
+ items = db.getAllItems();
+ vddItems = VddDb.getAllItems();
+
+ if(new File(CPUQUIET_DIR).exists()) {
+ String cpuquiet = Helpers.getFileContent(new File(CPUQUIET_GOVERNORS));
+ cpuquiet_govs = cpuquiet.trim().replaceAll("\n", "").split(" ");
+ }
+
+ if(items.size() != 0) {
+ for(DataItem item : items) {
+ String fPath = item.getName().replaceAll("'", "");
+ String fName = item.getFileName();
+ Log.d("PATH", fPath);
+ String value = item.getValue();
+ String category = item.getCategory();
+ if(category.equals(cpuCat)) {
+ String color = getColor(2);
+ if(fName.contains("CPU Max Frequency")) {
+ createListPreference(mCpu,fPath,fName,value,frequencies, names,color,category,false);
+ }
+ else if(fName.contains("CPU Min Frequency")) {
+ createListPreference(mCpu,fPath,fName,value,frequencies, names,color,category,false);
+ }
+ else if(fName.contains("Governor")) {
+ createListPreference(mCpu,fPath,fName,value,governors, governors,color,category,false);
+ } else if(fName.contains("Cpuquiet")) {
+ createListPreference(mCpu,fPath,fName,value,cpuquiet_govs,cpuquiet_govs,color,category,false);
+ }else {
+ createPreference(mCpu,fPath, fName, value, color, category, false);
+ }
+ }
+ else if (category.equals(gpuCat)) {
+ String color = getColor(3);
+ if(fName.contains("GPU Max Frequency")) {
+ createListPreference(mGpu,fPath, fName, value, gpuFrequencies, gpuNames, color, category, false);
+ }else {
+ createPreference(mGpu,fPath, fName, value, color, category, false);
+ }
+ }
+ else if(category.equals(uvCat)) {
+ String color = getColor(4);
+ createPreference(mUv,fPath, fName, value, color, category, false);
+ }
+ else if(category.equals(kernelCat)) {
+ String color = getColor(5);
+ if(fName.contains("I/O Scheduler")) {
+ createListPreference(mKernel,fPath, fName, value, schedulers, schedulers, color, category, false);
+ }else if(fName.contains("Read Ahead size")) {
+ createListPreference(mKernel,fPath, fName, value, readAheadKb,readAheadKb, color, category, false);
+ }else if(fName.contains("TCP Congestion control")) {
+ String[] availTCP = Helpers.readCommandStrdOut(TCP_OPTIONS, false).replaceAll("net.ipv4.tcp_available_congestion_control = ", "").replaceAll("\n", "").split(" ");
+ createListPreference(mKernel, fPath, fName, value, availTCP, availTCP, color, category, false);
+ }
+ else {
+ createPreference(mKernel,fPath, fName, value, color, category, false);
+ }
+ }
+ else if(category.equals(LmkCat)) {
+ String color = getColor(6);
+ createPreference(mLmk,fPath, fName, value, color, category, false);
+ }
+ else if(category.equals(GovCat)) {
+ String color = getColor(12);
+ createPreference(mGov,fPath, fName, value, color, category, false);
+ }
+ else if(category.equals(SchedCat)) {
+ String color = getColor(12);
+ createPreference(mSched,fPath, fName, value, color, category, false);
+ }
+ else if(category.equals(QuietCat)) {
+ String color = getColor(12);
+ createPreference(mQuiet,fPath, fName, value, color, category, false);
+ }
+ else if(category.equals(vmCat)) {
+ String color = getColor(7);
+ createPreference(mVm,fPath, fName, value, color, category, false);
+ }
+
+ }
+ }
+
+ if(vddItems.size() != 0) {
+ String color = getResources().getStringArray(R.array.menu_colors)[2];
+ createPreference(mUv,"",
+ getResources().getString(R.string.vdd_pref),
+ getResources().getString(R.string.vdd_desc),
+ color,
+ "uv",
+ true);
+ }
+
+ checkEmpty();
+ if(mRoot.getPreferenceCount() == 0) {
+ addEmptyView();
+ }
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle(true);
+ }
+ setRetainInstance(true);
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenu.ContextMenuInfo menuInfo) {
+ getActivity().getMenuInflater().inflate(R.menu.main, menu);
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ return super.onContextItemSelected(item);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list, container,false);
+
+ listView = (ListView) v.findViewById(android.R.id.list);
+ listView.setFastScrollEnabled(true);
+ listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ registerForContextMenu(listView);
+ listView.setMultiChoiceModeListener(new ListViewMultiChoiceModeListener(
+ mContext,getActivity(),
+ listView,mRoot,
+ mCpu,
+ mGpu,
+ mUv,
+ mKernel,
+ mLmk,
+ mGov,
+ mSched,
+ mQuiet,
+ mVm,
+ db,
+ VddDb,
+ true));
+
+
+ return v;
+ }
+
+
+ private void createPreference(PreferenceCategory mCategory,
+ String fPath, String fName, String value, String color,
+ final String category, boolean excludeEdit) {
+
+ final CustomPreference pref = new CustomPreference(mContext, false, category);
+ pref.setTitle(fName);
+ pref.setTitleColor(color);
+ pref.setSummary(value);
+ pref.setKey(fPath);
+ pref.hideBoot(true);
+ Log.d("CONTENT", value);
+ mCategory.addPreference(pref);
+ if(!excludeEdit) {
+ pref.setOnPreferenceClickListener(new OnPreferenceClickListener(){
+
+ @Override
+ public boolean onPreferenceClick(final Preference p) {
+ // TODO Auto-generated method stub
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View v = inflater.inflate(R.layout.dialog_layout, null, false);
+ final EditText et = (EditText) v.findViewById(R.id.et);
+ String val = p.getSummary().toString();
+ et.setText(val);
+ //et.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+ et.setGravity(Gravity.CENTER_HORIZONTAL);
+ db.getAllItems();
+ builder.setView(v);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ String value = et.getText().toString();
+ p.setSummary(value);
+ Log.d("TEST", "echo "+value+" > "+ p.getKey());
+ CommandCapture command = new CommandCapture(0,"echo \""+value+"\" > "+p.getKey());
+ try {
+ RootTools.getShell(true).add(command);
+ updateDb(p, value, true, category);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ } );
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ return true;
+ }
+
+ });
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mRoot.removeAll();
+ }
+
+
+ private void createListPreference(PreferenceCategory mCategory,
+ String fPath, String fName, String value,String[] entries, String[] names, String color,
+ final String category, boolean excludeEdit) {
+
+ final CustomListPreference pref = new CustomListPreference(mContext, category);
+ pref.setTitle(fName);
+ pref.setTitleColor(color);
+ pref.setSummary(value);
+ pref.setEntries(names);
+ pref.setEntryValues(entries);
+ pref.hideBoot(true);
+ pref.setKey(fPath);
+ Log.d("CONTENT", value);
+ mCategory.addPreference(pref);
+ if(!excludeEdit) {
+ pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener(){
+
+ @Override
+ public boolean onPreferenceChange(final Preference p, Object newValue) {
+ // TODO Auto-generated method stub
+ p.setSummary((String)newValue);
+ pref.setValue(p.getSummary().toString());
+ Log.d("TEST", "echo "+(String)newValue+" > "+ p.getKey());
+ CommandCapture command = new CommandCapture(0,"echo \""+(String)newValue+"\" > "+p.getKey());
+ try {
+ RootTools.getShell(true).add(command);
+ updateDb(p, (String)newValue, true, category);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ });
+ }
+ }
+
+
+
+ private void updateDb(final Preference p, final String value,final boolean isChecked, final String category) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ if(isChecked) {
+ List<DataItem> items = db.getAllItems();
+ for(DataItem item : items) {
+ if(item.getName().equals("'"+p.getKey()+"'")) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+ if(p.getTitle().toString().contains("TCP")) {
+ db.addItem(new DataItem("'"+"sysctl -w net.ipv4.tcp_congestion_control="+value+"'", value, p.getTitle().toString(), category));
+ } else {
+ db.addItem(new DataItem("'"+p.getKey()+"'", value, p.getTitle().toString(), category));
+ }
+ } else {
+ if(db.getContactsCount() != 0) {
+ db.deleteItemByName("'"+p.getKey()+"'");
+ }
+ }
+
+ return "Executed";
+ }
+ @Override
+ protected void onPostExecute(String result) {
+
+ }
+ }
+ new LongOperation().execute();
+ }
+
+ public void addEmptyView() {
+ mRoot.removeAll();
+ CustomPreference pref = new CustomPreference(mContext, true, "");
+ pref.setTitle("EMPTY");
+ pref.setSummary("No Values set at boot");
+ String color = getResources().getStringArray(R.array.menu_colors)[8];
+ pref.setTitleColor(color);
+ pref.setSummaryColor(color);
+ pref.hideBoot(true);
+ mRoot.addPreference(pref);
+ }
+
+
+
+
+ private void checkEmpty() {
+
+ if(mCpu.getPreferenceCount() == 0) {
+ mRoot.removePreference(mCpu);
+ }
+ if(mGpu.getPreferenceCount() == 0) {
+ mRoot.removePreference(mGpu);
+ }
+ if(mUv.getPreferenceCount() == 0) {
+ mRoot.removePreference(mUv);
+ }
+ if(mKernel.getPreferenceCount() == 0) {
+ mRoot.removePreference(mKernel);
+ }
+ if(mLmk.getPreferenceCount() == 0) {
+ mRoot.removePreference(mLmk);
+ }
+ if(mGov.getPreferenceCount() == 0) {
+ mRoot.removePreference(mGov);
+ }
+ if(mSched.getPreferenceCount() == 0) {
+ mRoot.removePreference(mSched);
+ }
+ if(mQuiet.getPreferenceCount() == 0) {
+ mRoot.removePreference(mQuiet);
+ }
+ if(mVm.getPreferenceCount()==0) {
+ mRoot.removePreference(mVm);
+ }
+ }
+
+ private String getColor(int pos) {
+ String color = "";
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FF0099cc"));
+ color = "#"+Integer.toHexString(col);
+ }else if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int col = Color.parseColor("#ff0099cc");
+ switch(pos) {
+ case 0:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_STAT, Color.parseColor("#FFFFFF"));
+ break;
+ case 1:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_INFO, Color.parseColor("#FFFFFF"));
+ break;
+ case 2:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_CPU, Color.parseColor("#FFFFFF"));
+ break;
+ case 3:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GPU, Color.parseColor("#FFFFFF"));
+ break;
+ case 4:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_UV, Color.parseColor("#FFFFFF"));
+ break;
+ case 5:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_KERNEL, Color.parseColor("#FFFFFF"));
+ break;
+ case 6:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_LMK, Color.parseColor("#FFFFFF"));
+ break;
+ case 7:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_VM, Color.parseColor("#FFFFFF"));
+ break;
+ case 8:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_REVIEW, Color.parseColor("#FFFFFF"));
+ break;
+ case 9:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_FILE, Color.parseColor("#FFFFFF"));
+ break;
+ case 10:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_BAK, Color.parseColor("#FFFFFF"));
+ break;
+ case 11:
+ col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_RECOVERY, Color.parseColor("#FFFFFF"));
+ break;
+ }
+ color = "#"+Integer.toHexString(col);
+ }
+ else {
+ color = getResources().getStringArray(R.array.menu_colors)[pos];
+ }
+ return color;
+ }
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/UvPreferenceFragment.java b/src/com/dsht/kerneltweaker/fragments/UvPreferenceFragment.java
new file mode 100644
index 0000000..6f96f89
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/UvPreferenceFragment.java
@@ -0,0 +1,466 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.text.InputType;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.view.View.OnClickListener;
+import android.view.WindowManager.LayoutParams;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+
+import com.dsht.kerneltweaker.CustomPreference;
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.database.DataItem;
+import com.dsht.kerneltweaker.database.DatabaseHandler;
+import com.dsht.kerneltweaker.database.VddDatabaseHandler;
+import com.dsht.settings.SettingsFragment;
+import com.stericson.RootTools.RootTools;
+import com.stericson.RootTools.exceptions.RootDeniedException;
+import com.stericson.RootTools.execution.CommandCapture;
+
+public class UvPreferenceFragment extends PreferenceFragment {
+
+ private PreferenceCategory mCategory;
+ private Context mContext;
+ private String[] names;
+ private String[] values;
+ private LinearLayout mButtonLayout;
+ private Button mButtonApply;
+ private Button mButtonCancel;
+ private String UV_TABLE_FILE = "/sys/devices/system/cpu/cpu0/cpufreq/UV_mV_table";
+ private String category = "uv";
+ private DatabaseHandler db = MainActivity.db;
+ private VddDatabaseHandler VddDb = MainActivity.vddDb;
+ private List<DataItem> items;
+ private List<DataItem> vddItems;
+ private MenuItem boot;
+ private boolean isVdd = false;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ init();
+ items = db.getAllItems();
+ vddItems = VddDb.getAllItems();
+
+ if(Helpers.UvTableExists(UV_TABLE_FILE)) {
+ if(mCategory.getPreferenceCount() != 0) {
+ mCategory.removeAll();
+ }
+ MainActivity.menu.setEnabled(false);
+ addPreferences(true);
+ isVdd = false;
+ } else {
+ if(Helpers.UvTableExists("/sys/devices/system/cpu/cpufreq/vdd_table/vdd_levels")) {
+ if(mCategory.getPreferenceCount() != 0) {
+ mCategory.removeAll();
+ }
+ MainActivity.menu.setEnabled(false);
+ UV_TABLE_FILE = "/sys/devices/system/cpu/cpufreq/vdd_table/vdd_levels";
+ addPreferences(false);
+ isVdd = true;
+ } else {
+ if(mCategory.getPreferenceCount() != 0) {
+ mCategory.removeAll();
+ }
+ CustomPreference pref = new CustomPreference(mContext, true, category);
+ pref.setTitle("Your Device Doesn\'t support UV");
+ pref.hideBoot(true);
+ pref.setSummary("You need a custom kernel that supports UnderVolt");
+ pref.setTitleColor("#ff4444");
+ pref.setSummaryColor("#ff4444");
+ mCategory.addPreference(pref);
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle();
+ }
+ }
+
+ }
+ setRetainInstance(true);
+
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list, container,false);
+
+ final ListView list = (ListView) v.findViewById(android.R.id.list);
+
+ mButtonLayout = (LinearLayout) v.findViewById(R.id.btn_layout);
+ mButtonApply = (Button) v.findViewById(R.id.btn_apply);
+ mButtonCancel = (Button) v.findViewById(R.id.btn_cancel);
+
+ mButtonCancel.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View arg0) {
+ // TODO Auto-generated method stub
+ for (int i = 0; i < mCategory.getPreferenceCount(); i++) {
+ CustomPreference pref = (CustomPreference) mCategory.getPreference(i);
+ pref.restoreSummaryKey(values[i], values[i]);
+ }
+ mButtonLayout.setVisibility(View.GONE);
+ list.bringToFront();
+ }
+
+ });
+
+ mButtonApply.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View arg0) {
+ // TODO Auto-generated method stub
+ if(isVdd) {
+ for(int i = 0; i<mCategory.getPreferenceCount(); i++) {
+ CustomPreference pref = (CustomPreference) mCategory.getPreference(i);
+ String value = "'"+pref.getTitle().toString()+" "+pref.getSummary().toString()+"'";
+ applyVddUV(value);
+ Log.d("VALUE", value);
+ }
+
+
+ } else {
+ String[] newValues = new String[values.length];
+ for (int i = 0; i < mCategory.getPreferenceCount(); i++) {
+ CustomPreference pref = (CustomPreference) mCategory.getPreference(i);
+ newValues[i] = pref.getKey();
+ values[i] = pref.getKey();
+
+ }
+ Log.d("newValues", buildTable(newValues));
+ CommandCapture command = new CommandCapture(0,"echo \""+buildTable(values)+"\" > "+UV_TABLE_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+ if(boot.isChecked()) {
+ db.deleteItemByName("'"+UV_TABLE_FILE+"'");
+ db.addItem(new DataItem("'"+UV_TABLE_FILE+"'",
+ buildTable(values),
+ "UV Table",
+ category));
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ mButtonLayout.setVisibility(View.GONE);
+ list.bringToFront();
+ }
+
+ });
+ return v;
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ if(Helpers.UvTableExists(UV_TABLE_FILE)) {
+ inflater.inflate(R.menu.menu_uv, menu);
+ boot = (MenuItem) menu.findItem(R.id.action_boot);
+ if(isVdd) {
+ if(vddItems.size() != 0) {
+ boot.setChecked(true);
+ }else {
+ boot.setChecked(false);
+ }
+ } else {
+ for (DataItem item : items) {
+ if(item.getName().contains(UV_TABLE_FILE)) {
+ boot.setChecked(true);
+ break;
+ }
+ boot.setChecked(false);
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int prefsIndex = mCategory.getPreferenceCount();
+ switch (item.getItemId()) {
+ case R.id.action_plus:
+ for (int i = 0; i< prefsIndex; i++) {
+ CustomPreference pref = (CustomPreference) mCategory.getPreference(i);
+ if(isVdd) {
+ pref.setCustomSummaryKeyPlus(25000);
+ } else {
+ pref.setCustomSummaryKeyPlus(25);
+ }
+ if (!pref.getKey().equals(values[i])) {
+ mButtonLayout.setVisibility(View.VISIBLE);
+ } else {
+ mButtonLayout.setVisibility(View.GONE);
+ }
+ }
+ return true;
+ case R.id.action_minus:
+ for (int i = 0; i< prefsIndex; i++) {
+ CustomPreference pref = (CustomPreference) mCategory.getPreference(i);
+ if(isVdd) {
+ pref.setCustomSummaryKeyMinus(25000);
+ }else {
+ pref.setCustomSummaryKeyMinus(25);
+ }
+ if (!pref.getKey().equals(values[i])) {
+ mButtonLayout.setVisibility(View.VISIBLE);
+ } else {
+ mButtonLayout.setVisibility(View.GONE);
+ }
+ }
+ return true;
+ case R.id.action_boot:
+ if(item.isChecked()) {
+ if(isVdd) {
+ VddDb.deleteAllItems();
+ } else {
+ db.deleteItemByName("'"+UV_TABLE_FILE+"'");
+ }
+ item.setChecked(false);
+ }else {
+ if(isVdd) {
+ addVddBoot();
+ } else {
+ db.deleteItemByName("'"+UV_TABLE_FILE+"'");
+ db.addItem(new DataItem("'"+UV_TABLE_FILE+"'",
+ buildTable(values),
+ "UV Table",
+ category));
+ }
+ item.setChecked(true);
+ }
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ public void addPreferences(final boolean millivolts) {
+
+ class LongOperation extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ names = Helpers.getUvTableNames();
+ values = Helpers.getUvValues();
+ Log.d("table", buildTable(values));
+ for(int i = 0; i<names.length; i++) {
+ String name = names[i];
+ final int j = i;
+ CustomPreference pref = new CustomPreference(mContext, false, category);
+ pref.setTitle(name);
+ pref.areMilliVolts(millivolts);
+ pref.hideBoot(true);
+ String color = "";
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#ff0099cc"));
+ color = "#"+Integer.toHexString(col);
+ }else if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_UV, Color.parseColor("#ff0099cc"));
+ color = "#"+Integer.toHexString(col);
+ }
+ else {
+ color = getResources().getStringArray(R.array.menu_colors)[4];
+ }
+ pref.setTitleColor(color);
+ if(isVdd){
+ pref.setSummary(values[i]);
+ }else {
+ pref.setSummary(values[i]+ " mV");
+ }
+ pref.setKey(values[i]);
+ mCategory.addPreference(pref);
+ pref.setOnPreferenceClickListener(new OnPreferenceClickListener(){
+
+ @Override
+ public boolean onPreferenceClick(final Preference p) {
+ // TODO Auto-generated method stub
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ LinearLayout ll = new LinearLayout(mContext);
+ ll.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
+ final EditText et = new EditText(mContext);
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ params.setMargins(40, 40, 40, 40);
+ params.gravity = Gravity.CENTER;
+ final String val = p.getKey().toString();
+ et.setLayoutParams(params);
+ et.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+ et.setGravity(Gravity.CENTER_HORIZONTAL);
+ et.setText(val);
+ ll.addView(et);
+ builder.setView(ll);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ if(isVdd) {
+ String value = "'"+p.getTitle().toString()+" "+et.getText().toString()+"'";
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+UV_TABLE_FILE);
+ p.setSummary(et.getText().toString());
+ p.setKey(et.getText().toString());
+ try {
+ RootTools.getShell(true).add(command);
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ } else {
+ String value = et.getText().toString();
+ p.setSummary(value+" mV");
+ p.setKey(value);
+ values[j] = value;
+ Log.d("NEWTABLE", buildTable(values));
+ Log.d("COMMAND", "echo \""+buildTable(values)+"\" > "+UV_TABLE_FILE);
+
+ CommandCapture command = new CommandCapture(0,"echo \""+buildTable(values)+"\" > "+UV_TABLE_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ if(boot.isChecked()) {
+ if(isVdd) {
+ addVddBoot();
+ } else {
+ db.deleteItemByName("'"+UV_TABLE_FILE+"'");
+ db.addItem(new DataItem("'"+UV_TABLE_FILE+"'",
+ buildTable(values),
+ "UV Table",
+ category));
+ }
+ }
+
+ }
+ } );
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
+ Window window = dialog.getWindow();
+ window.setLayout(800, LayoutParams.WRAP_CONTENT);
+ return true;
+ }
+ });
+
+ }
+ return "Executed";
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ Helpers.waitForMillis(500, mContext);
+ MainActivity.menu.setEnabled(true);
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle();
+ }
+
+ }
+
+ @Override
+ protected void onPreExecute() {
+
+ }
+
+
+ }
+ new LongOperation().execute();
+ }
+
+ private String buildTable(String[] vals) {
+ String newTable="";
+ for(int j = 0; j<vals.length; j++) {
+ if(j!= vals.length-1) {
+ newTable+=vals[j]+" ";
+ }else{
+ newTable+=vals[j];
+ }
+ }
+ return newTable;
+ }
+
+ public void init() {
+ addPreferencesFromResource(R.xml.pref_sccreen_uv);
+ mContext = getActivity();
+ mCategory = (PreferenceCategory) findPreference("key_uv_category");
+ }
+
+ private void applyVddUV(String value) {
+
+ CommandCapture command = new CommandCapture(0,"echo "+value+" > "+UV_TABLE_FILE);
+ try {
+ RootTools.getShell(true).add(command);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RootDeniedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ private void addVddBoot() {
+ VddDb.deleteAllItems();
+ for(int i = 0; i<mCategory.getPreferenceCount(); i++) {
+ CustomPreference pref = (CustomPreference)mCategory.getPreference(i);
+ String value = "'"+pref.getTitle().toString()+" "+pref.getSummary().toString()+"'";
+ VddDb.addItem(new DataItem("'"+UV_TABLE_FILE+"'", value, "vdd_levels", category));
+ }
+ }
+
+}
diff --git a/src/com/dsht/kerneltweaker/fragments/WallpaperEffectsFragment.java b/src/com/dsht/kerneltweaker/fragments/WallpaperEffectsFragment.java
new file mode 100644
index 0000000..f08d52b
--- /dev/null
+++ b/src/com/dsht/kerneltweaker/fragments/WallpaperEffectsFragment.java
@@ -0,0 +1,138 @@
+package com.dsht.kerneltweaker.fragments;
+
+import java.io.IOException;
+
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+
+import android.app.Fragment;
+import android.app.WallpaperManager;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.v8.renderscript.*;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+
+public class WallpaperEffectsFragment extends Fragment implements OnSeekBarChangeListener, OnClickListener {
+
+ private ImageView mWall;
+ private SeekBar mBlur;
+ private Button mApply;
+ private Bitmap source;
+ private WallpaperManager wallpaperManager;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle(true);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.wallpaper_effects, container,false);
+
+ mWall = (ImageView) v.findViewById(R.id.wall);
+ mBlur = (SeekBar) v.findViewById(R.id.sb_blur);
+ mApply = (Button) v.findViewById(R.id.btn_apply);
+ mWall.setDrawingCacheEnabled(true);
+ mBlur.setMax(25);
+
+ mBlur.setOnSeekBarChangeListener(this);
+ mApply.setOnClickListener(this);
+
+ wallpaperManager = WallpaperManager.getInstance(getActivity());
+ final Drawable wallpaperDrawable = wallpaperManager.getDrawable();
+
+ mWall.setImageDrawable(wallpaperDrawable);
+
+ source = drawableToBitmap(wallpaperDrawable);
+
+ return v;
+ }
+
+ @Override
+ public void onClick(View v) {
+ // TODO Auto-generated method stub
+ switch(v.getId()) {
+ case R.id.btn_apply:
+ try {
+ wallpaperManager.setBitmap(mWall.getDrawingCache());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ break;
+ }
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar arg0) {
+ // TODO Auto-generated method stub
+ int rad = arg0.getProgress();
+ if(rad == 0) {
+ mWall.setImageBitmap(source);
+ }else {
+ Bitmap blurred = BlurImage(source, rad);
+ mWall.setImageBitmap(blurred);
+ }
+
+ }
+
+ public static Bitmap drawableToBitmap (Drawable drawable) {
+ if (drawable instanceof BitmapDrawable) {
+ return ((BitmapDrawable)drawable).getBitmap();
+ }
+
+ Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+
+ return bitmap;
+ }
+
+
+ private Bitmap BlurImage (Bitmap input, int radius)
+ {
+ RenderScript rsScript = RenderScript.create(getActivity());
+ Allocation alloc = Allocation.createFromBitmap(rsScript, input);
+
+ ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rsScript,Element.U8_4(rsScript));
+ blur.setRadius (radius);
+ blur.setInput (alloc);
+
+ Bitmap result = Bitmap.createBitmap(input.getWidth(), input.getHeight(), input.getConfig());
+ Allocation outAlloc = Allocation.createFromBitmap (rsScript, result);
+ blur.forEach (outAlloc);
+ outAlloc.copyTo(result);
+
+ rsScript.destroy();
+ return result;
+ }
+
+}
diff --git a/src/com/dsht/kernetweaker/cmdprocessor/AbstractAsyncSuCMDProcessor.java b/src/com/dsht/kernetweaker/cmdprocessor/AbstractAsyncSuCMDProcessor.java
new file mode 100755
index 0000000..c980060
--- /dev/null
+++ b/src/com/dsht/kernetweaker/cmdprocessor/AbstractAsyncSuCMDProcessor.java
@@ -0,0 +1,104 @@
+package com.dsht.kernetweaker.cmdprocessor;
+
+import com.dsht.kerneltweaker.Helpers;
+
+import android.os.AsyncTask;
+
+/**
+ * An abstract implentation of AsyncTask
+ *
+ * since our needs are simple send a command, perform a task when we finish
+ * this implentation requires you send the command as String...
+ * in the .execute(String) so you can send String[] of commands if needed
+ *
+ * This class is not for you if...
+ * 1) You do not need to perform any action after command execution
+ * you want a Thread not this.
+ * 2) You need to perform more complex tasks in doInBackground
+ * than simple script/command sequence of commands
+ * you want your own AsyncTask not this.
+ *
+ * This class is for you if...
+ * 1) You need to run a command/script/sequence of commands without
+ * blocking the UI thread and you must perform actions after the
+ * task completes.
+ * 2) see #1.
+ */
+public abstract class AbstractAsyncSuCMDProcessor extends AsyncTask<String, Void, String> {
+ // if /system needs to be mounted before command
+ private boolean mMountSystem;
+ // return if we recieve a null command or empty command
+ public final String FAILURE = "failed_no_command";
+
+ /**
+ * Constructor that allows mounting/dismounting
+ * of /system partition while in background thread
+ */
+ public AbstractAsyncSuCMDProcessor(boolean mountSystem) {
+ this.mMountSystem = mountSystem;
+ }
+
+ /**
+ * Constructor that assumes /system should not be mounted
+ */
+ public AbstractAsyncSuCMDProcessor() {
+ this.mMountSystem = false;
+ }
+
+ /**
+ * DO NOT override this method you should simply send your commands off
+ * as params and expect to handle results in {@link #onPostExecute}
+ *
+ * if you find a need to @Override this method then you should
+ * consider using a new AsyncTask implentation instead
+ *
+ * @param params The parameters of the task.
+ *
+ * @return A result, defined by the subclass of this task.
+ */
+ @Override
+ protected String doInBackground(String... params) {
+ // don't bother if we don't get a command
+ if (params[0] == null || params[0].trim().equals(""))
+ return FAILURE;
+
+ String stdout = null;
+
+ // conditionally enforce mounting
+ if (mMountSystem) {
+ Helpers.getMount("rw");
+ }
+ try {
+ // process all commands ***DO NOT SEND null OR ""; you have been warned***
+ for (int i = 0; params.length > i; i++) {
+ // always watch for null and empty strings, lazy devs :/
+ if (params[i] != null && !params[i].trim().equals("")) {
+ stdout = CMDProcessor.runSuCommand(params[i]).getStdout();
+ } else {
+ // bail because of careless devs
+ return FAILURE;
+ }
+ }
+ // always unmount
+ } finally {
+ if (mMountSystem)
+ Helpers.getMount("ro");
+ }
+ // return the stdout from the command
+ return stdout;
+ }
+
+ /**
+ * <p>Runs on the UI thread after {@link #doInBackground}. The
+ * specified result is the value returned by {@link #doInBackground}.</p>
+ *
+ * <p>This method won't be invoked if the task was cancelled.</p>
+ *
+ * You MUST @Override this method if you don't need the result
+ * then you should consider using a new Thread implentation instead
+ *
+ * @param result The result of the operation computed by {@link #doInBackground}.
+ */
+ @Override
+ protected abstract void onPostExecute(String result);
+}
diff --git a/src/com/dsht/kernetweaker/cmdprocessor/CMDProcessor.java b/src/com/dsht/kernetweaker/cmdprocessor/CMDProcessor.java
new file mode 100755
index 0000000..9270dc4
--- /dev/null
+++ b/src/com/dsht/kernetweaker/cmdprocessor/CMDProcessor.java
@@ -0,0 +1,163 @@
+package com.dsht.kernetweaker.cmdprocessor;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.InputStream;
+
+import com.dsht.open.Constants;
+
+import android.util.Log;
+
+// convenience import for quick referencing of this method
+
+public final class CMDProcessor implements Constants {
+ private static final String TAG = "CMDProcessor";
+
+ private Boolean can_su;
+ public sh sh;
+ public sh su;
+
+ public CMDProcessor() {
+ // Cannot instantiate this class
+ sh = new sh("sh");
+ su = new sh("su");
+ //throw new AssertionError();
+ }
+
+
+ /* Run a system command with full redirection */
+ public static ChildProcess startSysCmd(String[] cmdarray, String childStdin) {
+ return new ChildProcess(cmdarray, childStdin);
+ }
+
+ public static CommandResult runSysCmd(String[] cmdarray, String childStdin) {
+ ChildProcess proc = startSysCmd(cmdarray, childStdin);
+ proc.waitFinished();
+ return proc.getResult();
+ }
+
+ public static ChildProcess startShellCommand(String cmd) {
+ String[] cmdarray = new String[3];
+ cmdarray[0] = "sh";
+ cmdarray[1] = "-c";
+ cmdarray[2] = cmd;
+ return startSysCmd(cmdarray, null);
+ }
+
+ public static CommandResult runShellCommand(String cmd) {
+ ChildProcess proc = startShellCommand(cmd);
+ proc.waitFinished();
+ return proc.getResult();
+ }
+
+ public static ChildProcess startSuCommand(String cmd) {
+ String[] cmdarray = new String[3];
+ cmdarray[0] = "su";
+ cmdarray[1] = "-c";
+ cmdarray[2] = cmd;
+ return startSysCmd(cmdarray, null);
+ }
+
+ public static CommandResult runSuCommand(String cmd) {
+ ChildProcess proc = startSuCommand(cmd);
+ proc.waitFinished();
+ return proc.getResult();
+ }
+
+ public static boolean canSU() {
+ CommandResult r = runShellCommand("id");
+ StringBuilder out = new StringBuilder(0);
+ out.append(r.getStdout());
+ out.append(" ; ");
+ out.append(r.getStderr());
+ Log.d(TAG, "canSU() su[" + r.getExitValue() + "]: " + out);
+ return r.success();
+ }
+
+ public class CommandResult2 {
+ public final String stdout;
+ public final String stderr;
+ public final Integer exit_value;
+
+ CommandResult2(final Integer exit_value_in) {
+ this(exit_value_in, null, null);
+ }
+
+ CommandResult2(final Integer exit_value_in, final String stdout_in,
+ final String stderr_in) {
+ exit_value = exit_value_in;
+ stdout = stdout_in;
+ stderr = stderr_in;
+ }
+
+ public boolean success() {
+ return exit_value != null && exit_value == 0;
+ }
+ }
+
+ public class sh {
+ private String SHELL = "sh";
+
+ public sh(final String SHELL_in) {
+ SHELL = SHELL_in;
+ }
+
+ private String getStreamLines(final InputStream is) {
+ String out = null;
+ StringBuffer buffer = null;
+ final DataInputStream dis = new DataInputStream(is);
+
+ try {
+ if (dis.available() > 0) {
+ buffer = new StringBuffer(dis.readLine());
+ while (dis.available() > 0) {
+ buffer.append("\n").append(dis.readLine());
+ }
+ }
+ dis.close();
+ } catch (final Exception ex) {
+ Log.e(TAG, ex.getMessage());
+ }
+ if (buffer != null) {
+ out = buffer.toString();
+ }
+ return out;
+ }
+
+ public Process run(final String s) {
+ Process process;
+ try {
+ process = Runtime.getRuntime().exec(SHELL);
+ final DataOutputStream toProcess = new DataOutputStream(
+ process.getOutputStream());
+ toProcess.writeBytes("exec " + s + "\n");
+ toProcess.flush();
+ } catch (final Exception e) {
+ Log.e(TAG,
+ "Exception while trying to run: '" + s + "' "
+ + e.getMessage());
+ process = null;
+ }
+ return process;
+ }
+
+ public CommandResult2 runWaitFor(final String s) {
+ final Process process = run(s);
+ Integer exit_value = null;
+ String stdout = null;
+ String stderr = null;
+ if (process != null) {
+ try {
+ exit_value = process.waitFor();
+
+ stdout = getStreamLines(process.getInputStream());
+ stderr = getStreamLines(process.getErrorStream());
+
+ } catch (final Exception e) {
+ Log.e(TAG, "runWaitFor " + e.toString());
+ }
+ }
+ return new CommandResult2(exit_value, stdout, stderr);
+ }
+ }
+}
diff --git a/src/com/dsht/kernetweaker/cmdprocessor/ChildProcess.java b/src/com/dsht/kernetweaker/cmdprocessor/ChildProcess.java
new file mode 100755
index 0000000..7c15184
--- /dev/null
+++ b/src/com/dsht/kernetweaker/cmdprocessor/ChildProcess.java
@@ -0,0 +1,144 @@
+package com.dsht.kernetweaker.cmdprocessor;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+import static java.lang.System.nanoTime;
+
+public class ChildProcess {
+ private static final int PIPE_SIZE = 1024;
+
+ private class ChildReader extends Thread {
+ InputStream mStream;
+ StringBuffer mBuffer;
+ ChildReader(InputStream is, StringBuffer buf) {
+ mStream = is;
+ mBuffer = buf;
+ }
+ public void run() {
+ byte[] buf = new byte[PIPE_SIZE];
+ try {
+ int len;
+ while ((len = mStream.read(buf)) != -1) {
+ String s = new String(buf, 0, len);
+ mBuffer.append(s);
+ }
+ }
+ catch (IOException e) {
+ // Ignore
+ }
+ try {
+ mStream.close();
+ }
+ catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+ private class ChildWriter extends Thread {
+ OutputStream mStream;
+ String mBuffer;
+ ChildWriter(OutputStream os, String buf) {
+ mStream = os;
+ mBuffer = buf;
+ }
+ public void run() {
+ int off = 0;
+ byte[] buf = mBuffer.getBytes();
+ try {
+ while (off < buf.length) {
+ int len = Math.min(PIPE_SIZE, buf.length - off);
+ mStream.write(buf, off, len);
+ off += len;
+ }
+ }
+ catch (IOException e) {
+ // Ignore
+ }
+ try {
+ mStream.close();
+ }
+ catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+
+ private long mStartTime;
+ private Process mChildProc;
+ private ChildWriter mChildStdinWriter;
+ private ChildReader mChildStdoutReader;
+ private ChildReader mChildStderrReader;
+ private StringBuffer mChildStdout;
+ private StringBuffer mChildStderr;
+ private int mExitValue;
+ private long mEndTime;
+
+ public ChildProcess(String[] cmdarray, String childStdin) {
+ mStartTime = nanoTime();
+ try {
+ mChildProc = Runtime.getRuntime().exec(cmdarray);
+ if (childStdin != null) {
+ mChildStdinWriter = new ChildWriter(mChildProc.getOutputStream(), childStdin);
+ mChildStdinWriter.start();
+ }
+ mChildStdout = new StringBuffer();
+ mChildStdoutReader = new ChildReader(mChildProc.getInputStream(), mChildStdout);
+ mChildStdoutReader.start();
+ mChildStderr = new StringBuffer();
+ mChildStderrReader = new ChildReader(mChildProc.getErrorStream(), mChildStderr);
+ mChildStderrReader.start();
+ }
+ catch (IOException e) {
+ // XXX: log
+ }
+ }
+
+ public boolean isFinished() {
+ boolean finished = true;
+ if (mChildProc != null) {
+ try {
+ mChildProc.exitValue();
+ }
+ catch (IllegalStateException e) {
+ finished = false;
+ }
+ }
+ return finished;
+ }
+
+ public int waitFinished() {
+ while (mChildProc != null) {
+ try {
+ mExitValue = mChildProc.waitFor();
+ mEndTime = nanoTime();
+ mChildProc = null;
+ mChildStderrReader.join();
+ mChildStderrReader = null;
+ mChildStdoutReader.join();
+ mChildStdoutReader = null;
+ if (mChildStdinWriter != null) {
+ mChildStdinWriter.join();
+ mChildStdinWriter = null;
+ }
+ }
+ catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ return mExitValue;
+ }
+
+ public CommandResult getResult() {
+ if (!isFinished()) {
+ throw new IllegalThreadStateException("Child process running");
+ }
+ return new CommandResult(
+ mStartTime,
+ mExitValue,
+ mChildStdout.toString(),
+ mChildStderr.toString(),
+ mEndTime);
+ }
+} \ No newline at end of file
diff --git a/src/com/dsht/kernetweaker/cmdprocessor/CommandResult.java b/src/com/dsht/kernetweaker/cmdprocessor/CommandResult.java
new file mode 100755
index 0000000..537df40
--- /dev/null
+++ b/src/com/dsht/kernetweaker/cmdprocessor/CommandResult.java
@@ -0,0 +1,168 @@
+package com.dsht.kernetweaker.cmdprocessor;
+
+import android.os.Environment;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+@SuppressWarnings("AccessOfSystemProperties")
+public class CommandResult implements Parcelable {
+ private final String TAG = getClass().getSimpleName();
+ private final long mStartTime;
+ private final int mExitValue;
+ private final String mStdout;
+ private final String mStderr;
+ private final long mEndTime;
+
+ public CommandResult(long startTime,
+ int exitValue,
+ String stdout,
+ String stderr,
+ long endTime) {
+ mStartTime = startTime;
+ mExitValue = exitValue;
+ mStdout = stdout;
+ mStderr = stderr;
+ mEndTime = endTime;
+
+ Log.d(TAG, "Time to execute: " + (mEndTime - mStartTime) + " ns (nanoseconds)");
+ // this is set last so log from here
+ checkForErrors();
+ }
+
+ // pretty much just forward the constructor from parcelable to our main
+ // loading constructor
+ @SuppressWarnings("CastToConcreteClass")
+ public CommandResult(Parcel inParcel) {
+ this(inParcel.readLong(),
+ inParcel.readInt(),
+ inParcel.readString(),
+ inParcel.readString(),
+ inParcel.readLong());
+ }
+
+ public boolean success() {
+ return (mExitValue == 0);
+ }
+
+ public long getEndTime() {
+ return mEndTime;
+ }
+
+ public String getStderr() {
+ return new String(mStderr);
+ }
+
+ public String getStdout() {
+ return new String(mStdout);
+ }
+
+ public Integer getExitValue() {
+ return mExitValue;
+ }
+
+ public long getStartTime() {
+ return mStartTime;
+ }
+
+ @SuppressWarnings("UnnecessaryExplicitNumericCast")
+ private void checkForErrors() {
+ if (mExitValue != 0
+ || !"".equals(mStderr.trim())) {
+ // don't log the commands that failed
+ // because the cpu was offline
+ boolean skipOfflineCpu =
+ // if core is off locking fails
+ mStderr.contains("chmod: /sys/devices/system/cpu/cpu")
+ // if core is off applying cpu freqs fails
+ || mStderr.contains(": can't create /sys/devices/system/cpu/cpu");
+ String lineEnding = System.getProperty("line.separator");
+ FileWriter errorWriter = null;
+ try {
+ File errorLogFile = new File(
+ Environment.getExternalStorageDirectory()
+ + "/aokp/error.txt");
+ if (!errorLogFile.exists()) {
+ errorLogFile.createNewFile();
+ }
+ errorWriter = new FileWriter(errorLogFile, true);
+ // only log the cpu state as offline while writing
+ if (skipOfflineCpu) {
+ errorWriter.write(lineEnding);
+ errorWriter.write("Attempted to write to an offline cpu core (ignore me).");
+ } else {
+ errorWriter.write(TAG + " shell error detected!");
+ errorWriter.write(lineEnding);
+ errorWriter.write("CommandResult {" + this.toString() + '}');
+ errorWriter.write(lineEnding);
+ }
+ errorWriter.write(lineEnding);
+ } catch (IOException e) {
+ Log.e(TAG, "Failed to write command result to error file", e);
+ } finally {
+ if (errorWriter != null) {
+ try {
+ errorWriter.close();
+ } catch (IOException ignored) {
+ // let it go
+ }
+ }
+ }
+ }
+ }
+
+ // implement parcelable
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int i) {
+ parcel.writeLong(mStartTime);
+ parcel.writeInt(mExitValue);
+ parcel.writeString(mStdout);
+ parcel.writeString(mStderr);
+ parcel.writeLong(mEndTime);
+ }
+
+ @Override
+ public String toString() {
+ return "CommandResult{" +
+ ", mStartTime=" + mStartTime +
+ ", mExitValue=" + mExitValue +
+ ", stdout='" + mStdout + "'" +
+ ", stderr='" + mStderr + "'" +
+ ", mEndTime=" + mEndTime +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof CommandResult)) return false;
+
+ CommandResult that = (CommandResult) o;
+
+ return (mStartTime == that.mStartTime &&
+ mExitValue == that.mExitValue &&
+ mStdout == that.mStdout &&
+ mStderr == that.mStderr &&
+ mEndTime == that.mEndTime);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 0;
+ result = 31 * result + (int) (mStartTime ^ (mStartTime >>> 32));
+ result = 31 * result + mExitValue;
+ result = 31 * result + (mStdout != null ? mStdout.hashCode() : 0);
+ result = 31 * result + (mStderr != null ? mStderr.hashCode() : 0);
+ result = 31 * result + (int) (mEndTime ^ (mEndTime >>> 32));
+ return result;
+ }
+}
diff --git a/src/com/dsht/kernetweaker/cmdprocessor/Executable.java b/src/com/dsht/kernetweaker/cmdprocessor/Executable.java
new file mode 100755
index 0000000..ea8f582
--- /dev/null
+++ b/src/com/dsht/kernetweaker/cmdprocessor/Executable.java
@@ -0,0 +1,142 @@
+package com.dsht.kernetweaker.cmdprocessor;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.Arrays;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: jbird
+ * Date: 1/22/13
+ * Time: 5:19 AM
+ */
+public class Executable implements Parcelable {
+ private String TAG = getClass().getSimpleName();
+ private boolean DEBUG = false;
+
+ private final String[] mCommandsArray;
+ private final long mStartTime;
+ private Status mStatus;
+ private long mFinishTime = -1;
+
+ public enum Status {
+ Queried, // Executable default status
+ Staged, // beginning execution
+ Finished // done.
+ }
+
+ public Executable(String... commands) {
+ this.mCommandsArray = commands;
+ this.mStartTime = System.nanoTime();
+ this.mStatus = Status.Queried;
+ }
+
+ public Executable(Parcel parcel) {
+ this.mCommandsArray = parcel.createStringArray();
+ this.mStartTime = parcel.readLong();
+ this.mStatus = Status.valueOf(parcel.readString());
+ this.mFinishTime = parcel.readLong();
+ }
+
+ public long getStartTime() {
+ return mStartTime;
+ }
+
+ public String[] getCommandsArray() {
+ // if the status is not finished we
+ // now consider the script Staged
+ if (getStatus() != Status.Finished) {
+ setStatus(Status.Staged);
+ }
+ return mCommandsArray;
+ }
+
+ public Status getStatus() {
+ return mStatus;
+ }
+
+ public Executable toggleDebug(boolean debug) {
+ this.DEBUG = debug;
+ return this;
+ }
+
+ public Executable setStatus(Status status) {
+ this.mStatus = status;
+ return this;
+ }
+
+ public long getFinishTime() {
+ return mFinishTime;
+ }
+
+ public Executable setFinishTime(long finishTime) {
+ mFinishTime = finishTime;
+ if (DEBUG) {
+ Log.d(TAG, "Executable completed execution in " + (mFinishTime - mStartTime) + " ms");
+ }
+ if (Status.Staged == mStatus) {
+ setStatus(Status.Finished);
+ }
+ return this;
+ }
+
+ // parcel implementation
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int i) {
+ parcel.writeStringArray(mCommandsArray);
+ parcel.writeLong(mStartTime);
+ parcel.writeString(mStatus.toString());
+ parcel.writeLong(mFinishTime);
+ }
+
+ public static final Executable.Creator<Executable> CREATOR = new Executable.Creator<Executable>() {
+ public Executable createFromParcel(Parcel in) {
+ return new Executable(in);
+ }
+
+ public Executable[] newArray(int size) {
+ return new Executable[size];
+ }
+ };
+
+ @Override
+ public String toString() {
+ return "Executable{" +
+ "TAG='" + TAG + '\'' +
+ ", mCommandsArray=" + (mCommandsArray == null ? null : Arrays.asList(mCommandsArray)) +
+ ", mStartTime=" + mStartTime +
+ ", mStatus=" + mStatus +
+ ", mFinishTime=" + mFinishTime +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Executable)) return false;
+ Executable that = (Executable) o;
+ if (mFinishTime != that.mFinishTime) return false;
+ if (mStartTime != that.mStartTime) return false;
+ if (!TAG.equals(that.TAG)) return false;
+ if (!Arrays.equals(mCommandsArray, that.mCommandsArray)) return false;
+ if (mStatus != that.mStatus) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = TAG.hashCode();
+ result = 31 * result + Arrays.hashCode(mCommandsArray);
+ result = 31 * result + (int) (mStartTime ^ (mStartTime >>> 32));
+ result = 31 * result + mStatus.hashCode();
+ result = 31 * result + (int) (mFinishTime ^ (mFinishTime >>> 32));
+ return result;
+ }
+}
diff --git a/src/com/dsht/open/CPUInfo.java b/src/com/dsht/open/CPUInfo.java
new file mode 100755
index 0000000..1caf8f8
--- /dev/null
+++ b/src/com/dsht/open/CPUInfo.java
@@ -0,0 +1,134 @@
+/*
+ * Performance Control - An Android CPU Control application Copyright (C) 2012
+ * James Roberts
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.dsht.open;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+
+public class CPUInfo extends Fragment implements Constants {
+
+ private TextView mKernelInfo;
+ private TextView mCPUInfo;
+ private TextView mMemInfo;
+ private Context context;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ context = getActivity();
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup root, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.cpu_info, root, false);
+ mKernelInfo = (TextView) view.findViewById(R.id.kernel_info);
+ mCPUInfo = (TextView) view.findViewById(R.id.cpu_info);
+ mMemInfo = (TextView) view.findViewById(R.id.mem_info);
+ updateData();
+ MainActivity.menu.toggle(true);
+ return view;
+ }
+
+ public void updateData() {
+ mKernelInfo.setText("");
+ mCPUInfo.setText("");
+ mMemInfo.setText("");
+ readFile(mKernelInfo, KERNEL_INFO_PATH);
+ if (new File(PFK_VER).exists()) {
+ mKernelInfo.append("\n");
+ mKernelInfo.append(getString(R.string.pfk_info, Helpers.readOneLine(PFK_VER)));
+ mKernelInfo.append("\n");
+ }
+ if (new File(DYNAMIC_DIRTY_WRITEBACK_PATH).exists()) {
+ mKernelInfo.append("\n");
+ mKernelInfo.append(getString(R.string.dynamic_writeback_info));
+ mKernelInfo.append("\n");
+ }
+ if (new File(DSYNC_PATH).exists()) {
+ mKernelInfo.append("\n");
+ mKernelInfo.append(getString(R.string.dsync_info));
+ mKernelInfo.append("\n");
+ }
+ if (new File(BLX_PATH).exists()) {
+ mKernelInfo.append("\n");
+ mKernelInfo.append(getString(R.string.blx_info));
+ mKernelInfo.append("\n");
+ }
+ readFile(mCPUInfo, CPU_INFO_PATH);
+ readFile(mMemInfo, MEM_INFO_PATH);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ if (!getResources().getBoolean(R.bool.config_showPerformanceOnly)) {
+ inflater.inflate(R.menu.cpu_info_menu, menu);
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.refresh:
+ updateData();
+ break;
+ }
+ return true;
+ }
+
+ public void readFile(TextView tView, String fName) {
+ FileReader fr = null;
+ try {
+ fr = new FileReader(fName);
+ BufferedReader br = new BufferedReader(fr);
+ String line = br.readLine();
+ while (null != line) {
+ tView.append(line);
+ tView.append("\n");
+ line = br.readLine();
+ }
+ } catch (IOException ex) {
+ } finally {
+ if (null != fr) {
+ try {
+ fr.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/dsht/open/CPUStateMonitor.java b/src/com/dsht/open/CPUStateMonitor.java
new file mode 100755
index 0000000..860b6a8
--- /dev/null
+++ b/src/com/dsht/open/CPUStateMonitor.java
@@ -0,0 +1,153 @@
+/*
+ * Performance Control - An Android CPU Control application Copyright (C)
+ * Brandon Valosek, 2011 <bvalosek@gmail.com> Copyright (C) Modified by 2012
+ * James Roberts
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.dsht.open;
+
+import android.os.SystemClock;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+//@SuppressLint("UseSparseArrays")
+public class CPUStateMonitor implements Constants {
+
+ private List<CpuState> mStates = new ArrayList<CpuState>();
+ private Map<Integer, Long> mOffsets = new HashMap<Integer, Long>();
+
+ @SuppressWarnings("serial")
+ public class CPUStateMonitorException extends Exception {
+ public CPUStateMonitorException(String s) {
+ super(s);
+ }
+ }
+
+ //@SuppressLint({"UseValueOf", "UseValueOf"})
+ public class CpuState implements Comparable<CpuState> {
+ public CpuState(int a, long b) {
+ freq = a;
+ duration = b;
+ }
+
+ public int freq = 0;
+ public long duration = 0;
+
+ public int compareTo(CpuState state) {
+ Integer a = freq;
+ Integer b = state.freq;
+ return a.compareTo(b);
+ }
+ }
+
+ public List<CpuState> getStates() {
+ List<CpuState> states = new ArrayList<CpuState>();
+
+ for (CpuState state : mStates) {
+ long duration = state.duration;
+ if (mOffsets.containsKey(state.freq)) {
+ long offset = mOffsets.get(state.freq);
+ if (offset <= duration) {
+ duration -= offset;
+ } else {
+ mOffsets.clear();
+ return getStates();
+ }
+ }
+ states.add(new CpuState(state.freq, duration));
+ }
+ return states;
+ }
+
+ public long getTotalStateTime() {
+ long sum = 0;
+ long offset = 0;
+
+ for (CpuState state : mStates) {
+ sum += state.duration;
+ }
+
+ for (Map.Entry<Integer, Long> entry : mOffsets.entrySet()) {
+ offset += entry.getValue();
+ }
+ return sum - offset;
+ }
+
+ public Map<Integer, Long> getOffsets() {
+ return mOffsets;
+ }
+
+ public void setOffsets(Map<Integer, Long> offsets) {
+ mOffsets = offsets;
+ }
+
+ public void setOffsets() throws CPUStateMonitorException {
+ mOffsets.clear();
+ updateStates();
+
+ for (CpuState state : mStates) {
+ mOffsets.put(state.freq, state.duration);
+ }
+ }
+
+ public void removeOffsets() {
+ mOffsets.clear();
+ }
+
+ public List<CpuState> updateStates() throws CPUStateMonitorException {
+ try {
+ InputStream is = new FileInputStream(TIME_IN_STATE_PATH);
+ InputStreamReader ir = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(ir);
+ mStates.clear();
+ readInStates(br);
+ is.close();
+ } catch (IOException e) {
+ throw new CPUStateMonitorException(
+ "Problem opening time-in-states file");
+ }
+
+ long sleepTime = (SystemClock.elapsedRealtime() - SystemClock.uptimeMillis()) / 10;
+ mStates.add(new CpuState(0, sleepTime));
+
+ Collections.sort(mStates, Collections.reverseOrder());
+
+ return mStates;
+ }
+
+ private void readInStates(BufferedReader br)
+ throws CPUStateMonitorException {
+ try {
+ String line;
+ while ((line = br.readLine()) != null) {
+ String[] nums = line.split(" ");
+ mStates.add(new CpuState(Integer.parseInt(nums[0]), Long.parseLong(nums[1])));
+ }
+ } catch (IOException e) {
+ throw new CPUStateMonitorException(
+ "Problem processing time-in-states file");
+ }
+ }
+}
diff --git a/src/com/dsht/open/Constants.java b/src/com/dsht/open/Constants.java
new file mode 100755
index 0000000..58ee66f
--- /dev/null
+++ b/src/com/dsht/open/Constants.java
@@ -0,0 +1,225 @@
+/*
+ * Performance Control - An Android CPU Control application Copyright (C) 2012
+ * James Roberts
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.dsht.open;
+
+public interface Constants {
+
+ public static final String TAG = "PerformanceControl";
+ public static final String VERSION_NUM = "2.1.4-omni";
+ //hide flashing kernel/recovery options
+ // NO_FLASH=true > hide flash options
+ // NO_FLASH=false > show flash options
+ public static final Boolean NO_FLASH = false;
+
+ // Fragment IDs
+ public static final int FRAGMENT_ID_CPUSETTINGS = 0;
+ public static final int FRAGMENT_ID_BATTERYINFO = 1;
+ public static final int FRAGMENT_ID_OOMSETTINGS = 2;
+ public static final int FRAGMENT_ID_VM = 3;
+ public static final int FRAGMENT_ID_VOLTAGECONROL = 4;
+ public static final int FRAGMENT_ID_ADVANCED = 5;
+ public static final int FRAGMENT_ID_TIMEINSTATE = 6;
+ public static final int FRAGMENT_ID_CPUINFO = 7;
+ public static final int FRAGMENT_ID_DISKINFO = 8;
+ public static final int FRAGMENT_ID_TOOLS = 9;
+
+ // CPU settings
+ public static final String CPU_PATH = "/sys/devices/system/cpu/cpu";
+ public static final String CPU_FREQ_TAIL = "/cpufreq/scaling_cur_freq";
+ public static final String CUR_CPU_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq";
+ public static final String MAX_FREQ_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq";
+ public static final String TEGRA_MAX_FREQ_PATH = "/sys/module/cpu_tegra/parameters/cpu_user_cap";
+ public static final String MIN_FREQ_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq";
+ public static final String STEPS_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies";
+ public static final String GOVERNORS_LIST_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors";
+ public static final String GOVERNOR_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor";
+ public static final String[] IO_SCHEDULER_PATH = {"/sys/block/mmcblk0/queue/scheduler", "/sys/block/mmcblk1/queue/scheduler"};
+ //Dynamic frequency scaling
+ public static final String DYN_MAX_FREQ_PATH = "/sys/power/cpufreq_max_limit";
+ public static final String DYN_MIN_FREQ_PATH = "/sys/power/cpufreq_min_limit";
+
+ public static final String NUM_OF_CPUS_PATH = "/sys/devices/system/cpu/present";
+
+ public static final String PREF_MAX_CPU = "pref_max_cpu";
+ public static final String PREF_MIN_CPU = "pref_min_cpu";
+ public static final String PREF_GOV = "pref_gov";
+ public static final String PREF_IO = "pref_io";
+ public static final String CPU_SOB = "cpu_sob";
+ public static final String GOV_SOB = "gov_settings_sob";
+ public static final String GOV_SETTINGS = "gov_settings";
+ public static final String GOV_NAME = "gov_name";
+ public static final String GOV_SETTINGS_PATH = "/sys/devices/system/cpu/cpufreq/";
+
+ // CPU info
+ public static String KERNEL_INFO_PATH = "/proc/version";
+ public static String CPU_INFO_PATH = "/proc/cpuinfo";
+ public static String MEM_INFO_PATH = "/proc/meminfo";
+
+ // Time in state
+ public static final String TIME_IN_STATE_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state";
+ public static final String TIME_IN_STATE_TAIL = "/cpufreq/stats/time_in_state";
+ public static final String PREF_OFFSETS = "pref_offsets";
+ // Battery
+ public static final String BAT_VOLT_PATH = "/sys/class/power_supply/battery/voltage_now";
+
+ // Other settings
+ public static final String MINFREE_PATH = "/sys/module/lowmemorykiller/parameters/minfree";
+ public static final String MINFREE_ADJ_PATH = "/sys/module/lowmemorykiller/parameters/adj";
+ public static final String READ_AHEAD_PATH = "/sys/block/mmcblk0/bdi/read_ahead_kb";
+ //"/sys/devices/virtual/bdi/default/read_ahead_kb"
+
+ public static final String INTENT_ACTION_FASTCHARGE = "com.aokp.romcontrol.FCHARGE_CHANGED";
+ public static final String PREF_MINFREE = "pref_minfree";
+ public static final String PREF_MINFREE_BOOT = "pref_minfree_boot";
+ public static final String PREF_READ_AHEAD = "pref_read_ahead";
+ public static final String PREF_READ_AHEAD_BOOT = "pref_read_ahead_boot";
+ public static final String PREF_FASTCHARGE = "pref_fast_charge";
+ //------ MinFree ------
+ public static final String OOM_FOREGROUND_APP = "oom_foreground_app";
+ public static final String OOM_VISIBLE_APP = "oom_visible_app";
+ public static final String OOM_SECONDARY_SERVER = "oom_secondary_server";
+ public static final String OOM_HIDDEN_APP = "oom_hidden_app";
+ public static final String OOM_CONTENT_PROVIDERS = "oom_content_providers";
+ public static final String OOM_EMPTY_APP = "oom_empty_app";
+ //------ KSM
+ public static final String KSM_RUN_PATH = "/sys/kernel/mm/ksm/run";
+ public static final String KSM_FULLSCANS_PATH = "/sys/kernel/mm/ksm/full_scans";
+ public static final String KSM_PAGESSHARED_PATH = "/sys/kernel/mm/ksm/pages_shared";
+ public static final String KSM_PAGESSHARING_PATH = "/sys/kernel/mm/ksm/pages_sharing";
+ public static final String KSM_PAGESTOSCAN_PATH = "/sys/kernel/mm/ksm/pages_to_scan";
+ public static final String KSM_PAGESUNSHERED_PATH = "/sys/kernel/mm/ksm/pages_unshared";
+ public static final String KSM_PAGESVOLATILE_PATH = "/sys/kernel/mm/ksm/pages_volatile";
+ public static final String KSM_SLEEP_PATH = "/sys/kernel/mm/ksm/sleep_millisecs";
+ public static final String PREF_RUN_KSM = "pref_run_ksm";
+ public static final String KSM_SOB = "ksm_boot";
+
+ //------ DoNotKillProc
+ public static final String USER_PROC_PATH = "/sys/module/lowmemorykiller/parameters/donotkill_proc";
+ public static final String SYS_PROC_PATH = "/sys/module/lowmemorykiller/parameters/donotkill_sysproc";
+ public static final String USER_PROC_NAMES_PATH = "/sys/module/lowmemorykiller/parameters/donotkill_proc_names";
+ public static final String USER_SYS_NAMES_PATH = "/sys/module/lowmemorykiller/parameters/donotkill_sysproc_names";
+ public static final String USER_PROC_SOB = "user_proc_boot";
+ public static final String SYS_PROC_SOB = "sys_proc_boot";
+ public static final String PREF_USER_PROC = "pref_user_proc";
+ public static final String PREF_SYS_PROC = "pref_sys_proc";
+ public static final String PREF_USER_NAMES = "pref_user_names_proc";
+ public static final String PREF_SYS_NAMES = "pref_sys_names_proc";
+ //-------BLX---------
+ public static final String PREF_BLX = "pref_blx";
+ public static final String BLX_PATH = "/sys/class/misc/batterylifeextender/charging_limit";
+ public static final String BLX_SOB = "blx_sob";
+ //-------DFsync---------
+ public static final String DSYNC_PATH = "/sys/kernel/dyn_fsync/Dyn_fsync_active";
+ public static final String PREF_DSYNC = "pref_dsync";
+ //-------BL----
+ public static final String PREF_BLTIMEOUT = "pref_bltimeout";
+ public static final String BLTIMEOUT_SOB = "bltimeout_sob";
+ public static final String PREF_BLTOUCH = "pref_bltouch";
+ public static final String BL_TIMEOUT_PATH = "/sys/class/misc/notification/bl_timeout";
+ public static final String BL_TOUCH_ON_PATH = "/sys/class/misc/notification/touchlight_enabled";
+ //-------BLN---------
+ public static final String PREF_BLN = "pref_bln";
+ //-------PFK---------
+ public static final String PFK_VER = "/sys/class/misc/phantom_kp_filter/version";
+ public static final String PFK_HOME_ON = "pfk_home_on";
+ public static final String PREF_HOME_ALLOWED_IRQ = "pref_home_allowed_irq";
+ public static final String PREF_HOME_REPORT_WAIT = "pref_home_report_wait";
+ public static final String PFK_MENUBACK_ON = "pfk_menuback_on";
+ public static final String PREF_MENUBACK_INTERRUPT_CHECKS = "pref_menuback_interrupt_checks";
+ public static final String PREF_MENUBACK_FIRST_ERR_WAIT = "pref_menuback_first_err_wait";
+ public static final String PREF_MENUBACK_LAST_ERR_WAIT = "pref_menuback_last_err_wait";
+
+ public static final String PFK_HOME_ENABLED = "/sys/class/misc/phantom_kp_filter/home_enabled";
+ public static final String PFK_HOME_ALLOWED_IRQ = "/sys/class/misc/phantom_kp_filter/home_allowed_irqs";
+ public static final String PFK_HOME_REPORT_WAIT = "/sys/class/misc/phantom_kp_filter/home_report_wait";
+ public static final String PFK_HOME_IGNORED_KP = "/sys/class/misc/phantom_kp_filter/home_ignored_kp";
+ public static final String PFK_MENUBACK_ENABLED = "/sys/class/misc/phantom_kp_filter/menuback_enabled";
+ public static final String PFK_MENUBACK_INTERRUPT_CHECKS = "/sys/class/misc/phantom_kp_filter/menuback_interrupt_checks";
+ public static final String PFK_MENUBACK_FIRST_ERR_WAIT = "/sys/class/misc/phantom_kp_filter/menuback_first_err_wait";
+ public static final String PFK_MENUBACK_LAST_ERR_WAIT = "/sys/class/misc/phantom_kp_filter/menuback_last_err_wait";
+ public static final String PFK_MENUBACK_IGNORED_KP = "/sys/class/misc/phantom_kp_filter/menuback_ignored_kp";
+ public static final String PFK_SOB = "pfk_sob";
+ //------------------
+ public static final String DYNAMIC_DIRTY_WRITEBACK_PATH = "/proc/sys/vm/dynamic_dirty_writeback";
+ public static final String DIRTY_WRITEBACK_ACTIVE_PATH = "/proc/sys/vm/dirty_writeback_active_centisecs";
+ public static final String DIRTY_WRITEBACK_SUSPEND_PATH = "/proc/sys/vm/dirty_writeback_suspend_centisecs";
+ public static final String PREF_DYNAMIC_DIRTY_WRITEBACK = "pref_dynamic_dirty_writeback";
+ public static final String PREF_DIRTY_WRITEBACK_ACTIVE = "pref_dynamic_writeback_active";
+ public static final String PREF_DIRTY_WRITEBACK_SUSPEND = "pref_dynamic_writeback_suspend";
+ public static final String DYNAMIC_DIRTY_WRITEBACK_SOB = "dynamic_write_back_sob";
+
+ // VM settings
+ public static final String PREF_DIRTY_RATIO = "pref_dirty_ratio";
+ public static final String PREF_DIRTY_BACKGROUND = "pref_dirty_background";
+ public static final String PREF_DIRTY_EXPIRE = "pref_dirty_expire";
+ public static final String PREF_DIRTY_WRITEBACK = "pref_dirty_writeback";
+ public static final String PREF_MIN_FREE_KB = "pref_min_free_kb";
+ public static final String PREF_OVERCOMMIT = "pref_overcommit";
+ public static final String PREF_SWAPPINESS = "pref_swappiness";
+ public static final String PREF_VFS = "pref_vfs";
+ public static final String DIRTY_RATIO_PATH = "/proc/sys/vm/dirty_ratio";
+ public static final String DIRTY_BACKGROUND_PATH = "/proc/sys/vm/dirty_background_ratio";
+ public static final String DIRTY_EXPIRE_PATH = "/proc/sys/vm/dirty_expire_centisecs";
+ public static final String DIRTY_WRITEBACK_PATH = "/proc/sys/vm/dirty_writeback_centisecs";
+ public static final String MIN_FREE_PATH = "/proc/sys/vm/min_free_kbytes";
+ public static final String OVERCOMMIT_PATH = "/proc/sys/vm/overcommit_ratio";
+ public static final String SWAPPINESS_PATH = "/proc/sys/vm/swappiness";
+ public static final String VFS_CACHE_PRESSURE_PATH = "/proc/sys/vm/vfs_cache_pressure";
+ public static final String VM_SOB = "vm_sob";
+
+ // Voltage control
+ public static final String VOLTAGE_SOB = "voltage_sob";
+ public static final String UV_MV_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/UV_mV_table";
+ public static final String VDD_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/vdd_levels";
+ public static final String COMMON_VDD_PATH = "/sys/devices/system/cpu/cpufreq/vdd_levels";
+ public static final String VDD_SYSFS_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/vdd_sysfs_levels";
+
+ //Tools
+ public static final String PREF_SH = "pref_sh";
+ public static final String PREF_WIPE_CACHE = "pref_wipe_cache";
+ public static final String NOT_FOUND = "not found";
+ public static final String FLASH_KERNEL = "pref_kernel_img";
+ public static final String FLASH_RECOVERY = "pref_recovery_img";
+ public static final String RESIDUAL_FILES = "pref_residual_files";
+ public static final String residualfiles[] = {"/data/log", "/data/tombstones", "/data/system/dropbox", "/data/system/usagestats", "/data/anr", "/data/local/tmp"};//add coresponding info in strings
+ public static final String PREF_FIX_PERMS = "pref_fix_perms";
+ public static final String PREF_LOG = "pref_log";
+ public static final String PREF_OPTIM_DB = "pref_optim_db";
+
+ //Freezer
+ public static final String PREF_FRREZE = "freeze_packs";
+ public static final String PREF_UNFRREZE = "unfreeze_packs";
+
+ //zRam
+ public static final String ISZRAM = "busybox echo `busybox zcat /proc/config.gz | busybox grep ZRAM | busybox grep -v ^#'`";
+ public static final String ZRAM_DEV = "/dev/block/zram0";
+ public static final String ZRAM_SIZE_PATH = "/sys/block/zram0/disksize";
+ public static final String ZRAM_RESET_PATH = "/sys/block/zram0/reset";
+ public static final String ZRAM_COMPR_PATH = "/sys/block/zram0/compr_data_size";
+ public static final String ZRAM_ORIG_PATH = "/sys/block/zram0/orig_data_size";
+ public static final String ZRAM_MEMTOT_PATH = "/sys/block/zram0/mem_used_total";
+
+ // PC Settings
+ public static final String PREF_USE_LIGHT_THEME = "use_light_theme";
+ public static final String PREF_WIDGET_BG_COLOR = "widget_bg_color";
+ public static final String PREF_WIDGET_TEXT_COLOR = "widget_text_color";
+
+}
+
+
diff --git a/src/com/dsht/open/PCSettings.java b/src/com/dsht/open/PCSettings.java
new file mode 100755
index 0000000..ae40ff8
--- /dev/null
+++ b/src/com/dsht/open/PCSettings.java
@@ -0,0 +1,72 @@
+/*
+ * Performance Control - An Android CPU Control application Copyright (C) 2012
+ * James Roberts
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.dsht.open;
+
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.R;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+
+
+public class PCSettings extends PreferenceFragment implements Constants, OnPreferenceChangeListener {
+
+ SharedPreferences mPreferences;
+ private CheckBoxPreference mLightThemePref;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ addPreferencesFromResource(R.xml.pc_settings);
+
+ mLightThemePref = (CheckBoxPreference) findPreference("use_light_theme");
+ Preference mVersion = findPreference("version_info");
+ mVersion.setTitle(getString(R.string.pt_ver) + VERSION_NUM);
+
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+ String key = preference.getKey();
+ if ("use_light_theme".equals(key)) {
+ Helpers.restartPC(getActivity());
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ return false;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+}
diff --git a/src/com/dsht/open/TimeInState.java b/src/com/dsht/open/TimeInState.java
new file mode 100755
index 0000000..b54329d
--- /dev/null
+++ b/src/com/dsht/open/TimeInState.java
@@ -0,0 +1,399 @@
+/*
+ * Performance Control - An Android CPU Control application Copyright (C)
+ * Brandon Valosek, 2011 <bvalosek@gmail.com> Copyright (C) Modified by 2012
+ * <James Roberts "xoomdevnet@gmail.com">
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.dsht.open;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.open.CPUStateMonitor.CPUStateMonitorException;
+import com.dsht.open.CPUStateMonitor.CpuState;
+
+public class TimeInState extends Fragment implements Constants {
+
+ private LinearLayout mStatesView;
+ private TextView mAdditionalStates;
+ private TextView mTotalStateTime;
+ private TextView mHeaderAdditionalStates;
+ private TextView mHeaderTotalStateTime;
+ private TextView mStatesWarning;
+ private boolean mUpdatingData = false;
+ private LayoutInflater mInflater;
+ private int mCpuNum = 1;
+ private CpuInfoListAdapter mCpuInfoListAdapter;
+ private CurCPUThread mCurCPUThread;
+
+ private CPUStateMonitor monitor = new CPUStateMonitor();
+ private Context context;
+ private SharedPreferences preferences;
+ private List<String> mCpuInfoListData;
+
+ public class CpuInfoListAdapter extends ArrayAdapter<String> {
+
+ public CpuInfoListAdapter(Context context, int resource, List<String> values) {
+ super(context, R.layout.cpu_info_item, resource, values);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View rowView = mInflater.inflate(R.layout.cpu_info_item, parent, false);
+ TextView cpuInfoCore = (TextView) rowView.findViewById(R.id.cpu_info_core);
+ TextView cpuInfoFreq = (TextView) rowView.findViewById(R.id.cpu_info_freq);
+ cpuInfoCore.setText(getString(R.string.core) + " " + String.valueOf(position) + ": ");
+ cpuInfoFreq.setText(mCpuInfoListData.get(position));
+ return rowView;
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ context = getActivity();
+ preferences = PreferenceManager.getDefaultSharedPreferences(context);
+ if (savedInstanceState != null) {
+ mUpdatingData = savedInstanceState.getBoolean("updatingData");
+ }
+ loadOffsets();
+ mCpuNum = Helpers.getNumOfCpus();
+ setRetainInstance(true);
+ setHasOptionsMenu(true);
+ if(MainActivity.menu != null && MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle(true);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup root, Bundle savedInstanceState) {
+ super.onCreateView(inflater, root, savedInstanceState);
+
+ View view = inflater.inflate(R.layout.time_in_state, root, false);
+
+ mStatesView = (LinearLayout) view.findViewById(R.id.ui_states_view);
+ mAdditionalStates = (TextView) view.findViewById(R.id.ui_additional_states);
+ mHeaderAdditionalStates = (TextView) view.findViewById(R.id.ui_header_additional_states);
+ mHeaderTotalStateTime = (TextView) view.findViewById(R.id.ui_header_total_state_time);
+ mStatesWarning = (TextView) view.findViewById(R.id.ui_states_warning);
+ mTotalStateTime = (TextView) view.findViewById(R.id.ui_total_state_time);
+ mInflater = inflater;
+ mCpuInfoListData = new ArrayList<String>(mCpuNum);
+ for (int i = 0; i < mCpuNum; i++) {
+ mCpuInfoListData.add("Core " + String.valueOf(i) + ": ");
+ }
+
+ mCpuInfoListAdapter = new CpuInfoListAdapter(
+ context, android.R.layout.simple_list_item_1, mCpuInfoListData);
+
+ ListView mCpuInfoList = (ListView) view.findViewById(R.id.cpu_info_list);
+ mCpuInfoList.setAdapter(mCpuInfoListAdapter);
+ mCurCPUThread = new CurCPUThread();
+ mCurCPUThread.start();
+ return view;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putBoolean("updatingData", mUpdatingData);
+ }
+
+ @Override
+ public void onResume() {
+ refreshData();
+ if (mCurCPUThread == null) {
+ mCurCPUThread = new CurCPUThread();
+ mCurCPUThread.start();
+ }
+ super.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ if (mCurCPUThread != null) {
+ if (mCurCPUThread.isAlive()) {
+ mCurCPUThread.interrupt();
+ try {
+ mCurCPUThread.join();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ mCurCPUThread = null;
+ }
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ if (!getResources().getBoolean(R.bool.config_showPerformanceOnly)) {
+ inflater.inflate(R.menu.time_in_state_menu, menu);
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.refresh:
+ refreshData();
+ break;
+ case R.id.reset:
+ try {
+ monitor.setOffsets();
+ } catch (Exception e) {
+ // not good
+ }
+
+ saveOffsets();
+ updateView();
+ break;
+ case R.id.restore:
+ monitor.removeOffsets();
+ saveOffsets();
+ updateView();
+ break;
+ }
+
+ return true;
+ }
+
+ public void updateView() {
+ mStatesView.removeAllViews();
+ List<String> extraStates = new ArrayList<String>();
+ for (CpuState state : monitor.getStates()) {
+ if (state.duration > 0) {
+ generateStateRow(state, mStatesView);
+ } else {
+ if (state.freq == 0) {
+ extraStates.add(getString(R.string.deep_sleep));
+ } else {
+ extraStates.add(state.freq / 1000 + " MHz");
+ }
+ }
+ }
+
+ if (monitor.getStates().size() == 0) {
+ mStatesWarning.setVisibility(View.VISIBLE);
+ mHeaderTotalStateTime.setVisibility(View.GONE);
+ mTotalStateTime.setVisibility(View.GONE);
+ mStatesView.setVisibility(View.GONE);
+ }
+
+ long totTime = monitor.getTotalStateTime() / 100;
+ mTotalStateTime.setText(toString(totTime));
+
+ if (extraStates.size() > 0) {
+ int n = 0;
+ String str = "";
+
+ for (String s : extraStates) {
+ if (n++ > 0)
+ str += ", ";
+ str += s;
+ }
+
+ mAdditionalStates.setVisibility(View.VISIBLE);
+ mHeaderAdditionalStates.setVisibility(View.VISIBLE);
+ mAdditionalStates.setText(str);
+ } else {
+ mAdditionalStates.setVisibility(View.GONE);
+ mHeaderAdditionalStates.setVisibility(View.GONE);
+ }
+ }
+
+ public void refreshData() {
+ if (!mUpdatingData) {
+ new RefreshStateDataTask().execute((Void) null);
+ }
+ }
+
+ private static String toString(long tSec) {
+ long h = (long) Math.floor(tSec / (60 * 60));
+ long m = (long) Math.floor((tSec - h * 60 * 60) / 60);
+ long s = tSec % 60;
+ String sDur;
+ sDur = h + ":";
+ if (m < 10)
+ sDur += "0";
+ sDur += m + ":";
+ if (s < 10)
+ sDur += "0";
+ sDur += s;
+
+ return sDur;
+ }
+
+ private View generateStateRow(CpuState state, ViewGroup parent) {
+
+ LayoutInflater inflater = LayoutInflater.from(context);
+ LinearLayout view = (LinearLayout) inflater.inflate(R.layout.state_row, parent, false);
+
+ float per = (float) state.duration * 100 / monitor.getTotalStateTime();
+ String sPer = (int) per + "%";
+
+
+ String sFreq;
+ if (state.freq == 0) {
+ sFreq = getString(R.string.deep_sleep);
+ } else {
+ sFreq = state.freq / 1000 + " MHz";
+ }
+
+ long tSec = state.duration / 100;
+ String sDur = toString(tSec);
+
+ TextView freqText = (TextView) view.findViewById(R.id.ui_freq_text);
+ TextView durText = (TextView) view.findViewById(R.id.ui_duration_text);
+ TextView perText = (TextView) view.findViewById(R.id.ui_percentage_text);
+ ProgressBar bar = (ProgressBar) view.findViewById(R.id.ui_bar);
+
+ freqText.setText(sFreq);
+ perText.setText(sPer);
+ durText.setText(sDur);
+ bar.setProgress((int) per);
+
+ parent.addView(view);
+ return view;
+ }
+
+ protected class RefreshStateDataTask extends AsyncTask<Void, Void, Void> {
+ @Override
+ protected Void doInBackground(Void... v) {
+ try {
+ monitor.updateStates();
+ } catch (CPUStateMonitorException e) {
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ mUpdatingData = true;
+ }
+
+ @Override
+ protected void onPostExecute(Void v) {
+ updateView();
+ mUpdatingData = false;
+ }
+ }
+
+ public void loadOffsets() {
+ String prefs = preferences.getString(PREF_OFFSETS, "");
+ if (prefs == null || prefs.length() < 1) {
+ return;
+ }
+
+ Map<Integer, Long> offsets = new HashMap<Integer, Long>();
+ String[] sOffsets = prefs.split(",");
+ for (String offset : sOffsets) {
+ String[] parts = offset.split(" ");
+ offsets.put(Integer.parseInt(parts[0]), Long.parseLong(parts[1]));
+ }
+
+ monitor.setOffsets(offsets);
+ }
+
+ public void saveOffsets() {
+ SharedPreferences.Editor editor = preferences.edit();
+ String str = "";
+ for (Map.Entry<Integer, Long> entry : monitor.getOffsets().entrySet()) {
+ str += entry.getKey() + " " + entry.getValue() + ",";
+ }
+ editor.putString(PREF_OFFSETS, str).commit();
+ }
+
+
+ protected class CurCPUThread extends Thread {
+ private boolean mInterrupt = false;
+
+ public void interrupt() {
+ mInterrupt = true;
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (!mInterrupt) {
+ sleep(500);
+ List<String> freqs = new ArrayList<String>();
+ for (int i = 0; i < mCpuNum; i++) {
+ String cpuFreq = CPU_PATH + String.valueOf(i) + CPU_FREQ_TAIL;
+ String curFreq = "0";
+ if (Helpers.fileExists(cpuFreq)) {
+ curFreq = Helpers.readOneLine(cpuFreq);
+ }
+ freqs.add(curFreq);
+ }
+ String[] freqArray = freqs.toArray(new String[freqs.size()]);
+ mCurCPUHandler.sendMessage(mCurCPUHandler.obtainMessage(0, freqArray));
+ }
+ } catch (InterruptedException e) {
+ //return;
+ }
+ }
+ }
+
+ protected Handler mCurCPUHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ String[] freqArray = (String[]) msg.obj;
+ for (int i = 0; i < freqArray.length; i++) {
+ // Convert freq in MHz
+ try {
+ int freqHz = Integer.parseInt(freqArray[i]);
+
+ if (freqHz == 0) {
+ mCpuInfoListData.set(i, getString(R.string.core_offline));
+ } else {
+ mCpuInfoListData.set(i, Integer.toString(freqHz / 1000) + " MHz");
+ }
+ } catch (Exception e) {
+ // Do nothing
+ }
+ }
+ mCpuInfoListAdapter.notifyDataSetChanged();
+ }
+ };
+}
diff --git a/src/com/dsht/open/VM.java b/src/com/dsht/open/VM.java
new file mode 100755
index 0000000..e9dbc04
--- /dev/null
+++ b/src/com/dsht/open/VM.java
@@ -0,0 +1,351 @@
+package com.dsht.open;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import java.io.File;
+
+import com.dsht.kerneltweaker.CustomPreference;
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.ListViewMultiChoiceModeListener;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kernetweaker.cmdprocessor.CMDProcessor;
+import com.dsht.settings.SettingsFragment;
+
+public class VM extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener, Constants {
+
+ private CustomPreference mDirtyRatio;
+ private CustomPreference mDirtyBackground;
+ private CustomPreference mDirtyExpireCentisecs;
+ private CustomPreference mDirtyWriteback;
+ private CustomPreference mMinFreeK;
+ private CustomPreference mOvercommit;
+ private CustomPreference mSwappiness;
+ private PreferenceScreen mRootScreen;
+ private CustomPreference mVfs;
+ String category = "vm";
+
+
+ private SharedPreferences mPreferences;
+
+ private int mSeekbarProgress;
+ private EditText settingText;
+ private Context context;
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ context = getActivity();
+ mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ mPreferences.registerOnSharedPreferenceChangeListener(this);
+ addPreferencesFromResource(R.xml.vm);
+
+ mRootScreen = (PreferenceScreen) findPreference("key_root");
+ mDirtyRatio = (CustomPreference) findPreference(PREF_DIRTY_RATIO);
+ mDirtyBackground = (CustomPreference) findPreference(PREF_DIRTY_BACKGROUND);
+ mDirtyExpireCentisecs = (CustomPreference) findPreference(PREF_DIRTY_EXPIRE);
+ mDirtyWriteback = (CustomPreference) findPreference(PREF_DIRTY_WRITEBACK);
+ mMinFreeK = (CustomPreference) findPreference(PREF_MIN_FREE_KB);
+ mOvercommit = (CustomPreference) findPreference(PREF_OVERCOMMIT);
+ mSwappiness = (CustomPreference) findPreference(PREF_SWAPPINESS);
+ mVfs = (CustomPreference) findPreference(PREF_VFS);
+
+ mDirtyRatio.setSummary(Helpers.readOneLine(DIRTY_RATIO_PATH));
+ mDirtyBackground.setSummary(Helpers.readOneLine(DIRTY_BACKGROUND_PATH));
+ mDirtyExpireCentisecs.setSummary(Helpers.readOneLine(DIRTY_EXPIRE_PATH));
+ mDirtyWriteback.setSummary(Helpers.readOneLine(DIRTY_WRITEBACK_PATH));
+ mMinFreeK.setSummary(Helpers.readOneLine(MIN_FREE_PATH));
+ mOvercommit.setSummary(Helpers.readOneLine(OVERCOMMIT_PATH));
+ mSwappiness.setSummary(Helpers.readOneLine(SWAPPINESS_PATH));
+ mVfs.setSummary(Helpers.readOneLine(VFS_CACHE_PRESSURE_PATH));
+
+ String color ="";
+ if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_GLOBAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_GLOBAL_COLOR, Color.parseColor("#FFFFFF"));
+ color = "#"+Integer.toHexString(col);
+ }else if(MainActivity.mPrefs.getBoolean(SettingsFragment.KEY_ENABLE_PERSONAL, false)) {
+ int col = MainActivity.mPrefs.getInt(SettingsFragment.KEY_VM, Color.parseColor("#ff0099cc"));
+ color = "#"+Integer.toHexString(col);
+ }
+ else {
+ color = getResources().getStringArray(R.array.menu_colors)[7];
+ }
+
+ mDirtyRatio.setTitleColor(color);
+ mDirtyBackground.setTitleColor(color);
+ mDirtyExpireCentisecs.setTitleColor(color);
+ mDirtyWriteback.setTitleColor(color);
+ mMinFreeK.setTitleColor(color);
+ mOvercommit.setTitleColor(color);
+ mSwappiness.setTitleColor(color);
+ mVfs.setTitleColor(color);
+
+ mDirtyRatio.setKey(DIRTY_RATIO_PATH);
+ mDirtyBackground.setKey(DIRTY_BACKGROUND_PATH);
+ mDirtyExpireCentisecs.setKey(DIRTY_EXPIRE_PATH);
+ mDirtyWriteback.setKey(DIRTY_WRITEBACK_PATH);
+ mMinFreeK.setKey(MIN_FREE_PATH);
+ mOvercommit.setKey(OVERCOMMIT_PATH);
+ mSwappiness.setKey(SWAPPINESS_PATH);
+ mVfs.setKey(VFS_CACHE_PRESSURE_PATH);
+
+ mDirtyRatio.setCategory(category);
+ mDirtyBackground.setCategory(category);
+ mDirtyExpireCentisecs.setCategory(category);
+ mDirtyWriteback.setCategory(category);
+ mMinFreeK.setCategory(category);
+ mOvercommit.setCategory(category);
+ mSwappiness.setCategory(category);
+ mVfs.setCategory(category);
+ MainActivity.menu.toggle(true);
+ setRetainInstance(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list, container,false);
+ ListView listView = (ListView) v.findViewById(android.R.id.list);
+ listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ registerForContextMenu(listView);
+ listView.setMultiChoiceModeListener(new ListViewMultiChoiceModeListener(
+ context,getActivity(),
+ listView,mRootScreen,
+ false,
+ MainActivity.db,
+ MainActivity.vddDb));
+ return v;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (!new File(DYNAMIC_DIRTY_WRITEBACK_PATH).exists()) {
+ mDirtyWriteback.setEnabled(true);
+ } else {
+ mDirtyWriteback.setEnabled(
+ !Helpers.readOneLine(DYNAMIC_DIRTY_WRITEBACK_PATH).equals("1"));
+ }
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+ if (preference == mDirtyRatio) {
+ String title = getString(R.string.dirty_ratio_title);
+ int currentProgress = Integer.parseInt(Helpers.readOneLine(DIRTY_RATIO_PATH));
+ openDialog(currentProgress, title, 0, 100, preference,
+ DIRTY_RATIO_PATH, PREF_DIRTY_RATIO);
+ return true;
+ } else if (preference == mDirtyBackground) {
+ String title = getString(R.string.dirty_background_title);
+ int currentProgress = Integer.parseInt(Helpers.readOneLine(DIRTY_BACKGROUND_PATH));
+ openDialog(currentProgress, title, 0, 100, preference,
+ DIRTY_BACKGROUND_PATH, PREF_DIRTY_BACKGROUND);
+ return true;
+ } else if (preference == mDirtyExpireCentisecs) {
+ String title = getString(R.string.dirty_expire_title);
+ int currentProgress = Integer.parseInt(Helpers.readOneLine(DIRTY_EXPIRE_PATH));
+ openDialog(currentProgress, title, 0, 5000, preference,
+ DIRTY_EXPIRE_PATH, PREF_DIRTY_EXPIRE);
+ return true;
+ } else if (preference == mDirtyWriteback) {
+ String title = getString(R.string.dirty_writeback_title);
+ int currentProgress = Integer.parseInt(Helpers.readOneLine(DIRTY_WRITEBACK_PATH));
+ openDialog(currentProgress, title, 0, 5000, preference,
+ DIRTY_WRITEBACK_PATH, PREF_DIRTY_WRITEBACK);
+ return true;
+ } else if (preference == mMinFreeK) {
+ String title = getString(R.string.min_free_title);
+ int currentProgress = Integer.parseInt(Helpers.readOneLine(MIN_FREE_PATH));
+ openDialog(currentProgress, title, 0, 8192, preference,
+ MIN_FREE_PATH, PREF_MIN_FREE_KB);
+ return true;
+ } else if (preference == mOvercommit) {
+ String title = getString(R.string.overcommit_title);
+ int currentProgress = Integer.parseInt(Helpers.readOneLine(OVERCOMMIT_PATH));
+ openDialog(currentProgress, title, 0, 100, preference,
+ OVERCOMMIT_PATH, PREF_OVERCOMMIT);
+ return true;
+ } else if (preference == mSwappiness) {
+ String title = getString(R.string.swappiness_title);
+ int currentProgress = Integer.parseInt(Helpers.readOneLine(SWAPPINESS_PATH));
+ openDialog(currentProgress, title, 0, 100, preference,
+ SWAPPINESS_PATH, PREF_SWAPPINESS);
+ return true;
+ } else if (preference == mVfs) {
+ String title = getString(R.string.vfs_title);
+ int currentProgress = Integer.parseInt(Helpers.readOneLine(VFS_CACHE_PRESSURE_PATH));
+ openDialog(currentProgress, title, 0, 200, preference,
+ VFS_CACHE_PRESSURE_PATH, PREF_VFS);
+ return true;
+ }
+
+ return super.onPreferenceTreeClick(preferenceScreen, preference);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, String key) {
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+
+ if (key.equals(VM_SOB)) {
+ if (sharedPreferences.getBoolean(key, false)) {
+ editor.putInt(PREF_DIRTY_RATIO,
+ Integer.parseInt(Helpers.readOneLine(DIRTY_RATIO_PATH)))
+ .putInt(PREF_DIRTY_BACKGROUND,
+ Integer.parseInt(Helpers.readOneLine(DIRTY_BACKGROUND_PATH)))
+ .putInt(PREF_DIRTY_EXPIRE,
+ Integer.parseInt(Helpers.readOneLine(DIRTY_EXPIRE_PATH)))
+ .putInt(PREF_DIRTY_WRITEBACK,
+ Integer.parseInt(Helpers.readOneLine(DIRTY_WRITEBACK_PATH)))
+ .putInt(PREF_MIN_FREE_KB,
+ Integer.parseInt(Helpers.readOneLine(MIN_FREE_PATH)))
+ .putInt(PREF_OVERCOMMIT,
+ Integer.parseInt(Helpers.readOneLine(OVERCOMMIT_PATH)))
+ .putInt(PREF_SWAPPINESS,
+ Integer.parseInt(Helpers.readOneLine(SWAPPINESS_PATH)))
+ .putInt(PREF_VFS,
+ Integer.parseInt(Helpers.readOneLine(VFS_CACHE_PRESSURE_PATH)))
+ .apply();
+ } else {
+ editor.remove(PREF_DIRTY_RATIO)
+ .remove(PREF_DIRTY_BACKGROUND)
+ .remove(PREF_DIRTY_EXPIRE)
+ .remove(PREF_DIRTY_WRITEBACK)
+ .remove(PREF_MIN_FREE_KB)
+ .remove(PREF_OVERCOMMIT)
+ .remove(PREF_SWAPPINESS)
+ .remove(PREF_VFS)
+ .apply();
+ }
+ }
+ }
+
+ public void openDialog(int currentProgress, String title, final int min, final int max,
+ final Preference pref, final String path, final String key) {
+ Resources res = context.getResources();
+ String cancel = res.getString(R.string.cancel);
+ String ok = res.getString(R.string.ok);
+ LayoutInflater factory = LayoutInflater.from(context);
+ final View alphaDialog = factory.inflate(R.layout.seekbar_dialog, null);
+
+ final SeekBar seekbar = (SeekBar) alphaDialog.findViewById(R.id.seek_bar);
+
+ seekbar.setMax(max);
+ seekbar.setProgress(currentProgress);
+
+ settingText = (EditText) alphaDialog.findViewById(R.id.setting_text);
+ settingText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ int val = Integer.parseInt(settingText.getText().toString());
+ seekbar.setProgress(val);
+ return true;
+ }
+ return false;
+ }
+ });
+ settingText.setText(Integer.toString(currentProgress));
+ settingText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ try {
+ int val = Integer.parseInt(s.toString());
+ if (val > max) {
+ s.replace(0, s.length(), Integer.toString(max));
+ val = max;
+ }
+ seekbar.setProgress(val);
+ } catch (NumberFormatException ex) {
+ }
+ }
+ });
+
+ SeekBar.OnSeekBarChangeListener seekBarChangeListener =
+ new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
+ mSeekbarProgress = seekbar.getProgress();
+ if (fromUser) {
+ settingText.setText(Integer.toString(mSeekbarProgress));
+ }
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekbar) {
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekbar) {
+ }
+ };
+ seekbar.setOnSeekBarChangeListener(seekBarChangeListener);
+
+ new AlertDialog.Builder(context)
+ .setTitle(title)
+ .setView(alphaDialog)
+ .setNegativeButton(cancel,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // nothing
+ }
+ })
+ .setPositiveButton(ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ int val = Integer.parseInt(settingText.getText().toString());
+ if (val < min) {
+ val = min;
+ }
+ seekbar.setProgress(val);
+ int newProgress = seekbar.getProgress();
+ pref.setSummary(Integer.toString(newProgress));
+ if (Helpers.isSystemApp(getActivity())) {
+ Helpers.writeOneLine(path, Integer.toString(newProgress));
+ } else {
+ CMDProcessor.runSuCommand("busybox echo " + newProgress + " > " + path);
+ }
+ final SharedPreferences.Editor editor = mPreferences.edit();
+ editor.putInt(key, newProgress);
+ editor.commit();
+ }
+ }).create().show();
+ }
+}
+
+
diff --git a/src/com/dsht/settings/SettingsFragment.java b/src/com/dsht/settings/SettingsFragment.java
new file mode 100644
index 0000000..c397ffa
--- /dev/null
+++ b/src/com/dsht/settings/SettingsFragment.java
@@ -0,0 +1,322 @@
+package com.dsht.settings;
+
+import java.io.File;
+
+import it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerPreference;
+
+import com.dsht.kerneltweaker.Helpers;
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+import com.dsht.kerneltweaker.Startup;
+
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.app.AlertDialog.Builder;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.Environment;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class SettingsFragment extends PreferenceFragment implements OnPreferenceChangeListener, OnPreferenceClickListener {
+
+ public static final String KEY_ENABLE_GLOBAL = "key_enable_global";
+ public static final String KEY_ENABLE_PERSONAL = "key_enable_personal";
+ public static final String KEY_GLOBAL_COLOR = "key_global_color";
+ public static final String KEY_THEME = "key_theme";
+ public static final String KEY_STAT = "key_color_stats";
+ public static final String KEY_INFO = "key_color_info";
+ public static final String KEY_CPU = "key_color_cpu";
+ public static final String KEY_GPU = "key_color_gpu";
+ public static final String KEY_UV = "key_color_uv";
+ public static final String KEY_KERNEL = "key_color_kernel";
+ public static final String KEY_LMK = "key_color_lmk";
+ public static final String KEY_VM = "key_color_vm";
+ public static final String KEY_REVIEW = "key_color_review";
+ public static final String KEY_FILE = "key_color_file";
+ public static final String KEY_BAK = "key_color_backup";
+ public static final String KEY_RECOVERY = "key_color_recovery";
+ public static final String KEY_PERSONAL_CAT = "key_personal_category";
+ public static final String KEY_PROP = "key_color_prop";
+ public static final String KEY_INIT = "key_color_init";
+ public static final String KEY_BLUR = "key_color_blur";
+ public static final String KEY_DEBUG = "key_debug";
+ public static final String KEY_SLOG = "key_slog";
+ public static final String LOG_FILE = Environment.getExternalStorageDirectory().getAbsolutePath()+"/KernelTweaker_log.txt";
+ public static final String KEY_RUNLOG = "key_runlog";
+
+ private CheckBoxPreference mEnable;
+ private CheckBoxPreference mPersonal;
+ private ColorPickerPreference mColor;
+ private ColorPickerPreference mStats;
+ private ColorPickerPreference mInfo;
+ private ColorPickerPreference mCpu;
+ private ColorPickerPreference mGpu;
+ private ColorPickerPreference mUv;
+ private ColorPickerPreference mKernel;
+ private ColorPickerPreference mLmk;
+ private ColorPickerPreference mVm;
+ private ColorPickerPreference mReview;
+ private ColorPickerPreference mFile;
+ private ColorPickerPreference mBak;
+ private ColorPickerPreference mRecovery;
+ private ColorPickerPreference mProp;
+ private ColorPickerPreference mInit;
+ private ColorPickerPreference mBlur;
+ private CheckBoxPreference mTheme;
+ private SharedPreferences mPrefs;
+ private PreferenceCategory mPersonalCat;
+ private Preference mLog;
+ private Preference mRunLog;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.pref_settings);
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ mEnable = (CheckBoxPreference) findPreference(KEY_ENABLE_GLOBAL);
+ mPersonal = (CheckBoxPreference) findPreference(KEY_ENABLE_PERSONAL);
+ mTheme = (CheckBoxPreference) findPreference(KEY_THEME);
+ mColor = (ColorPickerPreference) findPreference(KEY_GLOBAL_COLOR);
+ mStats = (ColorPickerPreference) findPreference(KEY_STAT);
+ mInfo = (ColorPickerPreference) findPreference(KEY_INFO);
+ mCpu = (ColorPickerPreference) findPreference(KEY_CPU);
+ mGpu = (ColorPickerPreference) findPreference(KEY_GPU);
+ mUv = (ColorPickerPreference) findPreference(KEY_UV);
+ mKernel = (ColorPickerPreference) findPreference(KEY_KERNEL);
+ mLmk = (ColorPickerPreference) findPreference(KEY_LMK);
+ mVm = (ColorPickerPreference) findPreference(KEY_VM);
+ mReview = (ColorPickerPreference) findPreference(KEY_REVIEW);
+ mFile = (ColorPickerPreference) findPreference(KEY_FILE);
+ mBak = (ColorPickerPreference) findPreference(KEY_BAK);
+ mRecovery = (ColorPickerPreference) findPreference(KEY_RECOVERY);
+
+ mProp = (ColorPickerPreference) findPreference(KEY_PROP);
+ mInit = (ColorPickerPreference) findPreference(KEY_INIT);
+ mBlur = (ColorPickerPreference) findPreference(KEY_BLUR);
+
+ mPersonalCat = (PreferenceCategory) findPreference(KEY_PERSONAL_CAT);
+
+ mLog = (Preference) findPreference(KEY_SLOG);
+ mRunLog = (Preference) findPreference(KEY_RUNLOG);
+
+
+ boolean enabled = mPrefs.getBoolean(KEY_ENABLE_GLOBAL, false);
+ mColor.setEnabled(enabled);
+
+ mEnable.setOnPreferenceChangeListener(this);
+ mTheme.setOnPreferenceChangeListener(this);
+ mColor.setOnPreferenceChangeListener(this);
+ mPersonal.setOnPreferenceChangeListener(this);
+ mStats.setOnPreferenceChangeListener(this);;
+ mInfo.setOnPreferenceChangeListener(this);
+ mCpu.setOnPreferenceChangeListener(this);
+ mGpu.setOnPreferenceChangeListener(this);
+ mUv.setOnPreferenceChangeListener(this);
+ mKernel.setOnPreferenceChangeListener(this);
+ mLmk.setOnPreferenceChangeListener(this);
+ mVm.setOnPreferenceChangeListener(this);
+ mReview.setOnPreferenceChangeListener(this);
+ mFile.setOnPreferenceChangeListener(this);
+ mBak.setOnPreferenceChangeListener(this);
+ mRecovery.setOnPreferenceChangeListener(this);
+ mProp.setOnPreferenceChangeListener(this);
+ mInit.setOnPreferenceChangeListener(this);
+ mBlur.setOnPreferenceChangeListener(this);
+ mLog.setOnPreferenceClickListener(this);
+ mRunLog.setOnPreferenceClickListener(this);
+
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle(true);
+ }
+
+ if(!mPrefs.getBoolean(KEY_ENABLE_PERSONAL, false)) {
+ this.getPreferenceScreen().removePreference(mPersonalCat);
+ }
+
+
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object newValue) {
+ // TODO Auto-generated method stub
+ SharedPreferences.Editor editor = mPrefs.edit();
+ if(pref == mEnable) {
+ editor.putBoolean(KEY_ENABLE_GLOBAL, (Boolean)newValue);
+ mColor.setEnabled((Boolean)newValue);
+ MainActivity.mAdapter.notifyDataSetChanged();
+ if(mPersonal.isChecked()) {
+ mPersonal.setChecked(false);
+ }
+ return true;
+ }
+ if(pref == mPersonal) {
+ editor.putBoolean(KEY_ENABLE_PERSONAL, (Boolean)newValue);
+ MainActivity.mAdapter.notifyDataSetChanged();
+ if(mEnable.isChecked()) {
+ mEnable.setChecked(false);
+ }
+ if(!(Boolean)newValue) {
+ this.getPreferenceScreen().removePreference(mPersonalCat);
+ }else {
+ this.getPreferenceScreen().addPreference(mPersonalCat);
+ }
+ return true;
+ }
+ if(pref == mColor) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mTheme) {
+ editor.putBoolean(KEY_THEME, (Boolean)newValue);
+ MainActivity.setAppTheme();
+ Helpers.restartPC(getActivity());
+ return true;
+ }
+ if(pref == mStats) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mInfo) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mCpu) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mGpu) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mUv) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mKernel) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mLmk) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mVm) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mReview) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mFile) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mBak) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mRecovery) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mProp) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mInit) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ if(pref == mBlur) {
+ MainActivity.mAdapter.notifyDataSetChanged();
+ return true;
+ }
+ editor.commit();
+ return false;
+ }
+
+ private void showDialog() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle("Info");
+ builder.setMessage("KernelTweaker needs to be restarted to apply changes.\nRestart now?");
+ builder.setPositiveButton("Restart", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ Helpers.restartPC(getActivity());
+ }
+ })
+ .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ dialog.cancel();
+ }
+ });
+ builder.create().show();
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference pref) {
+ // TODO Auto-generated method stub
+ if(pref == mLog) {
+ if(new File(LOG_FILE).exists()) {
+ String fcontent = Helpers.readFileViaShell(LOG_FILE, false);
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View v = inflater.inflate(R.layout.log_dialog, null, false);
+ TextView textLog = (TextView)v.findViewById(R.id.text);
+ textLog.setText(fcontent);
+ builder.setTitle("Log content");
+ builder.setView(v);
+ builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ dialog.cancel();
+ }
+ });
+ builder.setNegativeButton("Delete Log", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ new File(LOG_FILE).delete();
+ dialog.cancel();
+
+ }
+ });
+ builder.create().show();
+ } else {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(null);
+ builder.setMessage("Log File not found!\nPlease enable debugging and reboot your phone!");
+ builder.create().show();
+ }
+ }
+ if(pref == mRunLog) {
+ Startup.applyValuesAsync(getActivity(), MainActivity.db, MainActivity.vddDb,true);
+ }
+ return false;
+ }
+
+}
diff --git a/src/com/dsht/settings/infos.java b/src/com/dsht/settings/infos.java
new file mode 100644
index 0000000..bc92a6e
--- /dev/null
+++ b/src/com/dsht/settings/infos.java
@@ -0,0 +1,129 @@
+package com.dsht.settings;
+
+import com.dsht.kerneltweaker.MainActivity;
+import com.dsht.kerneltweaker.R;
+
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+public class infos extends PreferenceFragment implements OnPreferenceClickListener {
+
+ private String KEY_DSHT = "key_dsht";
+ private String KEY_CESCO = "key_cesco";
+ private String KEY_SOLLYX = "key_sollyx";
+ private String KEY_AOKP = "key_aokp";
+ private String KEY_OMNI = "key_omni";
+ private String KEY_DU = "key_du";
+ private String KEY_SLIDINGMENU = "key_slidingmenu";
+
+ private Preference mDsht,
+ mCesco,
+ mSollyx,
+ mAokp,
+ mOmni,
+ mDu,
+ mSlidingMenu;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.infos);
+
+ mDsht = (Preference) findPreference(KEY_DSHT);
+ mCesco = (Preference) findPreference(KEY_CESCO);
+ mSollyx = (Preference) findPreference(KEY_SOLLYX);
+ mAokp = (Preference) findPreference(KEY_AOKP);
+ mOmni = (Preference) findPreference(KEY_OMNI);
+ mDu = (Preference) findPreference(KEY_DU);
+ mSlidingMenu = (Preference) findPreference(KEY_SLIDINGMENU);
+
+ PackageInfo pInfo = null;
+ try {
+ pInfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0);
+ } catch (NameNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ String version = pInfo.versionName;
+
+ mDsht.setTitle(R.string.app_name);
+ mDsht.setIcon(R.drawable.ic_launcher);
+ mDsht.setSummary("Version: "+version);
+
+ mCesco.setIcon(R.drawable.cesco);
+ mSollyx.setIcon(R.drawable.sollyx_google);
+
+ mAokp.setIcon(R.drawable.aokp);
+ mOmni.setIcon(R.drawable.omni);
+ mDu.setIcon(R.drawable.du);
+
+ mSlidingMenu.setIcon(R.drawable.github);
+
+ mDsht.setOnPreferenceClickListener(this);
+ mCesco.setOnPreferenceClickListener(this);
+ mSollyx.setOnPreferenceClickListener(this);
+ mAokp.setOnPreferenceClickListener(this);
+ mOmni.setOnPreferenceClickListener(this);
+ mDu.setOnPreferenceClickListener(this);
+ mSlidingMenu.setOnPreferenceClickListener(this);
+
+ if(MainActivity.menu.isMenuShowing()) {
+ MainActivity.menu.toggle(true);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View v = inflater.inflate(R.layout.layout_list, container,false);
+ ListView listView = (ListView) v.findViewById(android.R.id.list);
+ View header = inflater.inflate(R.layout.header, null, false);
+ listView.addHeaderView(header);
+ return v;
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference pref) {
+ // TODO Auto-generated method stub
+ String url = "";
+ if(pref == mDsht) {
+ url = "https://play.google.com/store/apps/developer?id=DSHT";
+ }
+ if(pref == mCesco) {
+ url = "https://plus.google.com/u/0/+FrancescoRigamonti/posts";
+ }
+ if(pref == mSollyx) {
+ url = "https://plus.google.com/u/0/116757450567339042397/posts";
+ }
+ if(pref == mAokp) {
+ url = "https://github.com/AOKP";
+ }
+ if(pref == mOmni) {
+ url = "https://github.com/omnirom/";
+ }
+ if(pref == mDu) {
+ url = "https://github.com/DirtyUnicorns-KitKat/";
+ }
+ if(pref == mSlidingMenu) {
+ url = "https://github.com/jfeinstein10/slidingmenu";
+ }
+ Uri uri = Uri.parse(url);
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ startActivity(intent);
+
+ return false;
+ }
+
+
+
+}
diff --git a/src/com/mobeta/android/dslv/DragSortController.java b/src/com/mobeta/android/dslv/DragSortController.java
new file mode 100755
index 0000000..41d477e
--- /dev/null
+++ b/src/com/mobeta/android/dslv/DragSortController.java
@@ -0,0 +1,468 @@
+package com.mobeta.android.dslv;
+
+import android.graphics.Point;
+import android.view.GestureDetector;
+import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.widget.AdapterView;
+
+/**
+ * Class that starts and stops item drags on a {@link DragSortListView}
+ * based on touch gestures. This class also inherits from
+ * {@link SimpleFloatViewManager}, which provides basic float View
+ * creation.
+ *
+ * An instance of this class is meant to be passed to the methods
+ * {@link DragSortListView#setTouchListener()} and
+ * {@link DragSortListView#setFloatViewManager()} of your
+ * {@link DragSortListView} instance.
+ */
+public class DragSortController extends SimpleFloatViewManager implements View.OnTouchListener, GestureDetector.OnGestureListener {
+
+ /**
+ * Drag init mode enum.
+ */
+ public static final int ON_DOWN = 0;
+ public static final int ON_DRAG = 1;
+ public static final int ON_LONG_PRESS = 2;
+
+ private int mDragInitMode = ON_DOWN;
+
+ private boolean mSortEnabled = true;
+
+ /**
+ * Remove mode enum.
+ */
+ public static final int CLICK_REMOVE = 0;
+ public static final int FLING_REMOVE = 1;
+
+ /**
+ * The current remove mode.
+ */
+ private int mRemoveMode;
+
+ private boolean mRemoveEnabled = false;
+ private boolean mIsRemoving = false;
+
+ private GestureDetector mDetector;
+
+ private GestureDetector mFlingRemoveDetector;
+
+ private int mTouchSlop;
+
+ public static final int MISS = -1;
+
+ private int mHitPos = MISS;
+ private int mFlingHitPos = MISS;
+
+ private int mClickRemoveHitPos = MISS;
+
+ private int[] mTempLoc = new int[2];
+
+ private int mItemX;
+ private int mItemY;
+
+ private int mCurrX;
+ private int mCurrY;
+
+ private boolean mDragging = false;
+
+ private float mFlingSpeed = 500f;
+
+ private int mDragHandleId;
+
+ private int mClickRemoveId;
+
+ private int mFlingHandleId;
+ private boolean mCanDrag;
+
+ private DragSortListView mDslv;
+ private int mPositionX;
+
+ /**
+ * Calls {@link #DragSortController(DragSortListView, int)} with a
+ * 0 drag handle id, FLING_RIGHT_REMOVE remove mode,
+ * and ON_DOWN drag init. By default, sorting is enabled, and
+ * removal is disabled.
+ *
+ * @param dslv The DSLV instance
+ */
+ public DragSortController(DragSortListView dslv) {
+ this(dslv, 0, ON_DOWN, FLING_REMOVE);
+ }
+
+ public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode, int removeMode) {
+ this(dslv, dragHandleId, dragInitMode, removeMode, 0);
+ }
+
+ public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode, int removeMode, int clickRemoveId) {
+ this(dslv, dragHandleId, dragInitMode, removeMode, clickRemoveId, 0);
+ }
+
+ /**
+ * By default, sorting is enabled, and removal is disabled.
+ *
+ * @param dslv The DSLV instance
+ * @param dragHandleId The resource id of the View that represents
+ * the drag handle in a list item.
+ */
+ public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode,
+ int removeMode, int clickRemoveId, int flingHandleId) {
+ super(dslv);
+ mDslv = dslv;
+ mDetector = new GestureDetector(dslv.getContext(), this);
+ mFlingRemoveDetector = new GestureDetector(dslv.getContext(), mFlingRemoveListener);
+ mFlingRemoveDetector.setIsLongpressEnabled(false);
+ mTouchSlop = ViewConfiguration.get(dslv.getContext()).getScaledTouchSlop();
+ mDragHandleId = dragHandleId;
+ mClickRemoveId = clickRemoveId;
+ mFlingHandleId = flingHandleId;
+ setRemoveMode(removeMode);
+ setDragInitMode(dragInitMode);
+ }
+
+
+ public int getDragInitMode() {
+ return mDragInitMode;
+ }
+
+ /**
+ * Set how a drag is initiated. Needs to be one of
+ * {@link ON_DOWN}, {@link ON_DRAG}, or {@link ON_LONG_PRESS}.
+ *
+ * @param mode The drag init mode.
+ */
+ public void setDragInitMode(int mode) {
+ mDragInitMode = mode;
+ }
+
+ /**
+ * Enable/Disable list item sorting. Disabling is useful if only item
+ * removal is desired. Prevents drags in the vertical direction.
+ *
+ * @param enabled Set <code>true</code> to enable list
+ * item sorting.
+ */
+ public void setSortEnabled(boolean enabled) {
+ mSortEnabled = enabled;
+ }
+
+ public boolean isSortEnabled() {
+ return mSortEnabled;
+ }
+
+ /**
+ * One of {@link CLICK_REMOVE}, {@link FLING_RIGHT_REMOVE},
+ * {@link FLING_LEFT_REMOVE},
+ * {@link SLIDE_RIGHT_REMOVE}, or {@link SLIDE_LEFT_REMOVE}.
+ */
+ public void setRemoveMode(int mode) {
+ mRemoveMode = mode;
+ }
+
+ public int getRemoveMode() {
+ return mRemoveMode;
+ }
+
+ /**
+ * Enable/Disable item removal without affecting remove mode.
+ */
+ public void setRemoveEnabled(boolean enabled) {
+ mRemoveEnabled = enabled;
+ }
+
+ public boolean isRemoveEnabled() {
+ return mRemoveEnabled;
+ }
+
+ /**
+ * Set the resource id for the View that represents the drag
+ * handle in a list item.
+ *
+ * @param id An android resource id.
+ */
+ public void setDragHandleId(int id) {
+ mDragHandleId = id;
+ }
+
+ /**
+ * Set the resource id for the View that represents the fling
+ * handle in a list item.
+ *
+ * @param id An android resource id.
+ */
+ public void setFlingHandleId(int id) {
+ mFlingHandleId = id;
+ }
+
+ /**
+ * Set the resource id for the View that represents click
+ * removal button.
+ *
+ * @param id An android resource id.
+ */
+ public void setClickRemoveId(int id) {
+ mClickRemoveId = id;
+ }
+
+ /**
+ * Sets flags to restrict certain motions of the floating View
+ * based on DragSortController settings (such as remove mode).
+ * Starts the drag on the DragSortListView.
+ *
+ * @param position The list item position (includes headers).
+ * @param deltaX Touch x-coord minus left edge of floating View.
+ * @param deltaY Touch y-coord minus top edge of floating View.
+ *
+ * @return True if drag started, false otherwise.
+ */
+ public boolean startDrag(int position, int deltaX, int deltaY) {
+
+ int dragFlags = 0;
+ if (mSortEnabled && !mIsRemoving) {
+ dragFlags |= DragSortListView.DRAG_POS_Y | DragSortListView.DRAG_NEG_Y;
+ }
+ if (mRemoveEnabled && mIsRemoving) {
+ dragFlags |= DragSortListView.DRAG_POS_X;
+ dragFlags |= DragSortListView.DRAG_NEG_X;
+ }
+
+ mDragging = mDslv.startDrag(position - mDslv.getHeaderViewsCount(), dragFlags, deltaX,
+ deltaY);
+ return mDragging;
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent ev) {
+ if (!mDslv.isDragEnabled() || mDslv.listViewIntercepted()) {
+ return false;
+ }
+
+ mDetector.onTouchEvent(ev);
+ if (mRemoveEnabled && mDragging && mRemoveMode == FLING_REMOVE) {
+ mFlingRemoveDetector.onTouchEvent(ev);
+ }
+
+ int action = ev.getAction() & MotionEvent.ACTION_MASK;
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ mCurrX = (int) ev.getX();
+ mCurrY = (int) ev.getY();
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mRemoveEnabled && mIsRemoving) {
+ int x = mPositionX >= 0 ? mPositionX : -mPositionX;
+ int removePoint = mDslv.getWidth() / 2;
+ if (x > removePoint) {
+ mDslv.stopDragWithVelocity(true, 0);
+ }
+ }
+ case MotionEvent.ACTION_CANCEL:
+ mIsRemoving = false;
+ mDragging = false;
+ break;
+ }
+
+ return false;
+ }
+
+ /**
+ * Overrides to provide fading when slide removal is enabled.
+ */
+ @Override
+ public void onDragFloatView(View floatView, Point position, Point touch) {
+
+ if (mRemoveEnabled && mIsRemoving) {
+ mPositionX = position.x;
+ }
+ }
+
+ /**
+ * Get the position to start dragging based on the ACTION_DOWN
+ * MotionEvent. This function simply calls
+ * {@link #dragHandleHitPosition(MotionEvent)}. Override
+ * to change drag handle behavior;
+ * this function is called internally when an ACTION_DOWN
+ * event is detected.
+ *
+ * @param ev The ACTION_DOWN MotionEvent.
+ *
+ * @return The list position to drag if a drag-init gesture is
+ * detected; MISS if unsuccessful.
+ */
+ public int startDragPosition(MotionEvent ev) {
+ return dragHandleHitPosition(ev);
+ }
+
+ public int startFlingPosition(MotionEvent ev) {
+ return mRemoveMode == FLING_REMOVE ? flingHandleHitPosition(ev) : MISS;
+ }
+
+ /**
+ * Checks for the touch of an item's drag handle (specified by
+ * {@link #setDragHandleId(int)}), and returns that item's position
+ * if a drag handle touch was detected.
+ *
+ * @param ev The ACTION_DOWN MotionEvent.
+
+ * @return The list position of the item whose drag handle was
+ * touched; MISS if unsuccessful.
+ */
+ public int dragHandleHitPosition(MotionEvent ev) {
+ return viewIdHitPosition(ev, mDragHandleId);
+ }
+
+ public int flingHandleHitPosition(MotionEvent ev) {
+ return viewIdHitPosition(ev, mFlingHandleId);
+ }
+
+ public int viewIdHitPosition(MotionEvent ev, int id) {
+ final int x = (int) ev.getX();
+ final int y = (int) ev.getY();
+
+ int touchPos = mDslv.pointToPosition(x, y); // includes headers/footers
+
+ final int numHeaders = mDslv.getHeaderViewsCount();
+ final int numFooters = mDslv.getFooterViewsCount();
+ final int count = mDslv.getCount();
+
+ // Log.d("mobeta", "touch down on position " + itemnum);
+ // We're only interested if the touch was on an
+ // item that's not a header or footer.
+ if (touchPos != AdapterView.INVALID_POSITION && touchPos >= numHeaders
+ && touchPos < (count - numFooters)) {
+ final View item = mDslv.getChildAt(touchPos - mDslv.getFirstVisiblePosition());
+ final int rawX = (int) ev.getRawX();
+ final int rawY = (int) ev.getRawY();
+
+ View dragBox = id == 0 ? item : (View) item.findViewById(id);
+ if (dragBox != null) {
+ dragBox.getLocationOnScreen(mTempLoc);
+
+ if (rawX > mTempLoc[0] && rawY > mTempLoc[1] &&
+ rawX < mTempLoc[0] + dragBox.getWidth() &&
+ rawY < mTempLoc[1] + dragBox.getHeight()) {
+
+ mItemX = item.getLeft();
+ mItemY = item.getTop();
+
+ return touchPos;
+ }
+ }
+ }
+
+ return MISS;
+ }
+
+ @Override
+ public boolean onDown(MotionEvent ev) {
+ if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
+ mClickRemoveHitPos = viewIdHitPosition(ev, mClickRemoveId);
+ }
+
+ mHitPos = startDragPosition(ev);
+ if (mHitPos != MISS && mDragInitMode == ON_DOWN) {
+ startDrag(mHitPos, (int) ev.getX() - mItemX, (int) ev.getY() - mItemY);
+ }
+
+ mIsRemoving = false;
+ mCanDrag = true;
+ mPositionX = 0;
+ mFlingHitPos = startFlingPosition(ev);
+
+ return true;
+ }
+
+ @Override
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+
+ final int x1 = (int) e1.getX();
+ final int y1 = (int) e1.getY();
+ final int x2 = (int) e2.getX();
+ final int y2 = (int) e2.getY();
+ final int deltaX = x2 - mItemX;
+ final int deltaY = y2 - mItemY;
+
+ if (mCanDrag && !mDragging && (mHitPos != MISS || mFlingHitPos != MISS)) {
+ if (mHitPos != MISS) {
+ if (mDragInitMode == ON_DRAG && Math.abs(y2 - y1) > mTouchSlop && mSortEnabled) {
+ startDrag(mHitPos, deltaX, deltaY);
+ }
+ else if (mDragInitMode != ON_DOWN && Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled)
+ {
+ mIsRemoving = true;
+ startDrag(mFlingHitPos, deltaX, deltaY);
+ }
+ } else if (mFlingHitPos != MISS) {
+ if (Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled) {
+ mIsRemoving = true;
+ startDrag(mFlingHitPos, deltaX, deltaY);
+ } else if (Math.abs(y2 - y1) > mTouchSlop) {
+ mCanDrag = false; // if started to scroll the list then
+ // don't allow sorting nor fling-removing
+ }
+ }
+ }
+ // return whatever
+ return false;
+ }
+
+ @Override
+ public void onLongPress(MotionEvent e) {
+ // Log.d("mobeta", "lift listener long pressed");
+ if (mHitPos != MISS && mDragInitMode == ON_LONG_PRESS) {
+ mDslv.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ startDrag(mHitPos, mCurrX - mItemX, mCurrY - mItemY);
+ }
+ }
+
+ // complete the OnGestureListener interface
+ @Override
+ public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+ return false;
+ }
+
+ // complete the OnGestureListener interface
+ @Override
+ public boolean onSingleTapUp(MotionEvent ev) {
+ if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
+ if (mClickRemoveHitPos != MISS) {
+ mDslv.removeItem(mClickRemoveHitPos - mDslv.getHeaderViewsCount());
+ }
+ }
+ return true;
+ }
+
+ // complete the OnGestureListener interface
+ @Override
+ public void onShowPress(MotionEvent ev) {
+ // do nothing
+ }
+
+ private GestureDetector.OnGestureListener mFlingRemoveListener =
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
+ float velocityY) {
+ // Log.d("mobeta", "on fling remove called");
+ if (mRemoveEnabled && mIsRemoving) {
+ int w = mDslv.getWidth();
+ int minPos = w / 5;
+ if (velocityX > mFlingSpeed) {
+ if (mPositionX > -minPos) {
+ mDslv.stopDragWithVelocity(true, velocityX);
+ }
+ } else if (velocityX < -mFlingSpeed) {
+ if (mPositionX < minPos) {
+ mDslv.stopDragWithVelocity(true, velocityX);
+ }
+ }
+ mIsRemoving = false;
+ }
+ return false;
+ }
+ };
+
+}
diff --git a/src/com/mobeta/android/dslv/DragSortCursorAdapter.java b/src/com/mobeta/android/dslv/DragSortCursorAdapter.java
new file mode 100755
index 0000000..d5a0281
--- /dev/null
+++ b/src/com/mobeta/android/dslv/DragSortCursorAdapter.java
@@ -0,0 +1,242 @@
+package com.mobeta.android.dslv;
+
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.util.SparseIntArray;
+import android.view.View;
+import android.view.ViewGroup;
+import android.support.v4.widget.CursorAdapter;
+
+
+/**
+ * A subclass of {@link android.widget.CursorAdapter} that provides
+ * reordering of the elements in the Cursor based on completed
+ * drag-sort operations. The reordering is a simple mapping of
+ * list positions into Cursor positions (the Cursor is unchanged).
+ * To persist changes made by drag-sorts, one can retrieve the
+ * mapping with the {@link #getCursorPositions()} method, which
+ * returns the reordered list of Cursor positions.
+ *
+ * An instance of this class is passed
+ * to {@link DragSortListView#setAdapter(ListAdapter)} and, since
+ * this class implements the {@link DragSortListView.DragSortListener}
+ * interface, it is automatically set as the DragSortListener for
+ * the DragSortListView instance.
+ */
+public abstract class DragSortCursorAdapter extends CursorAdapter implements DragSortListView.DragSortListener {
+
+ public static final int REMOVED = -1;
+
+ /**
+ * Key is ListView position, value is Cursor position
+ */
+ private SparseIntArray mListMapping = new SparseIntArray();
+
+ private ArrayList<Integer> mRemovedCursorPositions = new ArrayList<Integer>();
+
+ @SuppressWarnings("deprecation")
+ public DragSortCursorAdapter(Context context, Cursor c) {
+ super(context, c);
+ }
+
+ public DragSortCursorAdapter(Context context, Cursor c, boolean autoRequery) {
+ super(context, c, autoRequery);
+ }
+
+ public DragSortCursorAdapter(Context context, Cursor c, int flags) {
+ super(context, c, flags);
+ }
+
+ /**
+ * Swaps Cursor and clears list-Cursor mapping.
+ *
+ * @see android.widget.CursorAdapter#swapCursor(android.database.Cursor)
+ */
+ @Override
+ public Cursor swapCursor(Cursor newCursor) {
+ Cursor old = super.swapCursor(newCursor);
+ resetMappings();
+ return old;
+ }
+
+ /**
+ * Changes Cursor and clears list-Cursor mapping.
+ *
+ * @see android.widget.CursorAdapter#changeCursor(android.database.Cursor)
+ */
+ @Override
+ public void changeCursor(Cursor cursor) {
+ super.changeCursor(cursor);
+ resetMappings();
+ }
+
+ /**
+ * Resets list-cursor mapping.
+ */
+ public void reset() {
+ resetMappings();
+ notifyDataSetChanged();
+ }
+
+ private void resetMappings() {
+ mListMapping.clear();
+ mRemovedCursorPositions.clear();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return super.getItem(mListMapping.get(position, position));
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return super.getItemId(mListMapping.get(position, position));
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ return super.getDropDownView(mListMapping.get(position, position), convertView, parent);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return super.getView(mListMapping.get(position, position), convertView, parent);
+ }
+
+ /**
+ * On drop, this updates the mapping between Cursor positions
+ * and ListView positions. The Cursor is unchanged. Retrieve
+ * the current mapping with {@link getCursorPositions()}.
+ *
+ * @see DragSortListView.DropListener#drop(int, int)
+ */
+ @Override
+ public void drop(int from, int to) {
+ if (from != to) {
+ int cursorFrom = mListMapping.get(from, from);
+
+ if (from > to) {
+ for (int i = from; i > to; --i) {
+ mListMapping.put(i, mListMapping.get(i - 1, i - 1));
+ }
+ } else {
+ for (int i = from; i < to; ++i) {
+ mListMapping.put(i, mListMapping.get(i + 1, i + 1));
+ }
+ }
+ mListMapping.put(to, cursorFrom);
+
+ cleanMapping();
+ notifyDataSetChanged();
+ }
+ }
+
+ /**
+ * On remove, this updates the mapping between Cursor positions
+ * and ListView positions. The Cursor is unchanged. Retrieve
+ * the current mapping with {@link getCursorPositions()}.
+ *
+ * @see DragSortListView.RemoveListener#remove(int)
+ */
+ @Override
+ public void remove(int which) {
+ int cursorPos = mListMapping.get(which, which);
+ if (!mRemovedCursorPositions.contains(cursorPos)) {
+ mRemovedCursorPositions.add(cursorPos);
+ }
+
+ int newCount = getCount();
+ for (int i = which; i < newCount; ++i) {
+ mListMapping.put(i, mListMapping.get(i + 1, i + 1));
+ }
+
+ mListMapping.delete(newCount);
+
+ cleanMapping();
+ notifyDataSetChanged();
+ }
+
+ /**
+ * Does nothing. Just completes DragSortListener interface.
+ */
+ @Override
+ public void drag(int from, int to) {
+ // do nothing
+ }
+
+ /**
+ * Remove unnecessary mappings from sparse array.
+ */
+ private void cleanMapping() {
+ ArrayList<Integer> toRemove = new ArrayList<Integer>();
+
+ int size = mListMapping.size();
+ for (int i = 0; i < size; ++i) {
+ if (mListMapping.keyAt(i) == mListMapping.valueAt(i)) {
+ toRemove.add(mListMapping.keyAt(i));
+ }
+ }
+
+ size = toRemove.size();
+ for (int i = 0; i < size; ++i) {
+ mListMapping.delete(toRemove.get(i));
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return super.getCount() - mRemovedCursorPositions.size();
+ }
+
+ /**
+ * Get the Cursor position mapped to by the provided list position
+ * (given all previously handled drag-sort
+ * operations).
+ *
+ * @param position List position
+ *
+ * @return The mapped-to Cursor position
+ */
+ public int getCursorPosition(int position) {
+ return mListMapping.get(position, position);
+ }
+
+ /**
+ * Get the current order of Cursor positions presented by the
+ * list.
+ */
+ public ArrayList<Integer> getCursorPositions() {
+ ArrayList<Integer> result = new ArrayList<Integer>();
+
+ for (int i = 0; i < getCount(); ++i) {
+ result.add(mListMapping.get(i, i));
+ }
+
+ return result;
+ }
+
+ /**
+ * Get the list position mapped to by the provided Cursor position.
+ * If the provided Cursor position has been removed by a drag-sort,
+ * this returns {@link #REMOVED}.
+ *
+ * @param cursorPosition A Cursor position
+ * @return The mapped-to list position or REMOVED
+ */
+ public int getListPosition(int cursorPosition) {
+ if (mRemovedCursorPositions.contains(cursorPosition)) {
+ return REMOVED;
+ }
+
+ int index = mListMapping.indexOfValue(cursorPosition);
+ if (index < 0) {
+ return cursorPosition;
+ } else {
+ return mListMapping.keyAt(index);
+ }
+ }
+
+
+}
diff --git a/src/com/mobeta/android/dslv/DragSortItemView.java b/src/com/mobeta/android/dslv/DragSortItemView.java
new file mode 100755
index 0000000..2ad2d02
--- /dev/null
+++ b/src/com/mobeta/android/dslv/DragSortItemView.java
@@ -0,0 +1,99 @@
+package com.mobeta.android.dslv;
+
+import android.content.Context;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+
+/**
+ * Lightweight ViewGroup that wraps list items obtained from user's
+ * ListAdapter. ItemView expects a single child that has a definite
+ * height (i.e. the child's layout height is not MATCH_PARENT).
+ * The width of
+ * ItemView will always match the width of its child (that is,
+ * the width MeasureSpec given to ItemView is passed directly
+ * to the child, and the ItemView measured width is set to the
+ * child's measured width). The height of ItemView can be anything;
+ * the
+ *
+ *
+ * The purpose of this class is to optimize slide
+ * shuffle animations.
+ */
+public class DragSortItemView extends ViewGroup {
+
+ private int mGravity = Gravity.TOP;
+
+ @SuppressWarnings("deprecation")
+ public DragSortItemView(Context context) {
+ super(context);
+
+ // always init with standard ListView layout params
+ setLayoutParams(new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+
+ //setClipChildren(true);
+ }
+
+ public void setGravity(int gravity) {
+ mGravity = gravity;
+ }
+
+ public int getGravity() {
+ return mGravity;
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ final View child = getChildAt(0);
+
+ if (child == null) {
+ return;
+ }
+
+ if (mGravity == Gravity.TOP) {
+ child.layout(0, 0, getMeasuredWidth(), child.getMeasuredHeight());
+ } else {
+ child.layout(0, getMeasuredHeight() - child.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
+ }
+ }
+
+ /**
+ *
+ */
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+
+ int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+
+ final View child = getChildAt(0);
+ if (child == null) {
+ setMeasuredDimension(0, width);
+ return;
+ }
+
+ if (child.isLayoutRequested()) {
+ // Always let child be as tall as it wants.
+ measureChild(child, widthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ }
+
+ if (heightMode == MeasureSpec.UNSPECIFIED) {
+ ViewGroup.LayoutParams lp = getLayoutParams();
+
+ if (lp.height > 0) {
+ height = lp.height;
+ } else {
+ height = child.getMeasuredHeight();
+ }
+ }
+
+ setMeasuredDimension(width, height);
+ }
+
+}
diff --git a/src/com/mobeta/android/dslv/DragSortItemViewCheckable.java b/src/com/mobeta/android/dslv/DragSortItemViewCheckable.java
new file mode 100755
index 0000000..2f58b66
--- /dev/null
+++ b/src/com/mobeta/android/dslv/DragSortItemViewCheckable.java
@@ -0,0 +1,50 @@
+package com.mobeta.android.dslv;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.Checkable;
+
+/**
+ * Lightweight ViewGroup that wraps list items obtained from user's
+ * ListAdapter. ItemView expects a single child that has a definite
+ * height (i.e. the child's layout height is not MATCH_PARENT).
+ * The width of
+ * ItemView will always match the width of its child (that is,
+ * the width MeasureSpec given to ItemView is passed directly
+ * to the child, and the ItemView measured width is set to the
+ * child's measured width). The height of ItemView can be anything;
+ * the
+ *
+ *
+ * The purpose of this class is to optimize slide
+ * shuffle animations.
+ */
+public class DragSortItemViewCheckable extends DragSortItemView implements Checkable {
+
+ public DragSortItemViewCheckable(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean isChecked() {
+ View child = getChildAt(0);
+ if (child instanceof Checkable)
+ return ((Checkable) child).isChecked();
+ else
+ return false;
+ }
+
+ @Override
+ public void setChecked(boolean checked) {
+ View child = getChildAt(0);
+ if (child instanceof Checkable)
+ ((Checkable) child).setChecked(checked);
+ }
+
+ @Override
+ public void toggle() {
+ View child = getChildAt(0);
+ if (child instanceof Checkable)
+ ((Checkable) child).toggle();
+ }
+}
diff --git a/src/com/mobeta/android/dslv/DragSortListView.java b/src/com/mobeta/android/dslv/DragSortListView.java
new file mode 100755
index 0000000..4859a76
--- /dev/null
+++ b/src/com/mobeta/android/dslv/DragSortListView.java
@@ -0,0 +1,3075 @@
+/*
+ * DragSortListView.
+ *
+ * A subclass of the Android ListView component that enables drag
+ * and drop re-ordering of list items.
+ *
+ * Copyright 2012 Carl Bauer
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.mobeta.android.dslv;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.graphics.drawable.Drawable;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.BaseAdapter;
+import android.widget.Checkable;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import com.dsht.kerneltweaker.R;
+
+/**
+ * ListView subclass that mediates drag and drop resorting of items.
+ *
+ *
+ * @author heycosmo
+ *
+ */
+public class DragSortListView extends ListView {
+
+
+ /**
+ * The View that floats above the ListView and represents
+ * the dragged item.
+ */
+ private View mFloatView;
+
+ /**
+ * The float View location. First based on touch location
+ * and given deltaX and deltaY. Then restricted by callback
+ * to FloatViewManager.onDragFloatView(). Finally restricted
+ * by bounds of DSLV.
+ */
+ private Point mFloatLoc = new Point();
+
+ private Point mTouchLoc = new Point();
+
+ /**
+ * The middle (in the y-direction) of the floating View.
+ */
+ private int mFloatViewMid;
+
+ /**
+ * Flag to make sure float View isn't measured twice
+ */
+ private boolean mFloatViewOnMeasured = false;
+
+ /**
+ * Watch the Adapter for data changes. Cancel a drag if
+ * coincident with a change.
+ */
+ private DataSetObserver mObserver;
+
+ /**
+ * Transparency for the floating View (XML attribute).
+ */
+ private float mFloatAlpha = 1.0f;
+ private float mCurrFloatAlpha = 1.0f;
+
+ /**
+ * While drag-sorting, the current position of the floating
+ * View. If dropped, the dragged item will land in this position.
+ */
+ private int mFloatPos;
+
+ /**
+ * The first expanded ListView position that helps represent
+ * the drop slot tracking the floating View.
+ */
+ private int mFirstExpPos;
+
+ /**
+ * The second expanded ListView position that helps represent
+ * the drop slot tracking the floating View. This can equal
+ * mFirstExpPos if there is no slide shuffle occurring; otherwise
+ * it is equal to mFirstExpPos + 1.
+ */
+ private int mSecondExpPos;
+
+ /**
+ * Flag set if slide shuffling is enabled.
+ */
+ private boolean mAnimate = false;
+
+ /**
+ * The user dragged from this position.
+ */
+ private int mSrcPos;
+
+ /**
+ * Offset (in x) within the dragged item at which the user
+ * picked it up (or first touched down with the digitalis).
+ */
+ private int mDragDeltaX;
+
+ /**
+ * Offset (in y) within the dragged item at which the user
+ * picked it up (or first touched down with the digitalis).
+ */
+ private int mDragDeltaY;
+
+
+ /**
+ * The difference (in x) between screen coordinates and coordinates
+ * in this view.
+ */
+ private int mOffsetX;
+
+ /**
+ * The difference (in y) between screen coordinates and coordinates
+ * in this view.
+ */
+ private int mOffsetY;
+
+ /**
+ * A listener that receives callbacks whenever the floating View
+ * hovers over a new position.
+ */
+ private DragListener mDragListener;
+
+ /**
+ * A listener that receives a callback when the floating View
+ * is dropped.
+ */
+ private DropListener mDropListener;
+
+ /**
+ * A listener that receives a callback when the floating View
+ * (or more precisely the originally dragged item) is removed
+ * by one of the provided gestures.
+ */
+ private RemoveListener mRemoveListener;
+
+ /**
+ * Enable/Disable item dragging
+ *
+ * @attr name dslv:drag_enabled
+ */
+ private boolean mDragEnabled = true;
+
+ /**
+ * Drag state enum.
+ */
+ private final static int IDLE = 0;
+ private final static int REMOVING = 1;
+ private final static int DROPPING = 2;
+ private final static int STOPPED = 3;
+ private final static int DRAGGING = 4;
+
+ private int mDragState = IDLE;
+
+ /**
+ * Height in pixels to which the originally dragged item
+ * is collapsed during a drag-sort. Currently, this value
+ * must be greater than zero.
+ */
+ private int mItemHeightCollapsed = 1;
+
+ /**
+ * Height of the floating View. Stored for the purpose of
+ * providing the tracking drop slot.
+ */
+ private int mFloatViewHeight;
+
+ /**
+ * Convenience member. See above.
+ */
+ private int mFloatViewHeightHalf;
+
+ /**
+ * Save the given width spec for use in measuring children
+ */
+ private int mWidthMeasureSpec = 0;
+
+ /**
+ * Sample Views ultimately used for calculating the height
+ * of ListView items that are off-screen.
+ */
+ private View[] mSampleViewTypes = new View[1];
+
+ /**
+ * Drag-scroll encapsulator!
+ */
+ private DragScroller mDragScroller;
+
+ /**
+ * Determines the start of the upward drag-scroll region
+ * at the top of the ListView. Specified by a fraction
+ * of the ListView height, thus screen resolution agnostic.
+ */
+ private float mDragUpScrollStartFrac = 1.0f / 3.0f;
+
+ /**
+ * Determines the start of the downward drag-scroll region
+ * at the bottom of the ListView. Specified by a fraction
+ * of the ListView height, thus screen resolution agnostic.
+ */
+ private float mDragDownScrollStartFrac = 1.0f / 3.0f;
+
+ /**
+ * The following are calculated from the above fracs.
+ */
+ private int mUpScrollStartY;
+ private int mDownScrollStartY;
+ private float mDownScrollStartYF;
+ private float mUpScrollStartYF;
+
+ /**
+ * Calculated from above above and current ListView height.
+ */
+ private float mDragUpScrollHeight;
+
+ /**
+ * Calculated from above above and current ListView height.
+ */
+ private float mDragDownScrollHeight;
+
+ /**
+ * Maximum drag-scroll speed in pixels per ms. Only used with
+ * default linear drag-scroll profile.
+ */
+ private float mMaxScrollSpeed = 0.5f;
+
+ /**
+ * Defines the scroll speed during a drag-scroll. User can
+ * provide their own; this default is a simple linear profile
+ * where scroll speed increases linearly as the floating View
+ * nears the top/bottom of the ListView.
+ */
+ private DragScrollProfile mScrollProfile = new DragScrollProfile() {
+ @Override
+ public float getSpeed(float w, long t) {
+ return mMaxScrollSpeed * w;
+ }
+ };
+
+ /**
+ * Current touch x.
+ */
+ private int mX;
+
+ /**
+ * Current touch y.
+ */
+ private int mY;
+
+ /**
+ * Last touch x.
+ */
+ private int mLastX;
+
+ /**
+ * Last touch y.
+ */
+ private int mLastY;
+
+ /**
+ * The touch y-coord at which drag started
+ */
+ private int mDragStartY;
+
+ /**
+ * Drag flag bit. Floating View can move in the positive
+ * x direction.
+ */
+ public final static int DRAG_POS_X = 0x1;
+
+ /**
+ * Drag flag bit. Floating View can move in the negative
+ * x direction.
+ */
+ public final static int DRAG_NEG_X = 0x2;
+
+ /**
+ * Drag flag bit. Floating View can move in the positive
+ * y direction. This is subtle. What this actually means is
+ * that, if enabled, the floating View can be dragged below its starting
+ * position. Remove in favor of upper-bounding item position?
+ */
+ public final static int DRAG_POS_Y = 0x4;
+
+ /**
+ * Drag flag bit. Floating View can move in the negative
+ * y direction. This is subtle. What this actually means is
+ * that the floating View can be dragged above its starting
+ * position. Remove in favor of lower-bounding item position?
+ */
+ public final static int DRAG_NEG_Y = 0x8;
+
+ /**
+ * Flags that determine limits on the motion of the
+ * floating View. See flags above.
+ */
+ private int mDragFlags = 0;
+
+ /**
+ * Last call to an on*TouchEvent was a call to
+ * onInterceptTouchEvent.
+ */
+ private boolean mLastCallWasIntercept = false;
+
+ /**
+ * A touch event is in progress.
+ */
+ private boolean mInTouchEvent = false;
+
+ /**
+ * Let the user customize the floating View.
+ */
+ private FloatViewManager mFloatViewManager = null;
+
+ /**
+ * Given to ListView to cancel its action when a drag-sort
+ * begins.
+ */
+ private MotionEvent mCancelEvent;
+
+ /**
+ * Enum telling where to cancel the ListView action when a
+ * drag-sort begins
+ */
+ private static final int NO_CANCEL = 0;
+ private static final int ON_TOUCH_EVENT = 1;
+ private static final int ON_INTERCEPT_TOUCH_EVENT = 2;
+
+ /**
+ * Where to cancel the ListView action when a
+ * drag-sort begins
+ */
+ private int mCancelMethod = NO_CANCEL;
+
+ /**
+ * Determines when a slide shuffle animation starts. That is,
+ * defines how close to the edge of the drop slot the floating
+ * View must be to initiate the slide.
+ */
+ private float mSlideRegionFrac = 0.25f;
+
+ /**
+ * Number between 0 and 1 indicating the relative location of
+ * a sliding item (only used if drag-sort animations
+ * are turned on). Nearly 1 means the item is
+ * at the top of the slide region (nearly full blank item
+ * is directly below).
+ */
+ private float mSlideFrac = 0.0f;
+
+ /**
+ * Wraps the user-provided ListAdapter. This is used to wrap each
+ * item View given by the user inside another View (currenly
+ * a RelativeLayout) which
+ * expands and collapses to simulate the item shuffling.
+ */
+ private AdapterWrapper mAdapterWrapper;
+
+ /**
+ * Turn on custom debugger.
+ */
+ private boolean mTrackDragSort = false;
+
+ /**
+ * Debugging class.
+ */
+ private DragSortTracker mDragSortTracker;
+
+ /**
+ * Needed for adjusting item heights from within layoutChildren
+ */
+ private boolean mBlockLayoutRequests = false;
+
+ /**
+ * Set to true when a down event happens during drag sort;
+ * for example, when drag finish animations are
+ * playing.
+ */
+ private boolean mIgnoreTouchEvent = false;
+
+ /**
+ * Caches DragSortItemView child heights. Sometimes DSLV has to
+ * know the height of an offscreen item. Since ListView virtualizes
+ * these, DSLV must get the item from the ListAdapter to obtain
+ * its height. That process can be expensive, but often the same
+ * offscreen item will be requested many times in a row. Once an
+ * offscreen item height is calculated, we cache it in this guy.
+ * Actually, we cache the height of the child of the
+ * DragSortItemView since the item height changes often during a
+ * drag-sort.
+ */
+ private static final int sCacheSize = 3;
+ private HeightCache mChildHeightCache = new HeightCache(sCacheSize);
+
+ private RemoveAnimator mRemoveAnimator;
+
+ private LiftAnimator mLiftAnimator;
+
+ private DropAnimator mDropAnimator;
+
+ private boolean mUseRemoveVelocity;
+ private float mRemoveVelocityX = 0;
+
+ public DragSortListView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ int defaultDuration = 150;
+ int removeAnimDuration = defaultDuration; // ms
+ int dropAnimDuration = defaultDuration; // ms
+
+ if (attrs != null) {
+ TypedArray a = getContext().obtainStyledAttributes(attrs,
+ R.styleable.DragSortListView, 0, 0);
+
+ mItemHeightCollapsed = Math.max(1, a.getDimensionPixelSize(
+ R.styleable.DragSortListView_collapsed_height, 1));
+
+ mTrackDragSort = a.getBoolean(
+ R.styleable.DragSortListView_track_drag_sort, false);
+
+ if (mTrackDragSort) {
+ mDragSortTracker = new DragSortTracker();
+ }
+
+ // alpha between 0 and 255, 0=transparent, 255=opaque
+ mFloatAlpha = a.getFloat(R.styleable.DragSortListView_float_alpha, mFloatAlpha);
+ mCurrFloatAlpha = mFloatAlpha;
+
+ mDragEnabled = a.getBoolean(R.styleable.DragSortListView_drag_enabled, mDragEnabled);
+
+ mSlideRegionFrac = Math.max(0.0f,
+ Math.min(1.0f, 1.0f - a.getFloat(
+ R.styleable.DragSortListView_slide_shuffle_speed,
+ 0.75f)));
+
+ mAnimate = mSlideRegionFrac > 0.0f;
+
+ float frac = a.getFloat(
+ R.styleable.DragSortListView_drag_scroll_start,
+ mDragUpScrollStartFrac);
+
+ setDragScrollStart(frac);
+
+ mMaxScrollSpeed = a.getFloat(
+ R.styleable.DragSortListView_max_drag_scroll_speed,
+ mMaxScrollSpeed);
+
+ removeAnimDuration = a.getInt(
+ R.styleable.DragSortListView_remove_animation_duration,
+ removeAnimDuration);
+
+ dropAnimDuration = a.getInt(
+ R.styleable.DragSortListView_drop_animation_duration,
+ dropAnimDuration);
+
+ boolean useDefault = a.getBoolean(
+ R.styleable.DragSortListView_use_default_controller,
+ true);
+
+ if (useDefault) {
+ boolean removeEnabled = a.getBoolean(
+ R.styleable.DragSortListView_remove_enabled,
+ false);
+ int removeMode = a.getInt(
+ R.styleable.DragSortListView_remove_mode,
+ DragSortController.FLING_REMOVE);
+ boolean sortEnabled = a.getBoolean(
+ R.styleable.DragSortListView_sort_enabled,
+ true);
+ int dragInitMode = a.getInt(
+ R.styleable.DragSortListView_drag_start_mode,
+ DragSortController.ON_DOWN);
+ int dragHandleId = a.getResourceId(
+ R.styleable.DragSortListView_drag_handle_id,
+ 0);
+ int flingHandleId = a.getResourceId(
+ R.styleable.DragSortListView_fling_handle_id,
+ 0);
+ int clickRemoveId = a.getResourceId(
+ R.styleable.DragSortListView_click_remove_id,
+ 0);
+ int bgColor = a.getColor(
+ R.styleable.DragSortListView_float_background_color,
+ Color.BLACK);
+
+ DragSortController controller = new DragSortController(
+ this, dragHandleId, dragInitMode, removeMode,
+ clickRemoveId, flingHandleId);
+ controller.setRemoveEnabled(removeEnabled);
+ controller.setSortEnabled(sortEnabled);
+ controller.setBackgroundColor(bgColor);
+
+ mFloatViewManager = controller;
+ setOnTouchListener(controller);
+ }
+
+ a.recycle();
+ }
+
+ mDragScroller = new DragScroller();
+
+ float smoothness = 0.5f;
+ if (removeAnimDuration > 0) {
+ mRemoveAnimator = new RemoveAnimator(smoothness, removeAnimDuration);
+ }
+ // mLiftAnimator = new LiftAnimator(smoothness, 100);
+ if (dropAnimDuration > 0) {
+ mDropAnimator = new DropAnimator(smoothness, dropAnimDuration);
+ }
+
+ mCancelEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0f, 0f, 0f, 0f, 0, 0f,
+ 0f, 0, 0);
+
+ // construct the dataset observer
+ mObserver = new DataSetObserver() {
+ private void cancel() {
+ if (mDragState == DRAGGING) {
+ cancelDrag();
+ }
+ }
+
+ @Override
+ public void onChanged() {
+ cancel();
+ }
+
+ @Override
+ public void onInvalidated() {
+ cancel();
+ }
+ };
+ }
+
+ /**
+ * Usually called from a FloatViewManager. The float alpha
+ * will be reset to the xml-defined value every time a drag
+ * is stopped.
+ */
+ public void setFloatAlpha(float alpha) {
+ mCurrFloatAlpha = alpha;
+ }
+
+ public float getFloatAlpha() {
+ return mCurrFloatAlpha;
+ }
+
+ /**
+ * Set maximum drag scroll speed in positions/second. Only applies
+ * if using default ScrollSpeedProfile.
+ *
+ * @param max Maximum scroll speed.
+ */
+ public void setMaxScrollSpeed(float max) {
+ mMaxScrollSpeed = max;
+ }
+
+ /**
+ * For each DragSortListView Listener interface implemented by
+ * <code>adapter</code>, this method calls the appropriate
+ * set*Listener method with <code>adapter</code> as the argument.
+ *
+ * @param adapter The ListAdapter providing data to back
+ * DragSortListView.
+ *
+ * @see android.widget.ListView#setAdapter(android.widget.ListAdapter)
+ */
+ @Override
+ public void setAdapter(ListAdapter adapter) {
+ if (adapter != null) {
+ mAdapterWrapper = new AdapterWrapper(adapter);
+ adapter.registerDataSetObserver(mObserver);
+
+ if (adapter instanceof DropListener) {
+ setDropListener((DropListener) adapter);
+ }
+ if (adapter instanceof DragListener) {
+ setDragListener((DragListener) adapter);
+ }
+ if (adapter instanceof RemoveListener) {
+ setRemoveListener((RemoveListener) adapter);
+ }
+ } else {
+ mAdapterWrapper = null;
+ }
+
+ super.setAdapter(mAdapterWrapper);
+ }
+
+ /**
+ * As opposed to {@link ListView#getAdapter()}, which returns
+ * a heavily wrapped ListAdapter (DragSortListView wraps the
+ * input ListAdapter {\emph and} ListView wraps the wrapped one).
+ *
+ * @return The ListAdapter set as the argument of {@link setAdapter()}
+ */
+ public ListAdapter getInputAdapter() {
+ if (mAdapterWrapper == null) {
+ return null;
+ } else {
+ return mAdapterWrapper.getAdapter();
+ }
+ }
+
+ private class AdapterWrapper extends BaseAdapter {
+ private ListAdapter mAdapter;
+
+ public AdapterWrapper(ListAdapter adapter) {
+ super();
+ mAdapter = adapter;
+
+ mAdapter.registerDataSetObserver(new DataSetObserver() {
+ public void onChanged() {
+ notifyDataSetChanged();
+ }
+
+ public void onInvalidated() {
+ notifyDataSetInvalidated();
+ }
+ });
+ }
+
+ public ListAdapter getAdapter() {
+ return mAdapter;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return mAdapter.getItemId(position);
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mAdapter.getItem(position);
+ }
+
+ @Override
+ public int getCount() {
+ return mAdapter.getCount();
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return mAdapter.areAllItemsEnabled();
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return mAdapter.isEnabled(position);
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return mAdapter.getItemViewType(position);
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return mAdapter.getViewTypeCount();
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return mAdapter.hasStableIds();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return mAdapter.isEmpty();
+ }
+
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+
+ DragSortItemView v;
+ View child;
+ // Log.d("mobeta",
+ // "getView: position="+position+" convertView="+convertView);
+ if (convertView != null) {
+ v = (DragSortItemView) convertView;
+ View oldChild = v.getChildAt(0);
+
+ child = mAdapter.getView(position, oldChild, DragSortListView.this);
+ if (child != oldChild) {
+ // shouldn't get here if user is reusing convertViews
+ // properly
+ if (oldChild != null) {
+ v.removeViewAt(0);
+ }
+ v.addView(child);
+ }
+ } else {
+ child = mAdapter.getView(position, null, DragSortListView.this);
+ if (child instanceof Checkable) {
+ v = new DragSortItemViewCheckable(getContext());
+ } else {
+ v = new DragSortItemView(getContext());
+ }
+ v.setLayoutParams(new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ v.addView(child);
+ }
+
+ // Set the correct item height given drag state; passed
+ // View needs to be measured if measurement is required.
+ adjustItem(position + getHeaderViewsCount(), v, true);
+
+ return v;
+ }
+ }
+
+ private void drawDivider(int expPosition, Canvas canvas) {
+
+ final Drawable divider = getDivider();
+ final int dividerHeight = getDividerHeight();
+ // Log.d("mobeta", "div="+divider+" divH="+dividerHeight);
+
+ if (divider != null && dividerHeight != 0) {
+ final ViewGroup expItem = (ViewGroup) getChildAt(expPosition
+ - getFirstVisiblePosition());
+ if (expItem != null) {
+ final int l = getPaddingLeft();
+ final int r = getWidth() - getPaddingRight();
+ final int t;
+ final int b;
+
+ final int childHeight = expItem.getChildAt(0).getHeight();
+
+ if (expPosition > mSrcPos) {
+ t = expItem.getTop() + childHeight;
+ b = t + dividerHeight;
+ } else {
+ b = expItem.getBottom() - childHeight;
+ t = b - dividerHeight;
+ }
+ // Log.d("mobeta", "l="+l+" t="+t+" r="+r+" b="+b);
+
+ // Have to clip to support ColorDrawable on <= Gingerbread
+ canvas.save();
+ canvas.clipRect(l, t, r, b);
+ divider.setBounds(l, t, r, b);
+ divider.draw(canvas);
+ canvas.restore();
+ }
+ }
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+
+ if (mDragState != IDLE) {
+ // draw the divider over the expanded item
+ if (mFirstExpPos != mSrcPos) {
+ drawDivider(mFirstExpPos, canvas);
+ }
+ if (mSecondExpPos != mFirstExpPos && mSecondExpPos != mSrcPos) {
+ drawDivider(mSecondExpPos, canvas);
+ }
+ }
+
+ if (mFloatView != null) {
+ // draw the float view over everything
+ final int w = mFloatView.getWidth();
+ final int h = mFloatView.getHeight();
+
+ int x = mFloatLoc.x;
+
+ int width = getWidth();
+ if (x < 0)
+ x = -x;
+ float alphaMod;
+ if (x < width) {
+ alphaMod = ((float) (width - x)) / ((float) width);
+ alphaMod *= alphaMod;
+ } else {
+ alphaMod = 0;
+ }
+
+ final int alpha = (int) (255f * mCurrFloatAlpha * alphaMod);
+
+ canvas.save();
+ // Log.d("mobeta", "clip rect bounds: " + canvas.getClipBounds());
+ canvas.translate(mFloatLoc.x, mFloatLoc.y);
+ canvas.clipRect(0, 0, w, h);
+
+ // Log.d("mobeta", "clip rect bounds: " + canvas.getClipBounds());
+ canvas.saveLayerAlpha(0, 0, w, h, alpha, Canvas.ALL_SAVE_FLAG);
+ mFloatView.draw(canvas);
+ canvas.restore();
+ canvas.restore();
+ }
+ }
+
+ private int getItemHeight(int position) {
+ View v = getChildAt(position - getFirstVisiblePosition());
+
+ if (v != null) {
+ // item is onscreen, just get the height of the View
+ return v.getHeight();
+ } else {
+ // item is offscreen. get child height and calculate
+ // item height based on current shuffle state
+ return calcItemHeight(position, getChildHeight(position));
+ }
+ }
+
+ private void printPosData() {
+ Log.d("mobeta", "mSrcPos=" + mSrcPos + " mFirstExpPos=" + mFirstExpPos + " mSecondExpPos="
+ + mSecondExpPos);
+ }
+
+ private class HeightCache {
+
+ private SparseIntArray mMap;
+ private ArrayList<Integer> mOrder;
+ private int mMaxSize;
+
+ public HeightCache(int size) {
+ mMap = new SparseIntArray(size);
+ mOrder = new ArrayList<Integer>(size);
+ mMaxSize = size;
+ }
+
+ /**
+ * Add item height at position if doesn't already exist.
+ */
+ public void add(int position, int height) {
+ int currHeight = mMap.get(position, -1);
+ if (currHeight != height) {
+ if (currHeight == -1) {
+ if (mMap.size() == mMaxSize) {
+ // remove oldest entry
+ mMap.delete(mOrder.remove(0));
+ }
+ } else {
+ // move position to newest slot
+ mOrder.remove((Integer) position);
+ }
+ mMap.put(position, height);
+ mOrder.add(position);
+ }
+ }
+
+ public int get(int position) {
+ return mMap.get(position, -1);
+ }
+
+ public void clear() {
+ mMap.clear();
+ mOrder.clear();
+ }
+
+ }
+
+ /**
+ * Get the shuffle edge for item at position when top of
+ * item is at y-coord top. Assumes that current item heights
+ * are consistent with current float view location and
+ * thus expanded positions and slide fraction. i.e. Should not be
+ * called between update of expanded positions/slide fraction
+ * and layoutChildren.
+ *
+ * @param position
+ * @param top
+ * @param height Height of item at position. If -1, this function
+ * calculates this height.
+ *
+ * @return Shuffle line between position-1 and position (for
+ * the given view of the list; that is, for when top of item at
+ * position has y-coord of given `top`). If
+ * floating View (treated as horizontal line) is dropped
+ * immediately above this line, it lands in position-1. If
+ * dropped immediately below this line, it lands in position.
+ */
+ private int getShuffleEdge(int position, int top) {
+
+ final int numHeaders = getHeaderViewsCount();
+ final int numFooters = getFooterViewsCount();
+
+ // shuffle edges are defined between items that can be
+ // dragged; there are N-1 of them if there are N draggable
+ // items.
+
+ if (position <= numHeaders || (position >= getCount() - numFooters)) {
+ return top;
+ }
+
+ int divHeight = getDividerHeight();
+
+ int edge;
+
+ int maxBlankHeight = mFloatViewHeight - mItemHeightCollapsed;
+ int childHeight = getChildHeight(position);
+ int itemHeight = getItemHeight(position);
+
+ // first calculate top of item given that floating View is
+ // centered over src position
+ int otop = top;
+ if (mSecondExpPos <= mSrcPos) {
+ // items are expanded on and/or above the source position
+
+ if (position == mSecondExpPos && mFirstExpPos != mSecondExpPos) {
+ if (position == mSrcPos) {
+ otop = top + itemHeight - mFloatViewHeight;
+ } else {
+ int blankHeight = itemHeight - childHeight;
+ otop = top + blankHeight - maxBlankHeight;
+ }
+ } else if (position > mSecondExpPos && position <= mSrcPos) {
+ otop = top - maxBlankHeight;
+ }
+
+ } else {
+ // items are expanded on and/or below the source position
+
+ if (position > mSrcPos && position <= mFirstExpPos) {
+ otop = top + maxBlankHeight;
+ } else if (position == mSecondExpPos && mFirstExpPos != mSecondExpPos) {
+ int blankHeight = itemHeight - childHeight;
+ otop = top + blankHeight;
+ }
+ }
+
+ // otop is set
+ if (position <= mSrcPos) {
+ edge = otop + (mFloatViewHeight - divHeight - getChildHeight(position - 1)) / 2;
+ } else {
+ edge = otop + (childHeight - divHeight - mFloatViewHeight) / 2;
+ }
+
+ return edge;
+ }
+
+ private boolean updatePositions() {
+
+ final int first = getFirstVisiblePosition();
+ int startPos = mFirstExpPos;
+ View startView = getChildAt(startPos - first);
+
+ if (startView == null) {
+ startPos = first + getChildCount() / 2;
+ startView = getChildAt(startPos - first);
+ }
+ int startTop = startView.getTop();
+
+ int itemHeight = startView.getHeight();
+
+ int edge = getShuffleEdge(startPos, startTop);
+ int lastEdge = edge;
+
+ int divHeight = getDividerHeight();
+
+ // Log.d("mobeta", "float mid="+mFloatViewMid);
+
+ int itemPos = startPos;
+ int itemTop = startTop;
+ if (mFloatViewMid < edge) {
+ // scanning up for float position
+ // Log.d("mobeta", " edge="+edge);
+ while (itemPos >= 0) {
+ itemPos--;
+ itemHeight = getItemHeight(itemPos);
+
+ if (itemPos == 0) {
+ edge = itemTop - divHeight - itemHeight;
+ break;
+ }
+
+ itemTop -= itemHeight + divHeight;
+ edge = getShuffleEdge(itemPos, itemTop);
+ // Log.d("mobeta", " edge="+edge);
+
+ if (mFloatViewMid >= edge) {
+ break;
+ }
+
+ lastEdge = edge;
+ }
+ } else {
+ // scanning down for float position
+ // Log.d("mobeta", " edge="+edge);
+ final int count = getCount();
+ while (itemPos < count) {
+ if (itemPos == count - 1) {
+ edge = itemTop + divHeight + itemHeight;
+ break;
+ }
+
+ itemTop += divHeight + itemHeight;
+ itemHeight = getItemHeight(itemPos + 1);
+ edge = getShuffleEdge(itemPos + 1, itemTop);
+ // Log.d("mobeta", " edge="+edge);
+
+ // test for hit
+ if (mFloatViewMid < edge) {
+ break;
+ }
+
+ lastEdge = edge;
+ itemPos++;
+ }
+ }
+
+ final int numHeaders = getHeaderViewsCount();
+ final int numFooters = getFooterViewsCount();
+
+ boolean updated = false;
+
+ int oldFirstExpPos = mFirstExpPos;
+ int oldSecondExpPos = mSecondExpPos;
+ float oldSlideFrac = mSlideFrac;
+
+ if (mAnimate) {
+ int edgeToEdge = Math.abs(edge - lastEdge);
+
+ int edgeTop, edgeBottom;
+ if (mFloatViewMid < edge) {
+ edgeBottom = edge;
+ edgeTop = lastEdge;
+ } else {
+ edgeTop = edge;
+ edgeBottom = lastEdge;
+ }
+ // Log.d("mobeta", "edgeTop="+edgeTop+" edgeBot="+edgeBottom);
+
+ int slideRgnHeight = (int) (0.5f * mSlideRegionFrac * edgeToEdge);
+ float slideRgnHeightF = (float) slideRgnHeight;
+ int slideEdgeTop = edgeTop + slideRgnHeight;
+ int slideEdgeBottom = edgeBottom - slideRgnHeight;
+
+ // Three regions
+ if (mFloatViewMid < slideEdgeTop) {
+ mFirstExpPos = itemPos - 1;
+ mSecondExpPos = itemPos;
+ mSlideFrac = 0.5f * ((float) (slideEdgeTop - mFloatViewMid)) / slideRgnHeightF;
+ // Log.d("mobeta",
+ // "firstExp="+mFirstExpPos+" secExp="+mSecondExpPos+" slideFrac="+mSlideFrac);
+ } else if (mFloatViewMid < slideEdgeBottom) {
+ mFirstExpPos = itemPos;
+ mSecondExpPos = itemPos;
+ } else {
+ mFirstExpPos = itemPos;
+ mSecondExpPos = itemPos + 1;
+ mSlideFrac = 0.5f * (1.0f + ((float) (edgeBottom - mFloatViewMid))
+ / slideRgnHeightF);
+ // Log.d("mobeta",
+ // "firstExp="+mFirstExpPos+" secExp="+mSecondExpPos+" slideFrac="+mSlideFrac);
+ }
+
+ } else {
+ mFirstExpPos = itemPos;
+ mSecondExpPos = itemPos;
+ }
+
+ // correct for headers and footers
+ if (mFirstExpPos < numHeaders) {
+ itemPos = numHeaders;
+ mFirstExpPos = itemPos;
+ mSecondExpPos = itemPos;
+ } else if (mSecondExpPos >= getCount() - numFooters) {
+ itemPos = getCount() - numFooters - 1;
+ mFirstExpPos = itemPos;
+ mSecondExpPos = itemPos;
+ }
+
+ if (mFirstExpPos != oldFirstExpPos || mSecondExpPos != oldSecondExpPos
+ || mSlideFrac != oldSlideFrac) {
+ updated = true;
+ }
+
+ if (itemPos != mFloatPos) {
+ if (mDragListener != null) {
+ mDragListener.drag(mFloatPos - numHeaders, itemPos - numHeaders);
+ }
+
+ mFloatPos = itemPos;
+ updated = true;
+ }
+
+ return updated;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ if (mTrackDragSort) {
+ mDragSortTracker.appendState();
+ }
+ }
+
+ private class SmoothAnimator implements Runnable {
+ protected long mStartTime;
+
+ private float mDurationF;
+
+ private float mAlpha;
+ private float mA, mB, mC, mD;
+
+ private boolean mCanceled;
+
+ public SmoothAnimator(float smoothness, int duration) {
+ mAlpha = smoothness;
+ mDurationF = (float) duration;
+ mA = mD = 1f / (2f * mAlpha * (1f - mAlpha));
+ mB = mAlpha / (2f * (mAlpha - 1f));
+ mC = 1f / (1f - mAlpha);
+ }
+
+ public float transform(float frac) {
+ if (frac < mAlpha) {
+ return mA * frac * frac;
+ } else if (frac < 1f - mAlpha) {
+ return mB + mC * frac;
+ } else {
+ return 1f - mD * (frac - 1f) * (frac - 1f);
+ }
+ }
+
+ public void start() {
+ mStartTime = SystemClock.uptimeMillis();
+ mCanceled = false;
+ onStart();
+ post(this);
+ }
+
+ public void cancel() {
+ mCanceled = true;
+ }
+
+ public void onStart() {
+ // stub
+ }
+
+ public void onUpdate(float frac, float smoothFrac) {
+ // stub
+ }
+
+ public void onStop() {
+ // stub
+ }
+
+ @Override
+ public void run() {
+ if (mCanceled) {
+ return;
+ }
+
+ float fraction = ((float) (SystemClock.uptimeMillis() - mStartTime)) / mDurationF;
+
+ if (fraction >= 1f) {
+ onUpdate(1f, 1f);
+ onStop();
+ } else {
+ onUpdate(fraction, transform(fraction));
+ post(this);
+ }
+ }
+ }
+
+ /**
+ * Centers floating View under touch point.
+ */
+ private class LiftAnimator extends SmoothAnimator {
+
+ private float mInitDragDeltaY;
+ private float mFinalDragDeltaY;
+
+ public LiftAnimator(float smoothness, int duration) {
+ super(smoothness, duration);
+ }
+
+ @Override
+ public void onStart() {
+ mInitDragDeltaY = mDragDeltaY;
+ mFinalDragDeltaY = mFloatViewHeightHalf;
+ }
+
+ @Override
+ public void onUpdate(float frac, float smoothFrac) {
+ if (mDragState != DRAGGING) {
+ cancel();
+ } else {
+ mDragDeltaY = (int) (smoothFrac * mFinalDragDeltaY + (1f - smoothFrac)
+ * mInitDragDeltaY);
+ mFloatLoc.y = mY - mDragDeltaY;
+ doDragFloatView(true);
+ }
+ }
+ }
+
+ /**
+ * Centers floating View over drop slot before destroying.
+ */
+ private class DropAnimator extends SmoothAnimator {
+
+ private int mDropPos;
+ private int srcPos;
+ private float mInitDeltaY;
+ private float mInitDeltaX;
+
+ public DropAnimator(float smoothness, int duration) {
+ super(smoothness, duration);
+ }
+
+ @Override
+ public void onStart() {
+ mDropPos = mFloatPos;
+ srcPos = mSrcPos;
+ mDragState = DROPPING;
+ mInitDeltaY = mFloatLoc.y - getTargetY();
+ mInitDeltaX = mFloatLoc.x - getPaddingLeft();
+ }
+
+ private int getTargetY() {
+ final int first = getFirstVisiblePosition();
+ final int otherAdjust = (mItemHeightCollapsed + getDividerHeight()) / 2;
+ View v = getChildAt(mDropPos - first);
+ int targetY = -1;
+ if (v != null) {
+ if (mDropPos == srcPos) {
+ targetY = v.getTop();
+ } else if (mDropPos < srcPos) {
+ // expanded down
+ targetY = v.getTop() - otherAdjust;
+ } else {
+ // expanded up
+ targetY = v.getBottom() + otherAdjust - mFloatViewHeight;
+ }
+ } else {
+ // drop position is not on screen?? no animation
+ cancel();
+ }
+
+ return targetY;
+ }
+
+ @Override
+ public void onUpdate(float frac, float smoothFrac) {
+ final int targetY = getTargetY();
+ final int targetX = getPaddingLeft();
+ final float deltaY = mFloatLoc.y - targetY;
+ final float deltaX = mFloatLoc.x - targetX;
+ final float f = 1f - smoothFrac;
+ if (f < Math.abs(deltaY / mInitDeltaY) || f < Math.abs(deltaX / mInitDeltaX)) {
+ mFloatLoc.y = targetY + (int) (mInitDeltaY * f);
+ mFloatLoc.x = getPaddingLeft() + (int) (mInitDeltaX * f);
+ doDragFloatView(true);
+ }
+ }
+
+ @Override
+ public void onStop() {
+ dropFloatView();
+ }
+
+ }
+
+ /**
+ * Collapses expanded items.
+ */
+ private class RemoveAnimator extends SmoothAnimator {
+
+ private float mFloatLocX;
+ private float mFirstStartBlank;
+ private float mSecondStartBlank;
+
+ private int mFirstChildHeight = -1;
+ private int mSecondChildHeight = -1;
+
+ private int mFirstPos;
+ private int mSecondPos;
+ private int srcPos;
+
+ public RemoveAnimator(float smoothness, int duration) {
+ super(smoothness, duration);
+ }
+
+ @Override
+ public void onStart() {
+ mFirstChildHeight = -1;
+ mSecondChildHeight = -1;
+ mFirstPos = mFirstExpPos;
+ mSecondPos = mSecondExpPos;
+ srcPos = mSrcPos;
+ mDragState = REMOVING;
+
+ mFloatLocX = mFloatLoc.x;
+ if (mUseRemoveVelocity) {
+ float minVelocity = 2f * getWidth();
+ if (mRemoveVelocityX == 0) {
+ mRemoveVelocityX = (mFloatLocX < 0 ? -1 : 1) * minVelocity;
+ } else {
+ minVelocity *= 2;
+ if (mRemoveVelocityX < 0 && mRemoveVelocityX > -minVelocity)
+ mRemoveVelocityX = -minVelocity;
+ else if (mRemoveVelocityX > 0 && mRemoveVelocityX < minVelocity)
+ mRemoveVelocityX = minVelocity;
+ }
+ } else {
+ destroyFloatView();
+ }
+ }
+
+ @Override
+ public void onUpdate(float frac, float smoothFrac) {
+ float f = 1f - smoothFrac;
+
+ final int firstVis = getFirstVisiblePosition();
+ View item = getChildAt(mFirstPos - firstVis);
+ ViewGroup.LayoutParams lp;
+ int blank;
+
+ if (mUseRemoveVelocity) {
+ float dt = (float) (SystemClock.uptimeMillis() - mStartTime) / 1000;
+ if (dt == 0)
+ return;
+ float dx = mRemoveVelocityX * dt;
+ int w = getWidth();
+ mRemoveVelocityX += (mRemoveVelocityX > 0 ? 1 : -1) * dt * w;
+ mFloatLocX += dx;
+ mFloatLoc.x = (int) mFloatLocX;
+ if (mFloatLocX < w && mFloatLocX > -w) {
+ mStartTime = SystemClock.uptimeMillis();
+ doDragFloatView(true);
+ return;
+ }
+ }
+
+ if (item != null) {
+ if (mFirstChildHeight == -1) {
+ mFirstChildHeight = getChildHeight(mFirstPos, item, false);
+ mFirstStartBlank = (float) (item.getHeight() - mFirstChildHeight);
+ }
+ blank = Math.max((int) (f * mFirstStartBlank), 1);
+ lp = item.getLayoutParams();
+ lp.height = mFirstChildHeight + blank;
+ item.setLayoutParams(lp);
+ }
+ if (mSecondPos != mFirstPos) {
+ item = getChildAt(mSecondPos - firstVis);
+ if (item != null) {
+ if (mSecondChildHeight == -1) {
+ mSecondChildHeight = getChildHeight(mSecondPos, item, false);
+ mSecondStartBlank = (float) (item.getHeight() - mSecondChildHeight);
+ }
+ blank = Math.max((int) (f * mSecondStartBlank), 1);
+ lp = item.getLayoutParams();
+ lp.height = mSecondChildHeight + blank;
+ item.setLayoutParams(lp);
+ }
+ }
+ }
+
+ @Override
+ public void onStop() {
+ doRemoveItem();
+ }
+ }
+
+ public void removeItem(int which) {
+
+ mUseRemoveVelocity = false;
+ removeItem(which, 0);
+ }
+
+ /**
+ * Removes an item from the list and animates the removal.
+ *
+ * @param which Position to remove (NOTE: headers/footers ignored!
+ * this is a position in your input ListAdapter).
+ * @param velocityX
+ */
+ public void removeItem(int which, float velocityX) {
+ if (mDragState == IDLE || mDragState == DRAGGING) {
+
+ if (mDragState == IDLE) {
+ // called from outside drag-sort
+ mSrcPos = getHeaderViewsCount() + which;
+ mFirstExpPos = mSrcPos;
+ mSecondExpPos = mSrcPos;
+ mFloatPos = mSrcPos;
+ View v = getChildAt(mSrcPos - getFirstVisiblePosition());
+ if (v != null) {
+ v.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ mDragState = REMOVING;
+ mRemoveVelocityX = velocityX;
+
+ if (mInTouchEvent) {
+ switch (mCancelMethod) {
+ case ON_TOUCH_EVENT:
+ super.onTouchEvent(mCancelEvent);
+ break;
+ case ON_INTERCEPT_TOUCH_EVENT:
+ super.onInterceptTouchEvent(mCancelEvent);
+ break;
+ }
+ }
+
+ if (mRemoveAnimator != null) {
+ mRemoveAnimator.start();
+ } else {
+ doRemoveItem(which);
+ }
+ }
+ }
+
+ /**
+ * Move an item, bypassing the drag-sort process. Simply calls
+ * through to {@link DropListener#drop(int, int)}.
+ *
+ * @param from Position to move (NOTE: headers/footers ignored!
+ * this is a position in your input ListAdapter).
+ * @param to Target position (NOTE: headers/footers ignored!
+ * this is a position in your input ListAdapter).
+ */
+ public void moveItem(int from, int to) {
+ if (mDropListener != null) {
+ final int count = getInputAdapter().getCount();
+ if (from >= 0 && from < count && to >= 0 && to < count) {
+ mDropListener.drop(from, to);
+ }
+ }
+ }
+
+ /**
+ * Cancel a drag. Calls {@link #stopDrag(boolean, boolean)} with
+ * <code>true</code> as the first argument.
+ */
+ public void cancelDrag() {
+ if (mDragState == DRAGGING) {
+ mDragScroller.stopScrolling(true);
+ destroyFloatView();
+ clearPositions();
+ adjustAllItems();
+
+ if (mInTouchEvent) {
+ mDragState = STOPPED;
+ } else {
+ mDragState = IDLE;
+ }
+ }
+ }
+
+ private void clearPositions() {
+ mSrcPos = -1;
+ mFirstExpPos = -1;
+ mSecondExpPos = -1;
+ mFloatPos = -1;
+ }
+
+ private void dropFloatView() {
+ // must set to avoid cancelDrag being called from the
+ // DataSetObserver
+ mDragState = DROPPING;
+
+ if (mDropListener != null && mFloatPos >= 0 && mFloatPos < getCount()) {
+ final int numHeaders = getHeaderViewsCount();
+ mDropListener.drop(mSrcPos - numHeaders, mFloatPos - numHeaders);
+ }
+
+ destroyFloatView();
+
+ adjustOnReorder();
+ clearPositions();
+ adjustAllItems();
+
+ // now the drag is done
+ if (mInTouchEvent) {
+ mDragState = STOPPED;
+ } else {
+ mDragState = IDLE;
+ }
+ }
+
+ private void doRemoveItem() {
+ doRemoveItem(mSrcPos - getHeaderViewsCount());
+ }
+
+ /**
+ * Removes dragged item from the list. Calls RemoveListener.
+ */
+ private void doRemoveItem(int which) {
+ // must set to avoid cancelDrag being called from the
+ // DataSetObserver
+ mDragState = REMOVING;
+
+ // end it
+ if (mRemoveListener != null) {
+ mRemoveListener.remove(which);
+ }
+
+ destroyFloatView();
+
+ adjustOnReorder();
+ clearPositions();
+
+ // now the drag is done
+ if (mInTouchEvent) {
+ mDragState = STOPPED;
+ } else {
+ mDragState = IDLE;
+ }
+ }
+
+ private void adjustOnReorder() {
+ final int firstPos = getFirstVisiblePosition();
+ // Log.d("mobeta", "first="+firstPos+" src="+mSrcPos);
+ if (mSrcPos < firstPos) {
+ // collapsed src item is off screen;
+ // adjust the scroll after item heights have been fixed
+ View v = getChildAt(0);
+ int top = 0;
+ if (v != null) {
+ top = v.getTop();
+ }
+ // Log.d("mobeta", "top="+top+" fvh="+mFloatViewHeight);
+ setSelectionFromTop(firstPos - 1, top - getPaddingTop());
+ }
+ }
+
+ /**
+ * Stop a drag in progress. Pass <code>true</code> if you would
+ * like to remove the dragged item from the list.
+ *
+ * @param remove Remove the dragged item from the list. Calls
+ * a registered RemoveListener, if one exists. Otherwise, calls
+ * the DropListener, if one exists.
+ *
+ * @return True if the stop was successful. False if there is
+ * no floating View.
+ */
+ public boolean stopDrag(boolean remove) {
+ mUseRemoveVelocity = false;
+ return stopDrag(remove, 0);
+ }
+
+ public boolean stopDragWithVelocity(boolean remove, float velocityX) {
+
+ mUseRemoveVelocity = true;
+ return stopDrag(remove, velocityX);
+ }
+
+ public boolean stopDrag(boolean remove, float velocityX) {
+ if (mFloatView != null) {
+ mDragScroller.stopScrolling(true);
+
+ if (remove) {
+ removeItem(mSrcPos - getHeaderViewsCount(), velocityX);
+ } else {
+ if (mDropAnimator != null) {
+ mDropAnimator.start();
+ } else {
+ dropFloatView();
+ }
+ }
+
+ if (mTrackDragSort) {
+ mDragSortTracker.stopTracking();
+ }
+
+ return true;
+ } else {
+ // stop failed
+ return false;
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if (mIgnoreTouchEvent) {
+ mIgnoreTouchEvent = false;
+ return false;
+ }
+
+ if (!mDragEnabled) {
+ return super.onTouchEvent(ev);
+ }
+
+ boolean more = false;
+
+ boolean lastCallWasIntercept = mLastCallWasIntercept;
+ mLastCallWasIntercept = false;
+
+ if (!lastCallWasIntercept) {
+ saveTouchCoords(ev);
+ }
+
+ // if (mFloatView != null) {
+ if (mDragState == DRAGGING) {
+ onDragTouchEvent(ev);
+ more = true; // give us more!
+ } else {
+ // what if float view is null b/c we dropped in middle
+ // of drag touch event?
+
+ // if (mDragState != STOPPED) {
+ if (mDragState == IDLE) {
+ if (super.onTouchEvent(ev)) {
+ more = true;
+ }
+ }
+
+ int action = ev.getAction() & MotionEvent.ACTION_MASK;
+
+ switch (action) {
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ doActionUpOrCancel();
+ break;
+ default:
+ if (more) {
+ mCancelMethod = ON_TOUCH_EVENT;
+ }
+ }
+ }
+
+ return more;
+ }
+
+ private void doActionUpOrCancel() {
+ mCancelMethod = NO_CANCEL;
+ mInTouchEvent = false;
+ if (mDragState == STOPPED) {
+ mDragState = IDLE;
+ }
+ mCurrFloatAlpha = mFloatAlpha;
+ mListViewIntercepted = false;
+ mChildHeightCache.clear();
+ }
+
+ private void saveTouchCoords(MotionEvent ev) {
+ int action = ev.getAction() & MotionEvent.ACTION_MASK;
+ if (action != MotionEvent.ACTION_DOWN) {
+ mLastX = mX;
+ mLastY = mY;
+ }
+ mX = (int) ev.getX();
+ mY = (int) ev.getY();
+ if (action == MotionEvent.ACTION_DOWN) {
+ mLastX = mX;
+ mLastY = mY;
+ }
+ mOffsetX = (int) ev.getRawX() - mX;
+ mOffsetY = (int) ev.getRawY() - mY;
+ }
+
+ public boolean listViewIntercepted() {
+ return mListViewIntercepted;
+ }
+
+ private boolean mListViewIntercepted = false;
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (!mDragEnabled) {
+ return super.onInterceptTouchEvent(ev);
+ }
+
+ saveTouchCoords(ev);
+ mLastCallWasIntercept = true;
+
+ int action = ev.getAction() & MotionEvent.ACTION_MASK;
+
+ if (action == MotionEvent.ACTION_DOWN) {
+ if (mDragState != IDLE) {
+ // intercept and ignore
+ mIgnoreTouchEvent = true;
+ return true;
+ }
+ mInTouchEvent = true;
+ }
+
+ boolean intercept = false;
+
+ // the following deals with calls to super.onInterceptTouchEvent
+ if (mFloatView != null) {
+ // super's touch event canceled in startDrag
+ intercept = true;
+ } else {
+ if (super.onInterceptTouchEvent(ev)) {
+ mListViewIntercepted = true;
+ intercept = true;
+ }
+
+ switch (action) {
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ doActionUpOrCancel();
+ break;
+ default:
+ if (intercept) {
+ mCancelMethod = ON_TOUCH_EVENT;
+ } else {
+ mCancelMethod = ON_INTERCEPT_TOUCH_EVENT;
+ }
+ }
+ }
+
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ mInTouchEvent = false;
+ }
+
+ return intercept;
+ }
+
+ /**
+ * Set the width of each drag scroll region by specifying
+ * a fraction of the ListView height.
+ *
+ * @param heightFraction Fraction of ListView height. Capped at
+ * 0.5f.
+ *
+ */
+ public void setDragScrollStart(float heightFraction) {
+ setDragScrollStarts(heightFraction, heightFraction);
+ }
+
+ /**
+ * Set the width of each drag scroll region by specifying
+ * a fraction of the ListView height.
+ *
+ * @param upperFrac Fraction of ListView height for up-scroll bound.
+ * Capped at 0.5f.
+ * @param lowerFrac Fraction of ListView height for down-scroll bound.
+ * Capped at 0.5f.
+ *
+ */
+ public void setDragScrollStarts(float upperFrac, float lowerFrac) {
+ if (lowerFrac > 0.5f) {
+ mDragDownScrollStartFrac = 0.5f;
+ } else {
+ mDragDownScrollStartFrac = lowerFrac;
+ }
+
+ if (upperFrac > 0.5f) {
+ mDragUpScrollStartFrac = 0.5f;
+ } else {
+ mDragUpScrollStartFrac = upperFrac;
+ }
+
+ if (getHeight() != 0) {
+ updateScrollStarts();
+ }
+ }
+
+ private void continueDrag(int x, int y) {
+
+ // proposed position
+ mFloatLoc.x = x - mDragDeltaX;
+ mFloatLoc.y = y - mDragDeltaY;
+
+ doDragFloatView(true);
+
+ int minY = Math.min(y, mFloatViewMid + mFloatViewHeightHalf);
+ int maxY = Math.max(y, mFloatViewMid - mFloatViewHeightHalf);
+
+ // get the current scroll direction
+ int currentScrollDir = mDragScroller.getScrollDir();
+
+ if (minY > mLastY && minY > mDownScrollStartY && currentScrollDir != DragScroller.DOWN) {
+ // dragged down, it is below the down scroll start and it is not
+ // scrolling up
+
+ if (currentScrollDir != DragScroller.STOP) {
+ // moved directly from up scroll to down scroll
+ mDragScroller.stopScrolling(true);
+ }
+
+ // start scrolling down
+ mDragScroller.startScrolling(DragScroller.DOWN);
+ } else if (maxY < mLastY && maxY < mUpScrollStartY && currentScrollDir != DragScroller.UP) {
+ // dragged up, it is above the up scroll start and it is not
+ // scrolling up
+
+ if (currentScrollDir != DragScroller.STOP) {
+ // moved directly from down scroll to up scroll
+ mDragScroller.stopScrolling(true);
+ }
+
+ // start scrolling up
+ mDragScroller.startScrolling(DragScroller.UP);
+ }
+ else if (maxY >= mUpScrollStartY && minY <= mDownScrollStartY
+ && mDragScroller.isScrolling()) {
+ // not in the upper nor in the lower drag-scroll regions but it is
+ // still scrolling
+
+ mDragScroller.stopScrolling(true);
+ }
+ }
+
+ private void updateScrollStarts() {
+ final int padTop = getPaddingTop();
+ final int listHeight = getHeight() - padTop - getPaddingBottom();
+ float heightF = (float) listHeight;
+
+ mUpScrollStartYF = padTop + mDragUpScrollStartFrac * heightF;
+ mDownScrollStartYF = padTop + (1.0f - mDragDownScrollStartFrac) * heightF;
+
+ mUpScrollStartY = (int) mUpScrollStartYF;
+ mDownScrollStartY = (int) mDownScrollStartYF;
+
+ mDragUpScrollHeight = mUpScrollStartYF - padTop;
+ mDragDownScrollHeight = padTop + listHeight - mDownScrollStartYF;
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ updateScrollStarts();
+ }
+
+ private void adjustAllItems() {
+ final int first = getFirstVisiblePosition();
+ final int last = getLastVisiblePosition();
+
+ int begin = Math.max(0, getHeaderViewsCount() - first);
+ int end = Math.min(last - first, getCount() - 1 - getFooterViewsCount() - first);
+
+ for (int i = begin; i <= end; ++i) {
+ View v = getChildAt(i);
+ if (v != null) {
+ adjustItem(first + i, v, false);
+ }
+ }
+ }
+
+ private void adjustItem(int position) {
+ View v = getChildAt(position - getFirstVisiblePosition());
+
+ if (v != null) {
+ adjustItem(position, v, false);
+ }
+ }
+
+ /**
+ * Sets layout param height, gravity, and visibility on
+ * wrapped item.
+ */
+ private void adjustItem(int position, View v, boolean invalidChildHeight) {
+
+ // Adjust item height
+ ViewGroup.LayoutParams lp = v.getLayoutParams();
+ int height;
+ if (position != mSrcPos && position != mFirstExpPos && position != mSecondExpPos) {
+ height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ } else {
+ height = calcItemHeight(position, v, invalidChildHeight);
+ }
+
+ if (height != lp.height) {
+ lp.height = height;
+ v.setLayoutParams(lp);
+ }
+
+ // Adjust item gravity
+ if (position == mFirstExpPos || position == mSecondExpPos) {
+ if (position < mSrcPos) {
+ ((DragSortItemView) v).setGravity(Gravity.BOTTOM);
+ } else if (position > mSrcPos) {
+ ((DragSortItemView) v).setGravity(Gravity.TOP);
+ }
+ }
+
+ // Finally adjust item visibility
+
+ int oldVis = v.getVisibility();
+ int vis = View.VISIBLE;
+
+ if (position == mSrcPos && mFloatView != null) {
+ vis = View.INVISIBLE;
+ }
+
+ if (vis != oldVis) {
+ v.setVisibility(vis);
+ }
+ }
+
+ private int getChildHeight(int position) {
+ if (position == mSrcPos) {
+ return 0;
+ }
+
+ View v = getChildAt(position - getFirstVisiblePosition());
+
+ if (v != null) {
+ // item is onscreen, therefore child height is valid,
+ // hence the "true"
+ return getChildHeight(position, v, false);
+ } else {
+ // item is offscreen
+ // first check cache for child height at this position
+ int childHeight = mChildHeightCache.get(position);
+ if (childHeight != -1) {
+ // Log.d("mobeta", "found child height in cache!");
+ return childHeight;
+ }
+
+ final ListAdapter adapter = getAdapter();
+ int type = adapter.getItemViewType(position);
+
+ // There might be a better place for checking for the following
+ final int typeCount = adapter.getViewTypeCount();
+ if (typeCount != mSampleViewTypes.length) {
+ mSampleViewTypes = new View[typeCount];
+ }
+
+ if (type >= 0) {
+ if (mSampleViewTypes[type] == null) {
+ v = adapter.getView(position, null, this);
+ mSampleViewTypes[type] = v;
+ } else {
+ v = adapter.getView(position, mSampleViewTypes[type], this);
+ }
+ } else {
+ // type is HEADER_OR_FOOTER or IGNORE
+ v = adapter.getView(position, null, this);
+ }
+
+ // current child height is invalid, hence "true" below
+ childHeight = getChildHeight(position, v, true);
+
+ // cache it because this could have been expensive
+ mChildHeightCache.add(position, childHeight);
+
+ return childHeight;
+ }
+ }
+
+ private int getChildHeight(int position, View item, boolean invalidChildHeight) {
+ if (position == mSrcPos) {
+ return 0;
+ }
+
+ View child;
+ if (position < getHeaderViewsCount() || position >= getCount() - getFooterViewsCount()) {
+ child = item;
+ } else {
+ child = ((ViewGroup) item).getChildAt(0);
+ }
+
+ ViewGroup.LayoutParams lp = child.getLayoutParams();
+
+ if (lp != null) {
+ if (lp.height > 0) {
+ return lp.height;
+ }
+ }
+
+ int childHeight = child.getHeight();
+
+ if (childHeight == 0 || invalidChildHeight) {
+ measureItem(child);
+ childHeight = child.getMeasuredHeight();
+ }
+
+ return childHeight;
+ }
+
+ private int calcItemHeight(int position, View item, boolean invalidChildHeight) {
+ return calcItemHeight(position, getChildHeight(position, item, invalidChildHeight));
+ }
+
+ private int calcItemHeight(int position, int childHeight) {
+
+ int divHeight = getDividerHeight();
+
+ boolean isSliding = mAnimate && mFirstExpPos != mSecondExpPos;
+ int maxNonSrcBlankHeight = mFloatViewHeight - mItemHeightCollapsed;
+ int slideHeight = (int) (mSlideFrac * maxNonSrcBlankHeight);
+
+ int height;
+
+ if (position == mSrcPos) {
+ if (mSrcPos == mFirstExpPos) {
+ if (isSliding) {
+ height = slideHeight + mItemHeightCollapsed;
+ } else {
+ height = mFloatViewHeight;
+ }
+ } else if (mSrcPos == mSecondExpPos) {
+ // if gets here, we know an item is sliding
+ height = mFloatViewHeight - slideHeight;
+ } else {
+ height = mItemHeightCollapsed;
+ }
+ } else if (position == mFirstExpPos) {
+ if (isSliding) {
+ height = childHeight + slideHeight;
+ } else {
+ height = childHeight + maxNonSrcBlankHeight;
+ }
+ } else if (position == mSecondExpPos) {
+ // we know an item is sliding (b/c 2ndPos != 1stPos)
+ height = childHeight + maxNonSrcBlankHeight - slideHeight;
+ } else {
+ height = childHeight;
+ }
+
+ return height;
+ }
+
+ @Override
+ public void requestLayout() {
+ if (!mBlockLayoutRequests) {
+ super.requestLayout();
+ }
+ }
+
+ private int adjustScroll(int movePos, View moveItem, int oldFirstExpPos, int oldSecondExpPos) {
+ int adjust = 0;
+
+ final int childHeight = getChildHeight(movePos);
+
+ int moveHeightBefore = moveItem.getHeight();
+ int moveHeightAfter = calcItemHeight(movePos, childHeight);
+
+ int moveBlankBefore = moveHeightBefore;
+ int moveBlankAfter = moveHeightAfter;
+ if (movePos != mSrcPos) {
+ moveBlankBefore -= childHeight;
+ moveBlankAfter -= childHeight;
+ }
+
+ int maxBlank = mFloatViewHeight;
+ if (mSrcPos != mFirstExpPos && mSrcPos != mSecondExpPos) {
+ maxBlank -= mItemHeightCollapsed;
+ }
+
+ if (movePos <= oldFirstExpPos) {
+ if (movePos > mFirstExpPos) {
+ adjust += maxBlank - moveBlankAfter;
+ }
+ } else if (movePos == oldSecondExpPos) {
+ if (movePos <= mFirstExpPos) {
+ adjust += moveBlankBefore - maxBlank;
+ } else if (movePos == mSecondExpPos) {
+ adjust += moveHeightBefore - moveHeightAfter;
+ } else {
+ adjust += moveBlankBefore;
+ }
+ } else {
+ if (movePos <= mFirstExpPos) {
+ adjust -= maxBlank;
+ } else if (movePos == mSecondExpPos) {
+ adjust -= moveBlankAfter;
+ }
+ }
+
+ return adjust;
+ }
+
+ private void measureItem(View item) {
+ ViewGroup.LayoutParams lp = item.getLayoutParams();
+ if (lp == null) {
+ lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ item.setLayoutParams(lp);
+ }
+ int wspec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getListPaddingLeft()
+ + getListPaddingRight(), lp.width);
+ int hspec;
+ if (lp.height > 0) {
+ hspec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
+ } else {
+ hspec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ }
+ item.measure(wspec, hspec);
+ }
+
+ private void measureFloatView() {
+ if (mFloatView != null) {
+ measureItem(mFloatView);
+ mFloatViewHeight = mFloatView.getMeasuredHeight();
+ mFloatViewHeightHalf = mFloatViewHeight / 2;
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ // Log.d("mobeta", "onMeasure called");
+ if (mFloatView != null) {
+ if (mFloatView.isLayoutRequested()) {
+ measureFloatView();
+ }
+ mFloatViewOnMeasured = true; // set to false after layout
+ }
+ mWidthMeasureSpec = widthMeasureSpec;
+ }
+
+ @Override
+ protected void layoutChildren() {
+ super.layoutChildren();
+
+ if (mFloatView != null) {
+ if (mFloatView.isLayoutRequested() && !mFloatViewOnMeasured) {
+ // Have to measure here when usual android measure
+ // pass is skipped. This happens during a drag-sort
+ // when layoutChildren is called directly.
+ measureFloatView();
+ }
+ mFloatView.layout(0, 0, mFloatView.getMeasuredWidth(), mFloatView.getMeasuredHeight());
+ mFloatViewOnMeasured = false;
+ }
+ }
+
+ protected boolean onDragTouchEvent(MotionEvent ev) {
+ // we are in a drag
+ int action = ev.getAction() & MotionEvent.ACTION_MASK;
+
+ switch (ev.getAction() & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_CANCEL:
+ if (mDragState == DRAGGING) {
+ cancelDrag();
+ }
+ doActionUpOrCancel();
+ break;
+ case MotionEvent.ACTION_UP:
+ // Log.d("mobeta", "calling stopDrag from onDragTouchEvent");
+ if (mDragState == DRAGGING) {
+ stopDrag(false);
+ }
+ doActionUpOrCancel();
+ break;
+ case MotionEvent.ACTION_MOVE:
+ continueDrag((int) ev.getX(), (int) ev.getY());
+ break;
+ }
+
+ return true;
+ }
+
+ private boolean mFloatViewInvalidated = false;
+
+ private void invalidateFloatView() {
+ mFloatViewInvalidated = true;
+ }
+
+ /**
+ * Start a drag of item at <code>position</code> using the
+ * registered FloatViewManager. Calls through
+ * to {@link #startDrag(int,View,int,int,int)} after obtaining
+ * the floating View from the FloatViewManager.
+ *
+ * @param position Item to drag.
+ * @param dragFlags Flags that restrict some movements of the
+ * floating View. For example, set <code>dragFlags |=
+ * ~{@link #DRAG_NEG_X}</code> to allow dragging the floating
+ * View in all directions except off the screen to the left.
+ * @param deltaX Offset in x of the touch coordinate from the
+ * left edge of the floating View (i.e. touch-x minus float View
+ * left).
+ * @param deltaY Offset in y of the touch coordinate from the
+ * top edge of the floating View (i.e. touch-y minus float View
+ * top).
+ *
+ * @return True if the drag was started, false otherwise. This
+ * <code>startDrag</code> will fail if we are not currently in
+ * a touch event, there is no registered FloatViewManager,
+ * or the FloatViewManager returns a null View.
+ */
+ public boolean startDrag(int position, int dragFlags, int deltaX, int deltaY) {
+ if (!mInTouchEvent || mFloatViewManager == null) {
+ return false;
+ }
+
+ View v = mFloatViewManager.onCreateFloatView(position);
+
+ if (v == null) {
+ return false;
+ } else {
+ return startDrag(position, v, dragFlags, deltaX, deltaY);
+ }
+
+ }
+
+ /**
+ * Start a drag of item at <code>position</code> without using
+ * a FloatViewManager.
+ *
+ * @param position Item to drag.
+ * @param floatView Floating View.
+ * @param dragFlags Flags that restrict some movements of the
+ * floating View. For example, set <code>dragFlags |=
+ * ~{@link #DRAG_NEG_X}</code> to allow dragging the floating
+ * View in all directions except off the screen to the left.
+ * @param deltaX Offset in x of the touch coordinate from the
+ * left edge of the floating View (i.e. touch-x minus float View
+ * left).
+ * @param deltaY Offset in y of the touch coordinate from the
+ * top edge of the floating View (i.e. touch-y minus float View
+ * top).
+ *
+ * @return True if the drag was started, false otherwise. This
+ * <code>startDrag</code> will fail if we are not currently in
+ * a touch event, <code>floatView</code> is null, or there is
+ * a drag in progress.
+ */
+ public boolean startDrag(int position, View floatView, int dragFlags, int deltaX, int deltaY) {
+ if (mDragState != IDLE || !mInTouchEvent || mFloatView != null || floatView == null
+ || !mDragEnabled) {
+ return false;
+ }
+
+ if (getParent() != null) {
+ getParent().requestDisallowInterceptTouchEvent(true);
+ }
+
+ int pos = position + getHeaderViewsCount();
+ mFirstExpPos = pos;
+ mSecondExpPos = pos;
+ mSrcPos = pos;
+ mFloatPos = pos;
+
+ // mDragState = dragType;
+ mDragState = DRAGGING;
+ mDragFlags = 0;
+ mDragFlags |= dragFlags;
+
+ mFloatView = floatView;
+ measureFloatView(); // sets mFloatViewHeight
+
+ mDragDeltaX = deltaX;
+ mDragDeltaY = deltaY;
+ mDragStartY = mY;
+
+ // updateFloatView(mX - mDragDeltaX, mY - mDragDeltaY);
+ mFloatLoc.x = mX - mDragDeltaX;
+ mFloatLoc.y = mY - mDragDeltaY;
+
+ // set src item invisible
+ final View srcItem = getChildAt(mSrcPos - getFirstVisiblePosition());
+
+ if (srcItem != null) {
+ srcItem.setVisibility(View.INVISIBLE);
+ }
+
+ if (mTrackDragSort) {
+ mDragSortTracker.startTracking();
+ }
+
+ // once float view is created, events are no longer passed
+ // to ListView
+ switch (mCancelMethod) {
+ case ON_TOUCH_EVENT:
+ super.onTouchEvent(mCancelEvent);
+ break;
+ case ON_INTERCEPT_TOUCH_EVENT:
+ super.onInterceptTouchEvent(mCancelEvent);
+ break;
+ }
+
+ requestLayout();
+
+ if (mLiftAnimator != null) {
+ mLiftAnimator.start();
+ }
+
+ return true;
+ }
+
+ private void doDragFloatView(boolean forceInvalidate) {
+ int movePos = getFirstVisiblePosition() + getChildCount() / 2;
+ View moveItem = getChildAt(getChildCount() / 2);
+
+ if (moveItem == null) {
+ return;
+ }
+
+ doDragFloatView(movePos, moveItem, forceInvalidate);
+ }
+
+ private void doDragFloatView(int movePos, View moveItem, boolean forceInvalidate) {
+ mBlockLayoutRequests = true;
+
+ updateFloatView();
+
+ int oldFirstExpPos = mFirstExpPos;
+ int oldSecondExpPos = mSecondExpPos;
+
+ boolean updated = updatePositions();
+
+ if (updated) {
+ adjustAllItems();
+ int scroll = adjustScroll(movePos, moveItem, oldFirstExpPos, oldSecondExpPos);
+ // Log.d("mobeta", " adjust scroll="+scroll);
+
+ setSelectionFromTop(movePos, moveItem.getTop() + scroll - getPaddingTop());
+ layoutChildren();
+ }
+
+ if (updated || forceInvalidate) {
+ invalidate();
+ }
+
+ mBlockLayoutRequests = false;
+ }
+
+ /**
+ * Sets float View location based on suggested values and
+ * constraints set in mDragFlags.
+ */
+ private void updateFloatView() {
+
+ if (mFloatViewManager != null) {
+ mTouchLoc.set(mX, mY);
+ mFloatViewManager.onDragFloatView(mFloatView, mFloatLoc, mTouchLoc);
+ }
+
+ final int floatX = mFloatLoc.x;
+ final int floatY = mFloatLoc.y;
+
+ // restrict x motion
+ int padLeft = getPaddingLeft();
+ if ((mDragFlags & DRAG_POS_X) == 0 && floatX > padLeft) {
+ mFloatLoc.x = padLeft;
+ } else if ((mDragFlags & DRAG_NEG_X) == 0 && floatX < padLeft) {
+ mFloatLoc.x = padLeft;
+ }
+
+ // keep floating view from going past bottom of last header view
+ final int numHeaders = getHeaderViewsCount();
+ final int numFooters = getFooterViewsCount();
+ final int firstPos = getFirstVisiblePosition();
+ final int lastPos = getLastVisiblePosition();
+
+ // Log.d("mobeta",
+ // "nHead="+numHeaders+" nFoot="+numFooters+" first="+firstPos+" last="+lastPos);
+ int topLimit = getPaddingTop();
+ if (firstPos < numHeaders) {
+ topLimit = getChildAt(numHeaders - firstPos - 1).getBottom();
+ }
+ if ((mDragFlags & DRAG_NEG_Y) == 0) {
+ if (firstPos <= mSrcPos) {
+ topLimit = Math.max(getChildAt(mSrcPos - firstPos).getTop(), topLimit);
+ }
+ }
+ // bottom limit is top of first footer View or
+ // bottom of last item in list
+ int bottomLimit = getHeight() - getPaddingBottom();
+ if (lastPos >= getCount() - numFooters - 1) {
+ bottomLimit = getChildAt(getCount() - numFooters - 1 - firstPos).getBottom();
+ }
+ if ((mDragFlags & DRAG_POS_Y) == 0) {
+ if (lastPos >= mSrcPos) {
+ bottomLimit = Math.min(getChildAt(mSrcPos - firstPos).getBottom(), bottomLimit);
+ }
+ }
+
+ // Log.d("mobeta", "dragView top=" + (y - mDragDeltaY));
+ // Log.d("mobeta", "limit=" + limit);
+ // Log.d("mobeta", "mDragDeltaY=" + mDragDeltaY);
+
+ if (floatY < topLimit) {
+ mFloatLoc.y = topLimit;
+ } else if (floatY + mFloatViewHeight > bottomLimit) {
+ mFloatLoc.y = bottomLimit - mFloatViewHeight;
+ }
+
+ // get y-midpoint of floating view (constrained to ListView bounds)
+ mFloatViewMid = mFloatLoc.y + mFloatViewHeightHalf;
+ }
+
+ private void destroyFloatView() {
+ if (mFloatView != null) {
+ mFloatView.setVisibility(GONE);
+ if (mFloatViewManager != null) {
+ mFloatViewManager.onDestroyFloatView(mFloatView);
+ }
+ mFloatView = null;
+ invalidate();
+ }
+ }
+
+ /**
+ * Interface for customization of the floating View appearance
+ * and dragging behavior. Implement
+ * your own and pass it to {@link #setFloatViewManager}. If
+ * your own is not passed, the default {@link SimpleFloatViewManager}
+ * implementation is used.
+ */
+ public interface FloatViewManager {
+ /**
+ * Return the floating View for item at <code>position</code>.
+ * DragSortListView will measure and layout this View for you,
+ * so feel free to just inflate it. You can help DSLV by
+ * setting some {@link ViewGroup.LayoutParams} on this View;
+ * otherwise it will set some for you (with a width of FILL_PARENT
+ * and a height of WRAP_CONTENT).
+ *
+ * @param position Position of item to drag (NOTE:
+ * <code>position</code> excludes header Views; thus, if you
+ * want to call {@link ListView#getChildAt(int)}, you will need
+ * to add {@link ListView#getHeaderViewsCount()} to the index).
+ *
+ * @return The View you wish to display as the floating View.
+ */
+ public View onCreateFloatView(int position);
+
+ /**
+ * Called whenever the floating View is dragged. Float View
+ * properties can be changed here. Also, the upcoming location
+ * of the float View can be altered by setting
+ * <code>location.x</code> and <code>location.y</code>.
+ *
+ * @param floatView The floating View.
+ * @param location The location (top-left; relative to DSLV
+ * top-left) at which the float
+ * View would like to appear, given the current touch location
+ * and the offset provided in {@link DragSortListView#startDrag}.
+ * @param touch The current touch location (relative to DSLV
+ * top-left).
+ * @param pendingScroll
+ */
+ public void onDragFloatView(View floatView, Point location, Point touch);
+
+ /**
+ * Called when the float View is dropped; lets you perform
+ * any necessary cleanup. The internal DSLV floating View
+ * reference is set to null immediately after this is called.
+ *
+ * @param floatView The floating View passed to
+ * {@link #onCreateFloatView(int)}.
+ */
+ public void onDestroyFloatView(View floatView);
+ }
+
+ public void setFloatViewManager(FloatViewManager manager) {
+ mFloatViewManager = manager;
+ }
+
+ public void setDragListener(DragListener l) {
+ mDragListener = l;
+ }
+
+ /**
+ * Allows for easy toggling between a DragSortListView
+ * and a regular old ListView. If enabled, items are
+ * draggable, where the drag init mode determines how
+ * items are lifted (see {@link setDragInitMode(int)}).
+ * If disabled, items cannot be dragged.
+ *
+ * @param enabled Set <code>true</code> to enable list
+ * item dragging
+ */
+ public void setDragEnabled(boolean enabled) {
+ mDragEnabled = enabled;
+ }
+
+ public boolean isDragEnabled() {
+ return mDragEnabled;
+ }
+
+ /**
+ * This better reorder your ListAdapter! DragSortListView does not do this
+ * for you; doesn't make sense to. Make sure
+ * {@link BaseAdapter#notifyDataSetChanged()} or something like it is called
+ * in your implementation. Furthermore, if you have a choiceMode other than
+ * none and the ListAdapter does not return true for
+ * {@link ListAdapter#hasStableIds()}, you will need to call
+ * {@link #moveCheckState(int, int)} to move the check boxes along with the
+ * list items.
+ *
+ * @param l
+ */
+ public void setDropListener(DropListener l) {
+ mDropListener = l;
+ }
+
+ /**
+ * Probably a no-brainer, but make sure that your remove listener
+ * calls {@link BaseAdapter#notifyDataSetChanged()} or something like it.
+ * When an item removal occurs, DragSortListView
+ * relies on a redraw of all the items to recover invisible views
+ * and such. Strictly speaking, if you remove something, your dataset
+ * has changed...
+ *
+ * @param l
+ */
+ public void setRemoveListener(RemoveListener l) {
+ mRemoveListener = l;
+ }
+
+ public interface DragListener {
+ public void drag(int from, int to);
+ }
+
+ /**
+ * Your implementation of this has to reorder your ListAdapter!
+ * Make sure to call
+ * {@link BaseAdapter#notifyDataSetChanged()} or something like it
+ * in your implementation.
+ *
+ * @author heycosmo
+ *
+ */
+ public interface DropListener {
+ public void drop(int from, int to);
+ }
+
+ /**
+ * Make sure to call
+ * {@link BaseAdapter#notifyDataSetChanged()} or something like it
+ * in your implementation.
+ *
+ * @author heycosmo
+ *
+ */
+ public interface RemoveListener {
+ public void remove(int which);
+ }
+
+ public interface DragSortListener extends DropListener, DragListener, RemoveListener {
+ }
+
+ public void setDragSortListener(DragSortListener l) {
+ setDropListener(l);
+ setDragListener(l);
+ setRemoveListener(l);
+ }
+
+ /**
+ * Completely custom scroll speed profile. Default increases linearly
+ * with position and is constant in time. Create your own by implementing
+ * {@link DragSortListView.DragScrollProfile}.
+ *
+ * @param ssp
+ */
+ public void setDragScrollProfile(DragScrollProfile ssp) {
+ if (ssp != null) {
+ mScrollProfile = ssp;
+ }
+ }
+
+ /**
+ * Use this to move the check state of an item from one position to another
+ * in a drop operation. If you have a choiceMode which is not none, this
+ * method must be called when the order of items changes in an underlying
+ * adapter which does not have stable IDs (see
+ * {@link ListAdapter#hasStableIds()}). This is because without IDs, the
+ * ListView has no way of knowing which items have moved where, and cannot
+ * update the check state accordingly.
+ * <p>
+ * A word of warning about a "feature" in Android that you may run into when
+ * dealing with movable list items: for an adapter that <em>does</em> have
+ * stable IDs, ListView will attempt to locate each item based on its ID and
+ * move the check state from the item's old position to the new position —
+ * which is all fine and good (and removes the need for calling this
+ * function), except for the half-baked approach. Apparently to save time in
+ * the naive algorithm used, ListView will only search for an ID in the
+ * close neighborhood of the old position. If the user moves an item too far
+ * (specifically, more than 20 rows away), ListView will give up and just
+ * force the item to be unchecked. So if there is a reasonable chance that
+ * the user will move items more than 20 rows away from the original
+ * position, you may wish to use an adapter with unstable IDs and call this
+ * method manually instead.
+ *
+ * @param from
+ * @param to
+ */
+ public void moveCheckState(int from, int to) {
+ // This method runs in O(n log n) time (n being the number of list
+ // items). The bottleneck is the call to AbsListView.setItemChecked,
+ // which is O(log n) because of the binary search involved in calling
+ // SparseBooleanArray.put().
+ //
+ // To improve on the average time, we minimize the number of calls to
+ // setItemChecked by only calling it for items that actually have a
+ // changed state. This is achieved by building a list containing the
+ // start and end of the "runs" of checked items, and then moving the
+ // runs. Note that moving an item from A to B is essentially a rotation
+ // of the range of items in [A, B]. Let's say we have
+ // . . U V X Y Z . .
+ // and move U after Z. This is equivalent to a rotation one step to the
+ // left within the range you are moving across:
+ // . . V X Y Z U . .
+ //
+ // So, to perform the move we enumerate all the runs within the move
+ // range, then rotate each run one step to the left or right (depending
+ // on move direction). For example, in the list:
+ // X X . X X X . X
+ // we have two runs. One begins at the last item of the list and wraps
+ // around to the beginning, ending at position 1. The second begins at
+ // position 3 and ends at position 5. To rotate a run, regardless of
+ // length, we only need to set a check mark at one end of the run, and
+ // clear a check mark at the other end:
+ // X . X X X . X X
+ SparseBooleanArray cip = getCheckedItemPositions();
+ int rangeStart = from;
+ int rangeEnd = to;
+ if (to < from) {
+ rangeStart = to;
+ rangeEnd = from;
+ }
+ rangeEnd += 1;
+
+ int[] runStart = new int[cip.size()];
+ int[] runEnd = new int[cip.size()];
+ int runCount = buildRunList(cip, rangeStart, rangeEnd, runStart, runEnd);
+ if (runCount == 1 && (runStart[0] == runEnd[0])) {
+ // Special case where all items are checked, we can never set any
+ // item to false like we do below.
+ return;
+ }
+
+ if (from < to) {
+ for (int i = 0; i != runCount; i++) {
+ setItemChecked(rotate(runStart[i], -1, rangeStart, rangeEnd), true);
+ setItemChecked(rotate(runEnd[i], -1, rangeStart, rangeEnd), false);
+ }
+
+ } else {
+ for (int i = 0; i != runCount; i++) {
+ setItemChecked(runStart[i], false);
+ setItemChecked(runEnd[i], true);
+ }
+ }
+ }
+
+ /**
+ * Use this when an item has been deleted, to move the check state of all
+ * following items up one step. If you have a choiceMode which is not none,
+ * this method must be called when the order of items changes in an
+ * underlying adapter which does not have stable IDs (see
+ * {@link ListAdapter#hasStableIds()}). This is because without IDs, the
+ * ListView has no way of knowing which items have moved where, and cannot
+ * update the check state accordingly.
+ *
+ * See also further comments on {@link #moveCheckState(int, int)}.
+ *
+ * @param position
+ */
+ public void removeCheckState(int position) {
+ SparseBooleanArray cip = getCheckedItemPositions();
+
+ if (cip.size() == 0)
+ return;
+ int[] runStart = new int[cip.size()];
+ int[] runEnd = new int[cip.size()];
+ int rangeStart = position;
+ int rangeEnd = cip.keyAt(cip.size() - 1) + 1;
+ int runCount = buildRunList(cip, rangeStart, rangeEnd, runStart, runEnd);
+ for (int i = 0; i != runCount; i++) {
+ if (!(runStart[i] == position || (runEnd[i] < runStart[i] && runEnd[i] > position))) {
+ // Only set a new check mark in front of this run if it does
+ // not contain the deleted position. If it does, we only need
+ // to make it one check mark shorter at the end.
+ setItemChecked(rotate(runStart[i], -1, rangeStart, rangeEnd), true);
+ }
+ setItemChecked(rotate(runEnd[i], -1, rangeStart, rangeEnd), false);
+ }
+ }
+
+ private static int buildRunList(SparseBooleanArray cip, int rangeStart,
+ int rangeEnd, int[] runStart, int[] runEnd) {
+ int runCount = 0;
+
+ int i = findFirstSetIndex(cip, rangeStart, rangeEnd);
+ if (i == -1)
+ return 0;
+
+ int position = cip.keyAt(i);
+ int currentRunStart = position;
+ int currentRunEnd = currentRunStart + 1;
+ for (i++; i < cip.size() && (position = cip.keyAt(i)) < rangeEnd; i++) {
+ if (!cip.valueAt(i)) // not checked => not interesting
+ continue;
+ if (position == currentRunEnd) {
+ currentRunEnd++;
+ } else {
+ runStart[runCount] = currentRunStart;
+ runEnd[runCount] = currentRunEnd;
+ runCount++;
+ currentRunStart = position;
+ currentRunEnd = position + 1;
+ }
+ }
+
+ if (currentRunEnd == rangeEnd) {
+ // rangeStart and rangeEnd are equivalent positions so to be
+ // consistent we translate them to the same integer value. That way
+ // we can check whether a run covers the entire range by just
+ // checking if the start equals the end position.
+ currentRunEnd = rangeStart;
+ }
+ runStart[runCount] = currentRunStart;
+ runEnd[runCount] = currentRunEnd;
+ runCount++;
+
+ if (runCount > 1) {
+ if (runStart[0] == rangeStart && runEnd[runCount - 1] == rangeStart) {
+ // The last run ends at the end of the range, and the first run
+ // starts at the beginning of the range. So they are actually
+ // part of the same run, except they wrap around the end of the
+ // range. To avoid adjacent runs, we need to merge them.
+ runStart[0] = runStart[runCount - 1];
+ runCount--;
+ }
+ }
+ return runCount;
+ }
+
+ private static int rotate(int value, int offset, int lowerBound, int upperBound) {
+ int windowSize = upperBound - lowerBound;
+
+ value += offset;
+ if (value < lowerBound) {
+ value += windowSize;
+ } else if (value >= upperBound) {
+ value -= windowSize;
+ }
+ return value;
+ }
+
+ private static int findFirstSetIndex(SparseBooleanArray sba, int rangeStart, int rangeEnd) {
+ int size = sba.size();
+ int i = insertionIndexForKey(sba, rangeStart);
+ while (i < size && sba.keyAt(i) < rangeEnd && !sba.valueAt(i))
+ i++;
+ if (i == size || sba.keyAt(i) >= rangeEnd)
+ return -1;
+ return i;
+ }
+
+ private static int insertionIndexForKey(SparseBooleanArray sba, int key) {
+ int low = 0;
+ int high = sba.size();
+ while (high - low > 0) {
+ int middle = (low + high) >> 1;
+ if (sba.keyAt(middle) < key)
+ low = middle + 1;
+ else
+ high = middle;
+ }
+ return low;
+ }
+
+ /**
+ * Interface for controlling
+ * scroll speed as a function of touch position and time. Use
+ * {@link DragSortListView#setDragScrollProfile(DragScrollProfile)} to
+ * set custom profile.
+ *
+ * @author heycosmo
+ *
+ */
+ public interface DragScrollProfile {
+ /**
+ * Return a scroll speed in pixels/millisecond. Always return a
+ * positive number.
+ *
+ * @param w Normalized position in scroll region (i.e. w \in [0,1]).
+ * Small w typically means slow scrolling.
+ * @param t Time (in milliseconds) since start of scroll (handy if you
+ * want scroll acceleration).
+ * @return Scroll speed at position w and time t in pixels/ms.
+ */
+ float getSpeed(float w, long t);
+ }
+
+ private class DragScroller implements Runnable {
+
+ private boolean mAbort;
+
+ private long mPrevTime;
+ private long mCurrTime;
+
+ private int dy;
+ private float dt;
+ private long tStart;
+ private int scrollDir;
+
+ public final static int STOP = -1;
+ public final static int UP = 0;
+ public final static int DOWN = 1;
+
+ private float mScrollSpeed; // pixels per ms
+
+ private boolean mScrolling = false;
+
+ private int mLastHeader;
+ private int mFirstFooter;
+
+ public boolean isScrolling() {
+ return mScrolling;
+ }
+
+ public int getScrollDir() {
+ return mScrolling ? scrollDir : STOP;
+ }
+
+ public DragScroller() {
+ }
+
+ public void startScrolling(int dir) {
+ if (!mScrolling) {
+ // Debug.startMethodTracing("dslv-scroll");
+ mAbort = false;
+ mScrolling = true;
+ tStart = SystemClock.uptimeMillis();
+ mPrevTime = tStart;
+ scrollDir = dir;
+ post(this);
+ }
+ }
+
+ public void stopScrolling(boolean now) {
+ if (now) {
+ DragSortListView.this.removeCallbacks(this);
+ mScrolling = false;
+ } else {
+ mAbort = true;
+ }
+
+ // Debug.stopMethodTracing();
+ }
+
+ @Override
+ public void run() {
+ if (mAbort) {
+ mScrolling = false;
+ return;
+ }
+
+ // Log.d("mobeta", "scroll");
+
+ final int first = getFirstVisiblePosition();
+ final int last = getLastVisiblePosition();
+ final int count = getCount();
+ final int padTop = getPaddingTop();
+ final int listHeight = getHeight() - padTop - getPaddingBottom();
+
+ int minY = Math.min(mY, mFloatViewMid + mFloatViewHeightHalf);
+ int maxY = Math.max(mY, mFloatViewMid - mFloatViewHeightHalf);
+
+ if (scrollDir == UP) {
+ View v = getChildAt(0);
+ // Log.d("mobeta", "vtop="+v.getTop()+" padtop="+padTop);
+ if (v == null) {
+ mScrolling = false;
+ return;
+ } else {
+ if (first == 0 && v.getTop() == padTop) {
+ mScrolling = false;
+ return;
+ }
+ }
+ mScrollSpeed = mScrollProfile.getSpeed((mUpScrollStartYF - maxY)
+ / mDragUpScrollHeight, mPrevTime);
+ } else {
+ View v = getChildAt(last - first);
+ if (v == null) {
+ mScrolling = false;
+ return;
+ } else {
+ if (last == count - 1 && v.getBottom() <= listHeight + padTop) {
+ mScrolling = false;
+ return;
+ }
+ }
+ mScrollSpeed = -mScrollProfile.getSpeed((minY - mDownScrollStartYF)
+ / mDragDownScrollHeight, mPrevTime);
+ }
+
+ mCurrTime = SystemClock.uptimeMillis();
+ dt = (float) (mCurrTime - mPrevTime);
+
+ // dy is change in View position of a list item; i.e. positive dy
+ // means user is scrolling up (list item moves down the screen,
+ // remember
+ // y=0 is at top of View).
+ dy = (int) Math.round(mScrollSpeed * dt);
+
+ int movePos;
+ if (dy >= 0) {
+ dy = Math.min(listHeight, dy);
+ movePos = first;
+ } else {
+ dy = Math.max(-listHeight, dy);
+ movePos = last;
+ }
+
+ final View moveItem = getChildAt(movePos - first);
+ int top = moveItem.getTop() + dy;
+
+ if (movePos == 0 && top > padTop) {
+ top = padTop;
+ }
+
+ // always do scroll
+ mBlockLayoutRequests = true;
+
+ setSelectionFromTop(movePos, top - padTop);
+ DragSortListView.this.layoutChildren();
+ invalidate();
+
+ mBlockLayoutRequests = false;
+
+ // scroll means relative float View movement
+ doDragFloatView(movePos, moveItem, false);
+
+ mPrevTime = mCurrTime;
+ // Log.d("mobeta", " updated prevTime="+mPrevTime);
+
+ post(this);
+ }
+ }
+
+ private class DragSortTracker {
+ StringBuilder mBuilder = new StringBuilder();
+
+ File mFile;
+
+ private int mNumInBuffer = 0;
+ private int mNumFlushes = 0;
+
+ private boolean mTracking = false;
+
+ public DragSortTracker() {
+ File root = Environment.getExternalStorageDirectory();
+ mFile = new File(root, "dslv_state.txt");
+
+ if (!mFile.exists()) {
+ try {
+ mFile.createNewFile();
+ Log.d("mobeta", "file created");
+ } catch (IOException e) {
+ Log.w("mobeta", "Could not create dslv_state.txt");
+ Log.d("mobeta", e.getMessage());
+ }
+ }
+
+ }
+
+ public void startTracking() {
+ mBuilder.append("<DSLVStates>\n");
+ mNumFlushes = 0;
+ mTracking = true;
+ }
+
+ public void appendState() {
+ if (!mTracking) {
+ return;
+ }
+
+ mBuilder.append("<DSLVState>\n");
+ final int children = getChildCount();
+ final int first = getFirstVisiblePosition();
+ mBuilder.append(" <Positions>");
+ for (int i = 0; i < children; ++i) {
+ mBuilder.append(first + i).append(",");
+ }
+ mBuilder.append("</Positions>\n");
+
+ mBuilder.append(" <Tops>");
+ for (int i = 0; i < children; ++i) {
+ mBuilder.append(getChildAt(i).getTop()).append(",");
+ }
+ mBuilder.append("</Tops>\n");
+ mBuilder.append(" <Bottoms>");
+ for (int i = 0; i < children; ++i) {
+ mBuilder.append(getChildAt(i).getBottom()).append(",");
+ }
+ mBuilder.append("</Bottoms>\n");
+
+ mBuilder.append(" <FirstExpPos>").append(mFirstExpPos).append("</FirstExpPos>\n");
+ mBuilder.append(" <FirstExpBlankHeight>")
+ .append(getItemHeight(mFirstExpPos) - getChildHeight(mFirstExpPos))
+ .append("</FirstExpBlankHeight>\n");
+ mBuilder.append(" <SecondExpPos>").append(mSecondExpPos).append("</SecondExpPos>\n");
+ mBuilder.append(" <SecondExpBlankHeight>")
+ .append(getItemHeight(mSecondExpPos) - getChildHeight(mSecondExpPos))
+ .append("</SecondExpBlankHeight>\n");
+ mBuilder.append(" <SrcPos>").append(mSrcPos).append("</SrcPos>\n");
+ mBuilder.append(" <SrcHeight>").append(mFloatViewHeight + getDividerHeight())
+ .append("</SrcHeight>\n");
+ mBuilder.append(" <ViewHeight>").append(getHeight()).append("</ViewHeight>\n");
+ mBuilder.append(" <LastY>").append(mLastY).append("</LastY>\n");
+ mBuilder.append(" <FloatY>").append(mFloatViewMid).append("</FloatY>\n");
+ mBuilder.append(" <ShuffleEdges>");
+ for (int i = 0; i < children; ++i) {
+ mBuilder.append(getShuffleEdge(first + i, getChildAt(i).getTop())).append(",");
+ }
+ mBuilder.append("</ShuffleEdges>\n");
+
+ mBuilder.append("</DSLVState>\n");
+ mNumInBuffer++;
+
+ if (mNumInBuffer > 1000) {
+ flush();
+ mNumInBuffer = 0;
+ }
+ }
+
+ public void flush() {
+ if (!mTracking) {
+ return;
+ }
+
+ // save to file on sdcard
+ try {
+ boolean append = true;
+ if (mNumFlushes == 0) {
+ append = false;
+ }
+ FileWriter writer = new FileWriter(mFile, append);
+
+ writer.write(mBuilder.toString());
+ mBuilder.delete(0, mBuilder.length());
+
+ writer.flush();
+ writer.close();
+
+ mNumFlushes++;
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+
+ public void stopTracking() {
+ if (mTracking) {
+ mBuilder.append("</DSLVStates>\n");
+ flush();
+ mTracking = false;
+ }
+ }
+
+ }
+
+}
diff --git a/src/com/mobeta/android/dslv/ResourceDragSortCursorAdapter.java b/src/com/mobeta/android/dslv/ResourceDragSortCursorAdapter.java
new file mode 100755
index 0000000..f2d0810
--- /dev/null
+++ b/src/com/mobeta/android/dslv/ResourceDragSortCursorAdapter.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.mobeta.android.dslv;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+
+// taken from v4 rev. 10 ResourceCursorAdapter.java
+
+/**
+ * Static library support version of the framework's {@link android.widget.ResourceCursorAdapter}.
+ * Used to write apps that run on platforms prior to Android 3.0. When running
+ * on Android 3.0 or above, this implementation is still used; it does not try
+ * to switch to the framework's implementation. See the framework SDK
+ * documentation for a class overview.
+ */
+public abstract class ResourceDragSortCursorAdapter extends DragSortCursorAdapter {
+ private int mLayout;
+
+ private int mDropDownLayout;
+
+ private LayoutInflater mInflater;
+
+ /**
+ * Constructor the enables auto-requery.
+ *
+ * @deprecated This option is discouraged, as it results in Cursor queries
+ * being performed on the application's UI thread and thus can cause poor
+ * responsiveness or even Application Not Responding errors. As an alternative,
+ * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
+ *
+ * @param context The context where the ListView associated with this adapter is running
+ * @param layout resource identifier of a layout file that defines the views
+ * for this list item. Unless you override them later, this will
+ * define both the item views and the drop down views.
+ */
+ @Deprecated
+ public ResourceDragSortCursorAdapter(Context context, int layout, Cursor c) {
+ super(context, c);
+ mLayout = mDropDownLayout = layout;
+ mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ /**
+ * Constructor with default behavior as per
+ * {@link CursorAdapter#CursorAdapter(Context, Cursor, boolean)}; it is recommended
+ * you not use this, but instead {@link #ResourceCursorAdapter(Context, int, Cursor, int)}.
+ * When using this constructor, {@link #FLAG_REGISTER_CONTENT_OBSERVER}
+ * will always be set.
+ *
+ * @param context The context where the ListView associated with this adapter is running
+ * @param layout resource identifier of a layout file that defines the views
+ * for this list item. Unless you override them later, this will
+ * define both the item views and the drop down views.
+ * @param c The cursor from which to get the data.
+ * @param autoRequery If true the adapter will call requery() on the
+ * cursor whenever it changes so the most recent
+ * data is always displayed. Using true here is discouraged.
+ */
+ public ResourceDragSortCursorAdapter(Context context, int layout, Cursor c, boolean autoRequery) {
+ super(context, c, autoRequery);
+ mLayout = mDropDownLayout = layout;
+ mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ /**
+ * Standard constructor.
+ *
+ * @param context The context where the ListView associated with this adapter is running
+ * @param layout Resource identifier of a layout file that defines the views
+ * for this list item. Unless you override them later, this will
+ * define both the item views and the drop down views.
+ * @param c The cursor from which to get the data.
+ * @param flags Flags used to determine the behavior of the adapter,
+ * as per {@link CursorAdapter#CursorAdapter(Context, Cursor, int)}.
+ */
+ public ResourceDragSortCursorAdapter(Context context, int layout, Cursor c, int flags) {
+ super(context, c, flags);
+ mLayout = mDropDownLayout = layout;
+ mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ /**
+ * Inflates view(s) from the specified XML file.
+ *
+ * @see android.widget.CursorAdapter#newView(android.content.Context,
+ * android.database.Cursor, ViewGroup)
+ */
+ @Override
+ public View newView(Context context, Cursor cursor, ViewGroup parent) {
+ return mInflater.inflate(mLayout, parent, false);
+ }
+
+ @Override
+ public View newDropDownView(Context context, Cursor cursor, ViewGroup parent) {
+ return mInflater.inflate(mDropDownLayout, parent, false);
+ }
+
+ /**
+ * <p>Sets the layout resource of the item views.</p>
+ *
+ * @param layout the layout resources used to create item views
+ */
+ public void setViewResource(int layout) {
+ mLayout = layout;
+ }
+
+ /**
+ * <p>Sets the layout resource of the drop down views.</p>
+ *
+ * @param dropDownLayout the layout resources used to create drop down views
+ */
+ public void setDropDownViewResource(int dropDownLayout) {
+ mDropDownLayout = dropDownLayout;
+ }
+}
diff --git a/src/com/mobeta/android/dslv/SimpleDragSortCursorAdapter.java b/src/com/mobeta/android/dslv/SimpleDragSortCursorAdapter.java
new file mode 100755
index 0000000..7a76ea9
--- /dev/null
+++ b/src/com/mobeta/android/dslv/SimpleDragSortCursorAdapter.java
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.mobeta.android.dslv;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.ImageView;
+
+// taken from sdk/sources/android-16/android/widget/SimpleCursorAdapter.java
+
+/**
+ * An easy adapter to map columns from a cursor to TextViews or ImageViews
+ * defined in an XML file. You can specify which columns you want, which
+ * views you want to display the columns, and the XML file that defines
+ * the appearance of these views.
+ *
+ * Binding occurs in two phases. First, if a
+ * {@link android.widget.SimpleCursorAdapter.ViewBinder} is available,
+ * {@link ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)}
+ * is invoked. If the returned value is true, binding has occured. If the
+ * returned value is false and the view to bind is a TextView,
+ * {@link #setViewText(TextView, String)} is invoked. If the returned value
+ * is false and the view to bind is an ImageView,
+ * {@link #setViewImage(ImageView, String)} is invoked. If no appropriate
+ * binding can be found, an {@link IllegalStateException} is thrown.
+ *
+ * If this adapter is used with filtering, for instance in an
+ * {@link android.widget.AutoCompleteTextView}, you can use the
+ * {@link android.widget.SimpleCursorAdapter.CursorToStringConverter} and the
+ * {@link android.widget.FilterQueryProvider} interfaces
+ * to get control over the filtering process. You can refer to
+ * {@link #convertToString(android.database.Cursor)} and
+ * {@link #runQueryOnBackgroundThread(CharSequence)} for more information.
+ */
+public class SimpleDragSortCursorAdapter extends ResourceDragSortCursorAdapter {
+ /**
+ * A list of columns containing the data to bind to the UI.
+ * This field should be made private, so it is hidden from the SDK.
+ * {@hide}
+ */
+ protected int[] mFrom;
+ /**
+ * A list of View ids representing the views to which the data must be bound.
+ * This field should be made private, so it is hidden from the SDK.
+ * {@hide}
+ */
+ protected int[] mTo;
+
+ private int mStringConversionColumn = -1;
+ private CursorToStringConverter mCursorToStringConverter;
+ private ViewBinder mViewBinder;
+
+ String[] mOriginalFrom;
+
+ /**
+ * Constructor the enables auto-requery.
+ *
+ * @deprecated This option is discouraged, as it results in Cursor queries
+ * being performed on the application's UI thread and thus can cause poor
+ * responsiveness or even Application Not Responding errors. As an alternative,
+ * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
+ */
+ @Deprecated
+ public SimpleDragSortCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
+ super(context, layout, c);
+ mTo = to;
+ mOriginalFrom = from;
+ findColumns(c, from);
+ }
+
+ /**
+ * Standard constructor.
+ *
+ * @param context The context where the ListView associated with this
+ * SimpleListItemFactory is running
+ * @param layout resource identifier of a layout file that defines the views
+ * for this list item. The layout file should include at least
+ * those named views defined in "to"
+ * @param c The database cursor. Can be null if the cursor is not available yet.
+ * @param from A list of column names representing the data to bind to the UI. Can be null
+ * if the cursor is not available yet.
+ * @param to The views that should display column in the "from" parameter.
+ * These should all be TextViews. The first N views in this list
+ * are given the values of the first N columns in the from
+ * parameter. Can be null if the cursor is not available yet.
+ * @param flags Flags used to determine the behavior of the adapter,
+ * as per {@link CursorAdapter#CursorAdapter(Context, Cursor, int)}.
+ */
+ public SimpleDragSortCursorAdapter(Context context, int layout,
+ Cursor c, String[] from, int[] to, int flags) {
+ super(context, layout, c, flags);
+ mTo = to;
+ mOriginalFrom = from;
+ findColumns(c, from);
+ }
+
+ /**
+ * Binds all of the field names passed into the "to" parameter of the
+ * constructor with their corresponding cursor columns as specified in the
+ * "from" parameter.
+ *
+ * Binding occurs in two phases. First, if a
+ * {@link android.widget.SimpleCursorAdapter.ViewBinder} is available,
+ * {@link ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)}
+ * is invoked. If the returned value is true, binding has occured. If the
+ * returned value is false and the view to bind is a TextView,
+ * {@link #setViewText(TextView, String)} is invoked. If the returned value is
+ * false and the view to bind is an ImageView,
+ * {@link #setViewImage(ImageView, String)} is invoked. If no appropriate
+ * binding can be found, an {@link IllegalStateException} is thrown.
+ *
+ * @throws IllegalStateException if binding cannot occur
+ *
+ * @see android.widget.CursorAdapter#bindView(android.view.View,
+ * android.content.Context, android.database.Cursor)
+ * @see #getViewBinder()
+ * @see #setViewBinder(android.widget.SimpleCursorAdapter.ViewBinder)
+ * @see #setViewImage(ImageView, String)
+ * @see #setViewText(TextView, String)
+ */
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+ final ViewBinder binder = mViewBinder;
+ final int count = mTo.length;
+ final int[] from = mFrom;
+ final int[] to = mTo;
+
+ for (int i = 0; i < count; i++) {
+ final View v = view.findViewById(to[i]);
+ if (v != null) {
+ boolean bound = false;
+ if (binder != null) {
+ bound = binder.setViewValue(v, cursor, from[i]);
+ }
+
+ if (!bound) {
+ String text = cursor.getString(from[i]);
+ if (text == null) {
+ text = "";
+ }
+
+ if (v instanceof TextView) {
+ setViewText((TextView) v, text);
+ } else if (v instanceof ImageView) {
+ setViewImage((ImageView) v, text);
+ } else {
+ throw new IllegalStateException(v.getClass().getName() + " is not a " +
+ " view that can be bounds by this SimpleCursorAdapter");
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the {@link ViewBinder} used to bind data to views.
+ *
+ * @return a ViewBinder or null if the binder does not exist
+ *
+ * @see #bindView(android.view.View, android.content.Context, android.database.Cursor)
+ * @see #setViewBinder(android.widget.SimpleCursorAdapter.ViewBinder)
+ */
+ public ViewBinder getViewBinder() {
+ return mViewBinder;
+ }
+
+ /**
+ * Sets the binder used to bind data to views.
+ *
+ * @param viewBinder the binder used to bind data to views, can be null to
+ * remove the existing binder
+ *
+ * @see #bindView(android.view.View, android.content.Context, android.database.Cursor)
+ * @see #getViewBinder()
+ */
+ public void setViewBinder(ViewBinder viewBinder) {
+ mViewBinder = viewBinder;
+ }
+
+ /**
+ * Called by bindView() to set the image for an ImageView but only if
+ * there is no existing ViewBinder or if the existing ViewBinder cannot
+ * handle binding to an ImageView.
+ *
+ * By default, the value will be treated as an image resource. If the
+ * value cannot be used as an image resource, the value is used as an
+ * image Uri.
+ *
+ * Intended to be overridden by Adapters that need to filter strings
+ * retrieved from the database.
+ *
+ * @param v ImageView to receive an image
+ * @param value the value retrieved from the cursor
+ */
+ public void setViewImage(ImageView v, String value) {
+ try {
+ v.setImageResource(Integer.parseInt(value));
+ } catch (NumberFormatException nfe) {
+ v.setImageURI(Uri.parse(value));
+ }
+ }
+
+ /**
+ * Called by bindView() to set the text for a TextView but only if
+ * there is no existing ViewBinder or if the existing ViewBinder cannot
+ * handle binding to a TextView.
+ *
+ * Intended to be overridden by Adapters that need to filter strings
+ * retrieved from the database.
+ *
+ * @param v TextView to receive text
+ * @param text the text to be set for the TextView
+ */
+ public void setViewText(TextView v, String text) {
+ v.setText(text);
+ }
+
+ /**
+ * Return the index of the column used to get a String representation
+ * of the Cursor.
+ *
+ * @return a valid index in the current Cursor or -1
+ *
+ * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
+ * @see #setStringConversionColumn(int)
+ * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
+ * @see #getCursorToStringConverter()
+ */
+ public int getStringConversionColumn() {
+ return mStringConversionColumn;
+ }
+
+ /**
+ * Defines the index of the column in the Cursor used to get a String
+ * representation of that Cursor. The column is used to convert the
+ * Cursor to a String only when the current CursorToStringConverter
+ * is null.
+ *
+ * @param stringConversionColumn a valid index in the current Cursor or -1 to use the default
+ * conversion mechanism
+ *
+ * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
+ * @see #getStringConversionColumn()
+ * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
+ * @see #getCursorToStringConverter()
+ */
+ public void setStringConversionColumn(int stringConversionColumn) {
+ mStringConversionColumn = stringConversionColumn;
+ }
+
+ /**
+ * Returns the converter used to convert the filtering Cursor
+ * into a String.
+ *
+ * @return null if the converter does not exist or an instance of
+ * {@link android.widget.SimpleCursorAdapter.CursorToStringConverter}
+ *
+ * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
+ * @see #getStringConversionColumn()
+ * @see #setStringConversionColumn(int)
+ * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
+ */
+ public CursorToStringConverter getCursorToStringConverter() {
+ return mCursorToStringConverter;
+ }
+
+ /**
+ * Sets the converter used to convert the filtering Cursor
+ * into a String.
+ *
+ * @param cursorToStringConverter the Cursor to String converter, or
+ * null to remove the converter
+ *
+ * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
+ * @see #getStringConversionColumn()
+ * @see #setStringConversionColumn(int)
+ * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
+ */
+ public void setCursorToStringConverter(CursorToStringConverter cursorToStringConverter) {
+ mCursorToStringConverter = cursorToStringConverter;
+ }
+
+ /**
+ * Returns a CharSequence representation of the specified Cursor as defined
+ * by the current CursorToStringConverter. If no CursorToStringConverter
+ * has been set, the String conversion column is used instead. If the
+ * conversion column is -1, the returned String is empty if the cursor
+ * is null or Cursor.toString().
+ *
+ * @param cursor the Cursor to convert to a CharSequence
+ *
+ * @return a non-null CharSequence representing the cursor
+ */
+ @Override
+ public CharSequence convertToString(Cursor cursor) {
+ if (mCursorToStringConverter != null) {
+ return mCursorToStringConverter.convertToString(cursor);
+ } else if (mStringConversionColumn > -1) {
+ return cursor.getString(mStringConversionColumn);
+ }
+
+ return super.convertToString(cursor);
+ }
+
+ /**
+ * Create a map from an array of strings to an array of column-id integers in cursor c.
+ * If c is null, the array will be discarded.
+ *
+ * @param c the cursor to find the columns from
+ * @param from the Strings naming the columns of interest
+ */
+ private void findColumns(Cursor c, String[] from) {
+ if (c != null) {
+ int i;
+ int count = from.length;
+ if (mFrom == null || mFrom.length != count) {
+ mFrom = new int[count];
+ }
+ for (i = 0; i < count; i++) {
+ mFrom[i] = c.getColumnIndexOrThrow(from[i]);
+ }
+ } else {
+ mFrom = null;
+ }
+ }
+
+ @Override
+ public Cursor swapCursor(Cursor c) {
+ // super.swapCursor() will notify observers before we have
+ // a valid mapping, make sure we have a mapping before this
+ // happens
+ findColumns(c, mOriginalFrom);
+ return super.swapCursor(c);
+ }
+
+ /**
+ * Change the cursor and change the column-to-view mappings at the same time.
+ *
+ * @param c The database cursor. Can be null if the cursor is not available yet.
+ * @param from A list of column names representing the data to bind to the UI. Can be null
+ * if the cursor is not available yet.
+ * @param to The views that should display column in the "from" parameter.
+ * These should all be TextViews. The first N views in this list
+ * are given the values of the first N columns in the from
+ * parameter. Can be null if the cursor is not available yet.
+ */
+ public void changeCursorAndColumns(Cursor c, String[] from, int[] to) {
+ mOriginalFrom = from;
+ mTo = to;
+ // super.changeCursor() will notify observers before we have
+ // a valid mapping, make sure we have a mapping before this
+ // happens
+ findColumns(c, mOriginalFrom);
+ super.changeCursor(c);
+ }
+
+ /**
+ * This class can be used by external clients of SimpleCursorAdapter
+ * to bind values fom the Cursor to views.
+ *
+ * You should use this class to bind values from the Cursor to views
+ * that are not directly supported by SimpleCursorAdapter or to
+ * change the way binding occurs for views supported by
+ * SimpleCursorAdapter.
+ *
+ * @see SimpleCursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor)
+ * @see SimpleCursorAdapter#setViewImage(ImageView, String)
+ * @see SimpleCursorAdapter#setViewText(TextView, String)
+ */
+ public static interface ViewBinder {
+ /**
+ * Binds the Cursor column defined by the specified index to the specified view.
+ *
+ * When binding is handled by this ViewBinder, this method must return true.
+ * If this method returns false, SimpleCursorAdapter will attempts to handle
+ * the binding on its own.
+ *
+ * @param view the view to bind the data to
+ * @param cursor the cursor to get the data from
+ * @param columnIndex the column at which the data can be found in the cursor
+ *
+ * @return true if the data was bound to the view, false otherwise
+ */
+ boolean setViewValue(View view, Cursor cursor, int columnIndex);
+ }
+
+ /**
+ * This class can be used by external clients of SimpleCursorAdapter
+ * to define how the Cursor should be converted to a String.
+ *
+ * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
+ */
+ public static interface CursorToStringConverter {
+ /**
+ * Returns a CharSequence representing the specified Cursor.
+ *
+ * @param cursor the cursor for which a CharSequence representation
+ * is requested
+ *
+ * @return a non-null CharSequence representing the cursor
+ */
+ CharSequence convertToString(Cursor cursor);
+ }
+
+}
diff --git a/src/com/mobeta/android/dslv/SimpleFloatViewManager.java b/src/com/mobeta/android/dslv/SimpleFloatViewManager.java
new file mode 100755
index 0000000..272186f
--- /dev/null
+++ b/src/com/mobeta/android/dslv/SimpleFloatViewManager.java
@@ -0,0 +1,88 @@
+package com.mobeta.android.dslv;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ListView;
+
+/**
+ * Simple implementation of the FloatViewManager class. Uses list
+ * items as they appear in the ListView to create the floating View.
+ */
+public class SimpleFloatViewManager implements DragSortListView.FloatViewManager {
+
+ private Bitmap mFloatBitmap;
+
+ private ImageView mImageView;
+
+ private int mFloatBGColor = Color.BLACK;
+
+ private ListView mListView;
+
+ public SimpleFloatViewManager(ListView lv) {
+ mListView = lv;
+ }
+
+ public void setBackgroundColor(int color) {
+ mFloatBGColor = color;
+ }
+
+ /**
+ * This simple implementation creates a Bitmap copy of the
+ * list item currently shown at ListView <code>position</code>.
+ */
+ @Override
+ public View onCreateFloatView(int position) {
+ // Guaranteed that this will not be null? I think so. Nope, got
+ // a NullPointerException once...
+ View v = mListView.getChildAt(position + mListView.getHeaderViewsCount() - mListView.getFirstVisiblePosition());
+
+ if (v == null) {
+ return null;
+ }
+
+ v.setPressed(false);
+
+ // Create a copy of the drawing cache so that it does not get
+ // recycled by the framework when the list tries to clean up memory
+ //v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
+ v.setDrawingCacheEnabled(true);
+ mFloatBitmap = Bitmap.createBitmap(v.getDrawingCache());
+ v.setDrawingCacheEnabled(false);
+
+ if (mImageView == null) {
+ mImageView = new ImageView(mListView.getContext());
+ }
+ mImageView.setBackgroundColor(mFloatBGColor);
+ mImageView.setPadding(0, 0, 0, 0);
+ mImageView.setImageBitmap(mFloatBitmap);
+ mImageView.setLayoutParams(new ViewGroup.LayoutParams(v.getWidth(), v.getHeight()));
+
+ return mImageView;
+ }
+
+ /**
+ * This does nothing
+ */
+ @Override
+ public void onDragFloatView(View floatView, Point position, Point touch) {
+ // do nothing
+ }
+
+ /**
+ * Removes the Bitmap from the ImageView created in
+ * onCreateFloatView() and tells the system to recycle it.
+ */
+ @Override
+ public void onDestroyFloatView(View floatView) {
+ ((ImageView) floatView).setImageDrawable(null);
+
+ mFloatBitmap.recycle();
+ mFloatBitmap = null;
+ }
+
+}
+
diff --git a/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerDialog.java b/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerDialog.java
new file mode 100755
index 0000000..b060eb6
--- /dev/null
+++ b/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerDialog.java
@@ -0,0 +1,208 @@
+package it.gmariotti.android.example.colorpicker.calendarstock;
+
+/*
+ * Copyright (C) 2013 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.
+ *
+ * You can find source here:
+ * https://android.googlesource.com/platform/frameworks/opt/colorpicker/+/master/src/com/android/colorpicker
+ */
+
+
+import com.dsht.kerneltweaker.R;
+
+import it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerSwatch.OnColorSelectedListener;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ProgressBar;
+
+
+
+/**
+ * A dialog which takes in as input an array of colors and creates a palette allowing the user to
+ * select a specific color swatch, which invokes a listener.
+ */
+public class ColorPickerDialog extends DialogFragment implements OnColorSelectedListener {
+
+ public static final int SIZE_LARGE = 1;
+ public static final int SIZE_SMALL = 2;
+
+ protected AlertDialog mAlertDialog;
+
+ protected static final String KEY_TITLE_ID = "title_id";
+ protected static final String KEY_COLORS = "colors";
+ protected static final String KEY_SELECTED_COLOR = "selected_color";
+ protected static final String KEY_COLUMNS = "columns";
+ protected static final String KEY_SIZE = "size";
+
+ protected int mTitleResId = R.string.color_picker_default_title;
+ protected int[] mColors = null;
+ protected int mSelectedColor;
+ protected int mColumns;
+ protected int mSize;
+
+ private ColorPickerPalette mPalette;
+ private ProgressBar mProgress;
+
+ protected OnColorSelectedListener mListener;
+
+ public ColorPickerDialog() {
+ // Empty constructor required for dialog fragments.
+ }
+
+ public static ColorPickerDialog newInstance(int titleResId, int[] colors, int selectedColor,
+ int columns, int size) {
+ ColorPickerDialog ret = new ColorPickerDialog();
+ ret.initialize(titleResId, colors, selectedColor, columns, size);
+ return ret;
+ }
+
+ public void initialize(int titleResId, int[] colors, int selectedColor, int columns, int size) {
+ setArguments(titleResId, columns, size);
+ setColors(colors, selectedColor);
+ }
+
+ public void setArguments(int titleResId, int columns, int size) {
+ Bundle bundle = new Bundle();
+ bundle.putInt(KEY_TITLE_ID, titleResId);
+ bundle.putInt(KEY_COLUMNS, columns);
+ bundle.putInt(KEY_SIZE, size);
+ setArguments(bundle);
+ }
+
+ public void setOnColorSelectedListener(OnColorSelectedListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (getArguments() != null) {
+ mTitleResId = getArguments().getInt(KEY_TITLE_ID);
+ mColumns = getArguments().getInt(KEY_COLUMNS);
+ mSize = getArguments().getInt(KEY_SIZE);
+ }
+
+ if (savedInstanceState != null) {
+ mColors = savedInstanceState.getIntArray(KEY_COLORS);
+ mSelectedColor = (Integer) savedInstanceState.getSerializable(KEY_SELECTED_COLOR);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Activity activity = getActivity();
+
+ View view = LayoutInflater.from(getActivity()).inflate(R.layout.calendar_color_picker_dialog, null);
+ mProgress = (ProgressBar) view.findViewById(android.R.id.progress);
+ mPalette = (ColorPickerPalette) view.findViewById(R.id.color_picker);
+ mPalette.init(mSize, mColumns, this);
+
+ if (mColors != null) {
+ showPaletteView();
+ }
+
+ mAlertDialog = new AlertDialog.Builder(activity)
+ .setTitle(mTitleResId)
+ .setView(view)
+ .create();
+
+ return mAlertDialog;
+ }
+
+ @Override
+ public void onColorSelected(int color) {
+ if (mListener != null) {
+ mListener.onColorSelected(color);
+ }
+
+ if (getTargetFragment() instanceof OnColorSelectedListener) {
+ final OnColorSelectedListener listener =
+ (OnColorSelectedListener) getTargetFragment();
+ listener.onColorSelected(color);
+ }
+
+ if (color != mSelectedColor) {
+ mSelectedColor = color;
+ // Redraw palette to show checkmark on newly selected color before dismissing.
+ mPalette.drawPalette(mColors, mSelectedColor);
+ }
+
+ dismiss();
+ }
+
+ public void showPaletteView() {
+ if (mProgress != null && mPalette != null) {
+ mProgress.setVisibility(View.GONE);
+ refreshPalette();
+ mPalette.setVisibility(View.VISIBLE);
+ }
+ }
+
+ public void showProgressBarView() {
+ if (mProgress != null && mPalette != null) {
+ mProgress.setVisibility(View.VISIBLE);
+ mPalette.setVisibility(View.GONE);
+ }
+ }
+
+ public void setColors(int[] colors, int selectedColor) {
+ if (mColors != colors || mSelectedColor != selectedColor) {
+ mColors = colors;
+ mSelectedColor = selectedColor;
+ refreshPalette();
+ }
+ }
+
+ public void setColors(int[] colors) {
+ if (mColors != colors) {
+ mColors = colors;
+ refreshPalette();
+ }
+ }
+
+ public void setSelectedColor(int color) {
+ if (mSelectedColor != color) {
+ mSelectedColor = color;
+ refreshPalette();
+ }
+ }
+
+ private void refreshPalette() {
+ if (mPalette != null && mColors != null) {
+ mPalette.drawPalette(mColors, mSelectedColor);
+ }
+ }
+
+ public int[] getColors() {
+ return mColors;
+ }
+
+ public int getSelectedColor() {
+ return mSelectedColor;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putIntArray(KEY_COLORS, mColors);
+ outState.putSerializable(KEY_SELECTED_COLOR, mSelectedColor);
+ }
+} \ No newline at end of file
diff --git a/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerPalette.java b/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerPalette.java
new file mode 100755
index 0000000..4b2a6d1
--- /dev/null
+++ b/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerPalette.java
@@ -0,0 +1,193 @@
+package it.gmariotti.android.example.colorpicker.calendarstock;
+
+/*
+ * Copyright (C) 2013 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.
+ *
+ * You can find source here:
+ * https://android.googlesource.com/platform/frameworks/opt/colorpicker/+/master/src/com/android/colorpicker
+ */
+
+
+
+
+import com.dsht.kerneltweaker.R;
+
+import it.gmariotti.android.example.colorpicker.calendarstock.ColorPickerSwatch.OnColorSelectedListener;
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+
+
+
+/**
+ * A color picker custom view which creates an grid of color squares. The number of squares per
+ * row (and the padding between the squares) is determined by the user.
+ */
+public class ColorPickerPalette extends TableLayout {
+
+ public OnColorSelectedListener mOnColorSelectedListener;
+
+ private String mDescription;
+ private String mDescriptionSelected;
+
+ private int mSwatchLength;
+ private int mMarginSize;
+ private int mNumColumns;
+
+ public ColorPickerPalette(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ColorPickerPalette(Context context) {
+ super(context);
+ }
+
+ /**
+ * Initialize the size, columns, and listener. Size should be a pre-defined size (SIZE_LARGE
+ * or SIZE_SMALL) from ColorPickerDialogFragment.
+ */
+ public void init(int size, int columns, OnColorSelectedListener listener) {
+ mNumColumns = columns;
+ Resources res = getResources();
+ if (size == ColorPickerDialog.SIZE_LARGE) {
+ mSwatchLength = res.getDimensionPixelSize(R.dimen.color_swatch_large);
+ mMarginSize = res.getDimensionPixelSize(R.dimen.color_swatch_margins_large);
+ } else {
+ mSwatchLength = res.getDimensionPixelSize(R.dimen.color_swatch_small);
+ mMarginSize = res.getDimensionPixelSize(R.dimen.color_swatch_margins_small);
+ }
+ mOnColorSelectedListener = listener;
+
+ mDescription = res.getString(R.string.color_swatch_description);
+ mDescriptionSelected = res.getString(R.string.color_swatch_description_selected);
+ }
+
+ private TableRow createTableRow() {
+ TableRow row = new TableRow(getContext());
+ ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT);
+ row.setLayoutParams(params);
+ return row;
+ }
+
+ /**
+ * Adds swatches to table in a serpentine format.
+ */
+ public void drawPalette(int[] colors, int selectedColor) {
+ if (colors == null) {
+ return;
+ }
+
+ this.removeAllViews();
+ int tableElements = 0;
+ int rowElements = 0;
+ int rowNumber = 0;
+
+ // Fills the table with swatches based on the array of colors.
+ TableRow row = createTableRow();
+ for (int color : colors) {
+ tableElements++;
+
+ View colorSwatch = createColorSwatch(color, selectedColor);
+ setSwatchDescription(rowNumber, tableElements, rowElements, color == selectedColor,
+ colorSwatch);
+ addSwatchToRow(row, colorSwatch, rowNumber);
+
+ rowElements++;
+ if (rowElements == mNumColumns) {
+ addView(row);
+ row = createTableRow();
+ rowElements = 0;
+ rowNumber++;
+ }
+ }
+
+ // Create blank views to fill the row if the last row has not been filled.
+ if (rowElements > 0) {
+ while (rowElements != mNumColumns) {
+ addSwatchToRow(row, createBlankSpace(), rowNumber);
+ rowElements++;
+ }
+ addView(row);
+ }
+ }
+
+ /**
+ * Appends a swatch to the end of the row for even-numbered rows (starting with row 0),
+ * to the beginning of a row for odd-numbered rows.
+ */
+ private void addSwatchToRow(TableRow row, View swatch, int rowNumber) {
+ if (rowNumber % 2 == 0) {
+ row.addView(swatch);
+ } else {
+ row.addView(swatch, 0);
+ }
+ }
+
+ /**
+ * Add a content description to the specified swatch view. Because the colors get added in a
+ * snaking form, every other row will need to compensate for the fact that the colors are added
+ * in an opposite direction from their left->right/top->bottom order, which is how the system
+ * will arrange them for accessibility purposes.
+ */
+ private void setSwatchDescription(int rowNumber, int index, int rowElements, boolean selected,
+ View swatch) {
+ int accessibilityIndex;
+ if (rowNumber % 2 == 0) {
+ // We're in a regular-ordered row
+ accessibilityIndex = index;
+ } else {
+ // We're in a backwards-ordered row.
+ int rowMax = ((rowNumber + 1) * mNumColumns);
+ accessibilityIndex = rowMax - rowElements;
+ }
+
+ String description;
+ if (selected) {
+ description = String.format(mDescriptionSelected, accessibilityIndex);
+ } else {
+ description = String.format(mDescription, accessibilityIndex);
+ }
+ swatch.setContentDescription(description);
+ }
+
+ /**
+ * Creates a blank space to fill the row.
+ */
+ private ImageView createBlankSpace() {
+ ImageView view = new ImageView(getContext());
+ TableRow.LayoutParams params = new TableRow.LayoutParams(mSwatchLength, mSwatchLength);
+ params.setMargins(mMarginSize, mMarginSize, mMarginSize, mMarginSize);
+ view.setLayoutParams(params);
+ return view;
+ }
+
+ /**
+ * Creates a color swatch.
+ */
+ private ColorPickerSwatch createColorSwatch(int color, int selectedColor) {
+ ColorPickerSwatch view = new ColorPickerSwatch(getContext(), color,
+ color == selectedColor, mOnColorSelectedListener);
+ TableRow.LayoutParams params = new TableRow.LayoutParams(mSwatchLength, mSwatchLength);
+ params.setMargins(mMarginSize, mMarginSize, mMarginSize, mMarginSize);
+ view.setLayoutParams(params);
+ return view;
+ }
+} \ No newline at end of file
diff --git a/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerPreference.java b/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerPreference.java
new file mode 100755
index 0000000..8cbaa7b
--- /dev/null
+++ b/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerPreference.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * Copyright 2013 Gabriele Mariotti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+package it.gmariotti.android.example.colorpicker.calendarstock;
+
+import com.dsht.kerneltweaker.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * ColorPreference based on ColorPickerDialog of Stock Calendar
+ *
+ * @author Gabriele Mariotti (gabri.mariotti@gmail.com)
+ *
+ */
+public class ColorPickerPreference extends Preference{
+
+ private int[] mColorChoices = {};
+ private int mValue = 0;
+ private int mItemLayoutId = R.layout.calendar_grid_item_color;
+ private int mNumColumns = 5;
+ private View mPreviewView;
+
+ public ColorPickerPreference(Context context) {
+ super(context);
+ initAttrs(null, 0);
+ }
+
+ public ColorPickerPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initAttrs(attrs, 0);
+ }
+
+ public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initAttrs(attrs, defStyle);
+ }
+
+ private void initAttrs(AttributeSet attrs, int defStyle) {
+ TypedArray a = getContext().getTheme().obtainStyledAttributes(
+ attrs, R.styleable.ColorPickerPreference, defStyle, defStyle);
+
+ try {
+ mItemLayoutId = a.getResourceId(R.styleable.ColorPickerPreference_cal_itemLayout, mItemLayoutId);
+ mNumColumns = a.getInteger(R.styleable.ColorPickerPreference_cal_numColumns, mNumColumns);
+ int choicesResId = a.getResourceId(R.styleable.ColorPickerPreference_cal_choices,
+ R.array.default_color_choice_values);
+ if (choicesResId > 0) {
+ String[] choices = a.getResources().getStringArray(choicesResId);
+ mColorChoices = new int[choices.length];
+ for (int i = 0; i < choices.length; i++) {
+ mColorChoices[i] = Color.parseColor(choices[i]);
+ }
+ }
+
+ } finally {
+ a.recycle();
+ }
+ setWidgetLayoutResource(mItemLayoutId);
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+ mPreviewView = view.findViewById(R.id.calendar_color_view);
+ setColorViewValue(mPreviewView, mValue);
+ }
+
+ public void setValue(int value) {
+ if (callChangeListener(value)) {
+ mValue = value;
+ persistInt(value);
+ notifyChanged();
+ }
+ }
+
+ @Override
+ protected void onClick() {
+ super.onClick();
+
+ ColorPickerDialog colorcalendar = (ColorPickerDialog) ColorPickerDialog.newInstance(R.string.color_picker_default_title,
+ mColorChoices, getValue(), mNumColumns, Utils.isTablet(getContext())? ColorPickerDialog.SIZE_LARGE : ColorPickerDialog.SIZE_SMALL);
+
+ //colorcalendar.setPreference(this);
+
+ Activity activity = (Activity) getContext();
+ activity.getFragmentManager().beginTransaction()
+ .add(colorcalendar, getFragmentTag())
+ .commit();
+
+ colorcalendar.setOnColorSelectedListener(listener);
+ }
+
+ /**
+ * Implement listener to get selected color value
+ */
+ ColorPickerSwatch.OnColorSelectedListener listener = new ColorPickerSwatch.OnColorSelectedListener() {
+
+ @Override
+ public void onColorSelected(int color) {
+ setValue(color);
+ }
+ };
+
+ @Override
+ protected void onAttachedToActivity() {
+ super.onAttachedToActivity();
+
+ Activity activity = (Activity) getContext();
+ ColorPickerDialog colorcalendar = (ColorPickerDialog) activity
+ .getFragmentManager().findFragmentByTag(getFragmentTag());
+ if (colorcalendar != null) {
+ // re-bind listener to fragment
+ colorcalendar.setOnColorSelectedListener(listener);
+ }
+ }
+
+ @Override
+ protected Object onGetDefaultValue(TypedArray a, int index) {
+ return a.getInt(index, 0);
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setValue(restoreValue ? getPersistedInt(0) : (Integer) defaultValue);
+ }
+
+ public String getFragmentTag() {
+ return "color_" + getKey();
+ }
+
+ public int getValue() {
+ return mValue;
+ }
+
+ private static void setColorViewValue(View view, int color) {
+ if (view instanceof ImageView) {
+ ImageView imageView = (ImageView) view;
+ Resources res = imageView.getContext().getResources();
+
+ Drawable currentDrawable = imageView.getDrawable();
+ GradientDrawable colorChoiceDrawable;
+ if (currentDrawable != null && currentDrawable instanceof GradientDrawable) {
+ // Reuse drawable
+ colorChoiceDrawable = (GradientDrawable) currentDrawable;
+ } else {
+ colorChoiceDrawable = new GradientDrawable();
+ colorChoiceDrawable.setShape(GradientDrawable.OVAL);
+ }
+
+ // Set stroke to dark version of color
+ int darkenedColor = Color.rgb(
+ Color.red(color) * 192 / 256,
+ Color.green(color) * 192 / 256,
+ Color.blue(color) * 192 / 256);
+
+ colorChoiceDrawable.setColor(color);
+ colorChoiceDrawable.setStroke((int) TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP, 1, res.getDisplayMetrics()), darkenedColor);
+ imageView.setImageDrawable(colorChoiceDrawable);
+
+ } else if (view instanceof TextView) {
+ ((TextView) view).setTextColor(color);
+ }
+ }
+
+
+}
diff --git a/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerSwatch.java b/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerSwatch.java
new file mode 100755
index 0000000..9416aaf
--- /dev/null
+++ b/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorPickerSwatch.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2013 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.
+ *
+ * You can find source here:
+ * https://android.googlesource.com/platform/frameworks/opt/colorpicker/+/master/src/com/android/colorpicker
+ */
+
+package it.gmariotti.android.example.colorpicker.calendarstock;
+
+import com.dsht.kerneltweaker.R;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+/**
+ * Creates a circular swatch of a specified color. Adds a checkmark if marked as checked.
+ */
+public class ColorPickerSwatch extends FrameLayout implements View.OnClickListener {
+ private int mColor;
+ private ImageView mSwatchImage;
+ private ImageView mCheckmarkImage;
+ private OnColorSelectedListener mOnColorSelectedListener;
+
+ /**
+ * Interface for a callback when a color square is selected.
+ */
+ public interface OnColorSelectedListener {
+
+ /**
+ * Called when a specific color square has been selected.
+ */
+ public void onColorSelected(int color);
+ }
+
+ public ColorPickerSwatch(Context context, int color, boolean checked,
+ OnColorSelectedListener listener) {
+ super(context);
+ mColor = color;
+ mOnColorSelectedListener = listener;
+
+ LayoutInflater.from(context).inflate(R.layout.calendar_color_picker_swatch, this);
+ mSwatchImage = (ImageView) findViewById(R.id.color_picker_swatch);
+ mCheckmarkImage = (ImageView) findViewById(R.id.color_picker_checkmark);
+ setColor(color);
+ setChecked(checked);
+ setOnClickListener(this);
+ }
+
+ protected void setColor(int color) {
+ Drawable[] colorDrawable = new Drawable[]
+ {getContext().getResources().getDrawable(R.drawable.calendar_color_picker_swatch)};
+ mSwatchImage.setImageDrawable(new ColorStateDrawable(colorDrawable, color));
+ }
+
+ private void setChecked(boolean checked) {
+ if (checked) {
+ mCheckmarkImage.setVisibility(View.VISIBLE);
+ } else {
+ mCheckmarkImage.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (mOnColorSelectedListener != null) {
+ mOnColorSelectedListener.onColorSelected(mColor);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorStateDrawable.java b/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorStateDrawable.java
new file mode 100755
index 0000000..84d2b40
--- /dev/null
+++ b/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorStateDrawable.java
@@ -0,0 +1,76 @@
+package it.gmariotti.android.example.colorpicker.calendarstock;
+
+/*
+ * Copyright (C) 2013 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.
+ *
+ * You can find source here:
+ * https://android.googlesource.com/platform/frameworks/opt/colorpicker/+/master/src/com/android/colorpicker
+ */
+
+
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+
+/**
+ * A drawable which sets its color filter to a color specified by the user, and changes to a
+ * slightly darker color when pressed or focused.
+ */
+public class ColorStateDrawable extends LayerDrawable {
+
+ private static final float PRESSED_STATE_MULTIPLIER = 0.70f;
+
+ private int mColor;
+
+ public ColorStateDrawable(Drawable[] layers, int color) {
+ super(layers);
+ mColor = color;
+ }
+
+ @Override
+ protected boolean onStateChange(int[] states) {
+ boolean pressedOrFocused = false;
+ for (int state : states) {
+ if (state == android.R.attr.state_pressed || state == android.R.attr.state_focused) {
+ pressedOrFocused = true;
+ break;
+ }
+ }
+
+ if (pressedOrFocused) {
+ super.setColorFilter(getPressedColor(mColor), PorterDuff.Mode.SRC_ATOP);
+ } else {
+ super.setColorFilter(mColor, PorterDuff.Mode.SRC_ATOP);
+ }
+
+ return super.onStateChange(states);
+ }
+
+ /**
+ * Given a particular color, adjusts its value by a multiplier.
+ */
+ private int getPressedColor(int color) {
+ float[] hsv = new float[3];
+ Color.colorToHSV(color, hsv);
+ hsv[2] = hsv[2] * PRESSED_STATE_MULTIPLIER;
+ return Color.HSVToColor(hsv);
+ }
+
+ @Override
+ public boolean isStateful() {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/src/it/gmariotti/android/example/colorpicker/calendarstock/Utils.java b/src/it/gmariotti/android/example/colorpicker/calendarstock/Utils.java
new file mode 100755
index 0000000..4ba007a
--- /dev/null
+++ b/src/it/gmariotti/android/example/colorpicker/calendarstock/Utils.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright 2013 Gabriele Mariotti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+package it.gmariotti.android.example.colorpicker.calendarstock;
+
+import com.dsht.kerneltweaker.R;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.Html;
+import android.text.SpannableStringBuilder;
+import android.text.method.LinkMovementMethod;
+import android.view.LayoutInflater;
+import android.widget.TextView;
+
+/**
+ *
+ * @author Gabriele Mariotti (gabri.mariotti@gmail.com)
+ *
+ */
+public class Utils {
+
+
+ /**
+ * Utility class for colors
+ *
+ * @author Gabriele Mariotti (gabri.mariotti@gmail.com)
+ *
+ */
+ public static class ColorUtils{
+
+ /**
+ * Create an array of int with colors
+ *
+ * @param context
+ * @return
+ */
+ public static int[] colorChoice(Context context){
+
+ int[] mColorChoices=null;
+ String[] color_array = context.getResources().getStringArray(R.array.default_color_choice_values);
+
+ if (color_array!=null && color_array.length>0) {
+ mColorChoices = new int[color_array.length];
+ for (int i = 0; i < color_array.length; i++) {
+ mColorChoices[i] = Color.parseColor(color_array[i]);
+ }
+ }
+ return mColorChoices;
+ }
+
+ /**
+ * Parse whiteColor
+ *
+ * @return
+ */
+ public static int parseWhiteColor(){
+ return Color.parseColor("#FFFFFF");
+ }
+
+ }
+
+ public static boolean isTablet(Context context) {
+ return (context.getResources().getConfiguration().screenLayout
+ & Configuration.SCREENLAYOUT_SIZE_MASK)
+ >= Configuration.SCREENLAYOUT_SIZE_LARGE;
+ }
+
+ public static void showAbout(Activity activity) {
+
+ FragmentManager fm = activity.getFragmentManager();
+ FragmentTransaction ft = fm.beginTransaction();
+ Fragment prev = fm.findFragmentByTag("dialog_about");
+ if (prev != null) {
+ ft.remove(prev);
+ }
+ ft.addToBackStack(null);
+
+ new AboutDialog().show(ft,"dialog_about");
+ }
+
+ /**
+ * About Dialog
+ */
+ public static class AboutDialog extends DialogFragment {
+
+ private static final String VERSION_UNAVAILABLE = "N/A";
+
+ public AboutDialog() {
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Get app version
+ PackageManager pm = getActivity().getPackageManager();
+ String packageName = getActivity().getPackageName();
+ String versionName;
+ try {
+ PackageInfo info = pm.getPackageInfo(packageName, 0);
+ versionName = info.versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ versionName = VERSION_UNAVAILABLE;
+ }
+
+ // Build the about body view and append the link to see OSS licenses
+ SpannableStringBuilder aboutBody = new SpannableStringBuilder();
+ aboutBody.append(Html.fromHtml(getString(R.string.about_body, versionName)));
+
+
+ LayoutInflater layoutInflater = (LayoutInflater) getActivity().getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ TextView aboutBodyView = (TextView) layoutInflater.inflate(R.layout.dialog_about, null);
+ aboutBodyView.setText(aboutBody);
+ aboutBodyView.setMovementMethod(new LinkMovementMethod());
+
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.title_about)
+ .setView(aboutBodyView)
+ .setPositiveButton(R.string.about_ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ dialog.dismiss();
+ }
+ }
+ )
+ .create();
+ }
+ }
+}