From 32b080261845c7508581f9c452d48ffd2401c450 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Fri, 2 Aug 2019 12:50:57 +0200 Subject: Add skeleton build variant --- main/src/main/AndroidManifest.xml | 20 - main/src/main/cpp/CMakeLists.txt | 23 +- main/src/main/cpp/openssl.cmake | 6 +- .../support/v4n/app/FragmentStatePagerAdapter.java | 232 -- .../android/support/v4n/view/PagerAdapter.java | 320 --- .../java/android/support/v4n/view/ViewPager.java | 2895 -------------------- .../java/de/blinkt/openvpn/OpenVPNTileService.java | 151 - .../de/blinkt/openvpn/activities/BaseActivity.java | 43 - .../blinkt/openvpn/activities/ConfigConverter.java | 847 ------ .../blinkt/openvpn/activities/CreateShortcuts.java | 159 -- .../de/blinkt/openvpn/activities/FileSelect.java | 257 -- .../de/blinkt/openvpn/activities/LogWindow.java | 37 - .../de/blinkt/openvpn/activities/MainActivity.java | 131 - .../de/blinkt/openvpn/activities/OpenSSLSpeed.java | 193 -- .../blinkt/openvpn/activities/VPNPreferences.java | 245 -- .../blinkt/openvpn/core/ICSOpenVPNApplication.java | 6 - .../java/de/blinkt/openvpn/core/NativeUtils.java | 4 + .../de/blinkt/openvpn/fragments/AboutFragment.java | 333 --- .../openvpn/fragments/ConnectionsAdapter.java | 413 --- .../de/blinkt/openvpn/fragments/FaqFragment.java | 216 -- .../blinkt/openvpn/fragments/FaqViewAdapter.java | 132 - .../openvpn/fragments/FileSelectionFragment.java | 325 --- .../blinkt/openvpn/fragments/GeneralSettings.java | 190 -- .../de/blinkt/openvpn/fragments/GraphFragment.java | 400 --- .../de/blinkt/openvpn/fragments/InlineFileTab.java | 70 - .../openvpn/fragments/KeyChainSettingsFragment.kt | 262 -- .../de/blinkt/openvpn/fragments/LogFragment.java | 694 ----- .../fragments/OpenVpnPreferencesFragment.java | 53 - .../blinkt/openvpn/fragments/SendDumpFragment.java | 128 - .../openvpn/fragments/Settings_Allowed_Apps.kt | 323 --- .../openvpn/fragments/Settings_Authentication.java | 238 -- .../blinkt/openvpn/fragments/Settings_Basic.java | 227 -- .../openvpn/fragments/Settings_Connections.java | 101 - .../openvpn/fragments/Settings_Fragment.java | 35 - .../de/blinkt/openvpn/fragments/Settings_IP.java | 137 - .../blinkt/openvpn/fragments/Settings_Obscure.java | 212 -- .../blinkt/openvpn/fragments/Settings_Routing.java | 109 - .../openvpn/fragments/Settings_UserEditable.java | 63 - .../openvpn/fragments/ShowConfigFragment.java | 134 - .../java/de/blinkt/openvpn/fragments/Utils.java | 288 -- .../blinkt/openvpn/fragments/VPNProfileList.java | 636 ----- .../openvpn/views/DefaultVPNListPreference.java | 39 - .../de/blinkt/openvpn/views/FileSelectLayout.java | 189 -- .../blinkt/openvpn/views/MultiLineRadioGroup.java | 164 -- .../blinkt/openvpn/views/PagerSlidingTabStrip.java | 732 ----- .../blinkt/openvpn/views/RemoteCNPreference.java | 146 - .../openvpn/views/ScreenSlidePagerAdapter.java | 79 - .../java/de/blinkt/openvpn/views/SeekBarTicks.java | 73 - .../de/blinkt/openvpn/views/SlidingTabLayout.java | 314 --- .../de/blinkt/openvpn/views/SlidingTabStrip.java | 207 -- .../java/de/blinkt/openvpn/views/TabBarView.java | 16 - main/src/main/res/anim/fab_anim.xml | 23 - .../ic_add_circle_outline_grey600_24dp.png | Bin 624 -> 0 bytes .../ic_add_circle_outline_white_24dp.png | Bin 606 -> 0 bytes .../res/drawable-hdpi/ic_archive_grey600_24dp.png | Bin 353 -> 0 bytes .../res/drawable-hdpi/ic_archive_white_24dp.png | Bin 347 -> 0 bytes .../main/res/drawable-hdpi/ic_check_white_24dp.png | Bin 309 -> 0 bytes .../main/res/drawable-hdpi/ic_close_white_24dp.png | Bin 221 -> 0 bytes .../drawable-hdpi/ic_content_copy_white_24dp.png | Bin 287 -> 0 bytes .../res/drawable-hdpi/ic_delete_grey600_24dp.png | Bin 248 -> 0 bytes .../res/drawable-hdpi/ic_delete_white_24dp.png | Bin 246 -> 0 bytes .../main/res/drawable-hdpi/ic_doc_generic_am.png | Bin 694 -> 0 bytes .../res/drawable-hdpi/ic_edit_grey600_24dp.png | Bin 341 -> 0 bytes .../main/res/drawable-hdpi/ic_edit_white_24dp.png | Bin 339 -> 0 bytes .../drawable-hdpi/ic_filter_list_white_24dp.png | Bin 206 -> 0 bytes .../res/drawable-hdpi/ic_menu_copy_holo_dark.png | Bin 186 -> 0 bytes .../main/res/drawable-hdpi/ic_pause_white_24dp.png | Bin 105 -> 0 bytes .../res/drawable-hdpi/ic_play_arrow_white_24dp.png | Bin 195 -> 0 bytes .../res/drawable-hdpi/ic_receipt_white_24dp.png | Bin 261 -> 0 bytes .../main/res/drawable-hdpi/ic_root_folder_am.png | Bin 508 -> 0 bytes .../res/drawable-hdpi/ic_search_white_24dp.png | Bin 396 -> 0 bytes .../main/res/drawable-hdpi/ic_share_white_24dp.png | Bin 506 -> 0 bytes .../main/res/drawable-hdpi/ic_sort_white_24dp.png | Bin 115 -> 0 bytes .../res/drawable-hdpi/ic_warning_black_36dp.png | Bin 549 -> 0 bytes .../ic_add_circle_outline_grey600_24dp.png | Bin 427 -> 0 bytes .../ic_add_circle_outline_white_24dp.png | Bin 409 -> 0 bytes .../res/drawable-mdpi/ic_archive_grey600_24dp.png | Bin 266 -> 0 bytes .../res/drawable-mdpi/ic_archive_white_24dp.png | Bin 264 -> 0 bytes .../main/res/drawable-mdpi/ic_check_white_24dp.png | Bin 243 -> 0 bytes .../main/res/drawable-mdpi/ic_close_white_24dp.png | Bin 175 -> 0 bytes .../drawable-mdpi/ic_content_copy_white_24dp.png | Bin 216 -> 0 bytes .../res/drawable-mdpi/ic_delete_grey600_24dp.png | Bin 199 -> 0 bytes .../res/drawable-mdpi/ic_delete_white_24dp.png | Bin 197 -> 0 bytes .../main/res/drawable-mdpi/ic_doc_generic_am.png | Bin 561 -> 0 bytes .../res/drawable-mdpi/ic_edit_grey600_24dp.png | Bin 276 -> 0 bytes .../main/res/drawable-mdpi/ic_edit_white_24dp.png | Bin 272 -> 0 bytes .../drawable-mdpi/ic_filter_list_white_24dp.png | Bin 181 -> 0 bytes .../res/drawable-mdpi/ic_menu_copy_holo_dark.png | Bin 162 -> 0 bytes .../main/res/drawable-mdpi/ic_pause_white_24dp.png | Bin 83 -> 0 bytes .../res/drawable-mdpi/ic_play_arrow_white_24dp.png | Bin 157 -> 0 bytes .../res/drawable-mdpi/ic_receipt_white_24dp.png | Bin 194 -> 0 bytes .../main/res/drawable-mdpi/ic_root_folder_am.png | Bin 442 -> 0 bytes .../res/drawable-mdpi/ic_search_white_24dp.png | Bin 247 -> 0 bytes .../main/res/drawable-mdpi/ic_share_white_24dp.png | Bin 361 -> 0 bytes .../main/res/drawable-mdpi/ic_sort_white_24dp.png | Bin 90 -> 0 bytes .../res/drawable-mdpi/ic_warning_black_36dp.png | Bin 432 -> 0 bytes .../ic_add_circle_outline_grey600_24dp.png | Bin 781 -> 0 bytes .../ic_add_circle_outline_white_24dp.png | Bin 775 -> 0 bytes .../res/drawable-xhdpi/ic_archive_grey600_24dp.png | Bin 372 -> 0 bytes .../res/drawable-xhdpi/ic_archive_white_24dp.png | Bin 362 -> 0 bytes .../res/drawable-xhdpi/ic_check_white_24dp.png | Bin 363 -> 0 bytes .../res/drawable-xhdpi/ic_close_white_24dp.png | Bin 257 -> 0 bytes .../drawable-xhdpi/ic_content_copy_white_24dp.png | Bin 330 -> 0 bytes .../res/drawable-xhdpi/ic_delete_grey600_24dp.png | Bin 271 -> 0 bytes .../res/drawable-xhdpi/ic_delete_white_24dp.png | Bin 270 -> 0 bytes .../main/res/drawable-xhdpi/ic_doc_generic_am.png | Bin 831 -> 0 bytes .../res/drawable-xhdpi/ic_edit_grey600_24dp.png | Bin 379 -> 0 bytes .../main/res/drawable-xhdpi/ic_edit_white_24dp.png | Bin 378 -> 0 bytes .../drawable-xhdpi/ic_filter_list_white_24dp.png | Bin 200 -> 0 bytes .../res/drawable-xhdpi/ic_menu_copy_holo_dark.png | Bin 261 -> 0 bytes .../res/drawable-xhdpi/ic_pause_white_24dp.png | Bin 90 -> 0 bytes .../drawable-xhdpi/ic_play_arrow_white_24dp.png | Bin 220 -> 0 bytes .../res/drawable-xhdpi/ic_receipt_white_24dp.png | Bin 240 -> 0 bytes .../main/res/drawable-xhdpi/ic_root_folder_am.png | Bin 582 -> 0 bytes .../res/drawable-xhdpi/ic_search_white_24dp.png | Bin 465 -> 0 bytes .../res/drawable-xhdpi/ic_share_white_24dp.png | Bin 625 -> 0 bytes .../main/res/drawable-xhdpi/ic_sort_white_24dp.png | Bin 101 -> 0 bytes .../res/drawable-xhdpi/ic_warning_black_36dp.png | Bin 655 -> 0 bytes .../ic_add_circle_outline_grey600_24dp.png | Bin 1106 -> 0 bytes .../ic_add_circle_outline_white_24dp.png | Bin 1097 -> 0 bytes .../drawable-xxhdpi/ic_archive_grey600_24dp.png | Bin 529 -> 0 bytes .../res/drawable-xxhdpi/ic_archive_white_24dp.png | Bin 520 -> 0 bytes .../res/drawable-xxhdpi/ic_check_white_24dp.png | Bin 460 -> 0 bytes .../res/drawable-xxhdpi/ic_close_white_24dp.png | Bin 347 -> 0 bytes .../drawable-xxhdpi/ic_content_copy_white_24dp.png | Bin 436 -> 0 bytes .../res/drawable-xxhdpi/ic_delete_grey600_24dp.png | Bin 341 -> 0 bytes .../res/drawable-xxhdpi/ic_delete_white_24dp.png | Bin 338 -> 0 bytes .../main/res/drawable-xxhdpi/ic_doc_generic_am.png | Bin 585 -> 0 bytes .../res/drawable-xxhdpi/ic_edit_grey600_24dp.png | Bin 493 -> 0 bytes .../res/drawable-xxhdpi/ic_edit_white_24dp.png | Bin 490 -> 0 bytes .../drawable-xxhdpi/ic_filter_list_white_24dp.png | Bin 223 -> 0 bytes .../res/drawable-xxhdpi/ic_menu_copy_holo_dark.png | Bin 1272 -> 0 bytes .../res/drawable-xxhdpi/ic_pause_white_24dp.png | Bin 92 -> 0 bytes .../drawable-xxhdpi/ic_play_arrow_white_24dp.png | Bin 283 -> 0 bytes .../res/drawable-xxhdpi/ic_receipt_white_24dp.png | Bin 292 -> 0 bytes .../main/res/drawable-xxhdpi/ic_root_folder_am.png | Bin 1263 -> 0 bytes .../res/drawable-xxhdpi/ic_search_white_24dp.png | Bin 728 -> 0 bytes .../res/drawable-xxhdpi/ic_share_white_24dp.png | Bin 857 -> 0 bytes .../res/drawable-xxhdpi/ic_sort_white_24dp.png | Bin 103 -> 0 bytes .../res/drawable-xxhdpi/ic_warning_black_36dp.png | Bin 873 -> 0 bytes .../ic_add_circle_outline_grey600_24dp.png | Bin 1508 -> 0 bytes .../ic_add_circle_outline_white_24dp.png | Bin 1634 -> 0 bytes .../drawable-xxxhdpi/ic_archive_grey600_24dp.png | Bin 773 -> 0 bytes .../res/drawable-xxxhdpi/ic_archive_white_24dp.png | Bin 763 -> 0 bytes .../res/drawable-xxxhdpi/ic_check_white_24dp.png | Bin 587 -> 0 bytes .../res/drawable-xxxhdpi/ic_close_white_24dp.png | Bin 436 -> 0 bytes .../ic_content_copy_white_24dp.png | Bin 522 -> 0 bytes .../drawable-xxxhdpi/ic_delete_grey600_24dp.png | Bin 402 -> 0 bytes .../res/drawable-xxxhdpi/ic_delete_white_24dp.png | Bin 397 -> 0 bytes .../res/drawable-xxxhdpi/ic_edit_grey600_24dp.png | Bin 639 -> 0 bytes .../res/drawable-xxxhdpi/ic_edit_white_24dp.png | Bin 632 -> 0 bytes .../drawable-xxxhdpi/ic_filter_list_white_24dp.png | Bin 254 -> 0 bytes .../res/drawable-xxxhdpi/ic_pause_white_24dp.png | Bin 94 -> 0 bytes .../drawable-xxxhdpi/ic_play_arrow_white_24dp.png | Bin 343 -> 0 bytes .../res/drawable-xxxhdpi/ic_receipt_white_24dp.png | Bin 334 -> 0 bytes .../res/drawable-xxxhdpi/ic_search_white_24dp.png | Bin 915 -> 0 bytes .../res/drawable-xxxhdpi/ic_share_white_24dp.png | Bin 1115 -> 0 bytes .../res/drawable-xxxhdpi/ic_sort_white_24dp.png | Bin 107 -> 0 bytes .../res/drawable-xxxhdpi/ic_warning_black_36dp.png | Bin 1033 -> 0 bytes main/src/main/res/drawable/bg_rect_round.xml | 12 - main/src/main/res/drawable/bg_switchbar.xml | 9 - main/src/main/res/drawable/bg_tabs.xml | 9 - main/src/main/res/drawable/ic_shortcut_cancel.xml | 21 - main/src/main/res/drawable/ic_shortcut_vpn_key.xml | 21 - main/src/main/res/drawable/oval_ripple.xml | 15 - .../main/res/drawable/slidingtab_background.xml | 13 - main/src/main/res/drawable/white_rect.xml | 10 - .../main/res/layout-sw600dp-port/log_fragment.xml | 45 - main/src/main/res/layout-sw600dp/log_fragment.xml | 37 - main/src/main/res/layout-v21/connection_fab.xml | 24 - main/src/main/res/layout-v21/profile_list_fabs.xml | 37 - main/src/main/res/layout-v21/save_fab.xml | 22 - main/src/main/res/layout-v21/share_fab.xml | 22 - main/src/main/res/layout-v21/tabs.xml | 15 - main/src/main/res/layout/about.xml | 207 -- .../main/res/layout/allowed_application_layout.xml | 61 - .../res/layout/allowed_application_settings.xml | 65 - main/src/main/res/layout/allowed_vpn_apps.xml | 47 - main/src/main/res/layout/basic_settings.xml | 244 -- main/src/main/res/layout/config_converter.xml | 81 - main/src/main/res/layout/connection_fab.xml | 11 - main/src/main/res/layout/connections.xml | 74 - main/src/main/res/layout/extauth_provider.xml | 70 - main/src/main/res/layout/faq.xml | 15 - main/src/main/res/layout/faqcard.xml | 41 - main/src/main/res/layout/file_dialog.xml | 19 - main/src/main/res/layout/file_dialog_inline.xml | 27 - main/src/main/res/layout/file_dialog_main.xml | 71 - main/src/main/res/layout/file_dialog_row.xml | 31 - main/src/main/res/layout/file_select.xml | 77 - main/src/main/res/layout/fragment_senddump.xml | 38 - main/src/main/res/layout/graph.xml | 33 - main/src/main/res/layout/graph_item.xml | 30 - main/src/main/res/layout/keystore_selector.xml | 85 - main/src/main/res/layout/log_fragment.xml | 37 - main/src/main/res/layout/log_silders.xml | 73 - main/src/main/res/layout/log_window.xml | 12 - main/src/main/res/layout/main_activity.xml | 19 - main/src/main/res/layout/openssl_speed.xml | 40 - main/src/main/res/layout/padersliding_tab.xml | 13 - main/src/main/res/layout/profile_list_fabs.xml | 7 - main/src/main/res/layout/save_fab.xml | 11 - main/src/main/res/layout/server_card.xml | 403 --- main/src/main/res/layout/server_footer.xml | 13 - main/src/main/res/layout/settings_usereditable.xml | 30 - main/src/main/res/layout/share_fab.xml | 9 - main/src/main/res/layout/speedviewitem.xml | 54 - main/src/main/res/layout/tabs.xml | 12 - main/src/main/res/layout/tlsremote.xml | 50 - main/src/main/res/layout/viewconfig.xml | 23 - main/src/main/res/layout/vpn_list_item.xml | 86 - main/src/main/res/layout/vpn_profile_list.xml | 79 - main/src/main/res/layout/vpnstatus.xml | 52 - main/src/main/res/menu/allowed_apps.xml | 14 - main/src/main/res/menu/configmenu.xml | 16 - main/src/main/res/menu/connections.xml | 15 - main/src/main/res/menu/import_menu.xml | 23 - main/src/main/res/menu/logmenu.xml | 42 - main/src/main/res/menu/main_menu.xml | 14 - main/src/main/res/menu/vpnpreferences_menu.xml | 22 - main/src/main/res/values-be/arrays.xml | 32 - main/src/main/res/values-be/plurals.xml | 28 - main/src/main/res/values-be/strings.xml | 491 ---- main/src/main/res/values-ca/arrays.xml | 27 - main/src/main/res/values-ca/plurals.xml | 3 - main/src/main/res/values-ca/strings.xml | 119 - main/src/main/res/values-cs/arrays.xml | 39 - main/src/main/res/values-cs/plurals.xml | 3 - main/src/main/res/values-cs/strings.xml | 434 --- main/src/main/res/values-da/arrays.xml | 32 - main/src/main/res/values-da/plurals.xml | 20 - main/src/main/res/values-da/strings.xml | 484 ---- main/src/main/res/values-de/arrays.xml | 39 - main/src/main/res/values-de/plurals.xml | 20 - main/src/main/res/values-de/strings.xml | 484 ---- main/src/main/res/values-es/arrays.xml | 32 - main/src/main/res/values-es/plurals.xml | 20 - main/src/main/res/values-es/strings.xml | 485 ---- main/src/main/res/values-et/arrays.xml | 32 - main/src/main/res/values-et/plurals.xml | 20 - main/src/main/res/values-et/strings.xml | 420 --- main/src/main/res/values-fr/arrays.xml | 32 - main/src/main/res/values-fr/plurals.xml | 20 - main/src/main/res/values-fr/strings.xml | 493 ---- main/src/main/res/values-hu/arrays.xml | 32 - main/src/main/res/values-hu/plurals.xml | 20 - main/src/main/res/values-hu/strings.xml | 480 ---- main/src/main/res/values-in/arrays.xml | 32 - main/src/main/res/values-in/plurals.xml | 10 - main/src/main/res/values-in/strings.xml | 463 ---- main/src/main/res/values-it/arrays.xml | 32 - main/src/main/res/values-it/plurals.xml | 20 - main/src/main/res/values-it/strings.xml | 485 ---- main/src/main/res/values-ja/arrays.xml | 39 - main/src/main/res/values-ja/plurals.xml | 16 - main/src/main/res/values-ja/strings.xml | 520 ---- main/src/main/res/values-ko/arrays.xml | 32 - main/src/main/res/values-ko/plurals.xml | 16 - main/src/main/res/values-ko/strings.xml | 480 ---- main/src/main/res/values-nl/arrays.xml | 32 - main/src/main/res/values-nl/plurals.xml | 20 - main/src/main/res/values-nl/strings.xml | 470 ---- main/src/main/res/values-no/arrays.xml | 32 - main/src/main/res/values-no/plurals.xml | 20 - main/src/main/res/values-no/strings.xml | 291 -- main/src/main/res/values-pl/arrays.xml | 32 - main/src/main/res/values-pl/plurals.xml | 28 - main/src/main/res/values-pl/strings.xml | 486 ---- main/src/main/res/values-pt/arrays.xml | 32 - main/src/main/res/values-pt/plurals.xml | 20 - main/src/main/res/values-pt/strings.xml | 308 --- main/src/main/res/values-ro/arrays.xml | 32 - main/src/main/res/values-ro/plurals.xml | 24 - main/src/main/res/values-ro/strings.xml | 444 --- main/src/main/res/values-ru/arrays.xml | 32 - main/src/main/res/values-ru/plurals.xml | 28 - main/src/main/res/values-ru/strings.xml | 483 ---- main/src/main/res/values-sl/arrays.xml | 32 - main/src/main/res/values-sl/plurals.xml | 28 - main/src/main/res/values-sl/strings.xml | 434 --- main/src/main/res/values-sv/arrays.xml | 32 - main/src/main/res/values-sv/plurals.xml | 20 - main/src/main/res/values-sv/strings.xml | 489 ---- main/src/main/res/values-tr/arrays.xml | 39 - main/src/main/res/values-tr/plurals.xml | 20 - main/src/main/res/values-tr/strings.xml | 503 ---- main/src/main/res/values-uk/arrays.xml | 32 - main/src/main/res/values-uk/plurals.xml | 22 - main/src/main/res/values-uk/strings.xml | 465 ---- main/src/main/res/values-v21/colours.xml | 9 - main/src/main/res/values-v21/refs.xml | 27 - main/src/main/res/values-v21/styles.xml | 29 - main/src/main/res/values-vi/arrays.xml | 32 - main/src/main/res/values-vi/plurals.xml | 16 - main/src/main/res/values-vi/strings.xml | 492 ---- main/src/main/res/values-zh-rCN/arrays.xml | 32 - main/src/main/res/values-zh-rCN/plurals.xml | 16 - main/src/main/res/values-zh-rCN/strings.xml | 492 ---- main/src/main/res/values-zh-rTW/arrays.xml | 32 - main/src/main/res/values-zh-rTW/plurals.xml | 16 - main/src/main/res/values-zh-rTW/strings.xml | 456 --- main/src/main/res/xml/general_settings.xml | 90 - main/src/main/res/xml/vpn_authentification.xml | 64 - main/src/main/res/xml/vpn_ipsettings.xml | 53 - main/src/main/res/xml/vpn_obscure.xml | 84 - main/src/main/res/xml/vpn_routing.xml | 66 - main/src/skeleton/AndroidManifest.xml | 16 + .../de/blinkt/openvpn/activities/LogWindow.java | 15 + .../de/blinkt/openvpn/activities/MainActivity.java | 15 + main/src/ui/AndroidManifest.xml | 33 + .../support/v4n/app/FragmentStatePagerAdapter.java | 232 ++ .../android/support/v4n/view/PagerAdapter.java | 320 +++ .../java/android/support/v4n/view/ViewPager.java | 2895 ++++++++++++++++++++ .../java/de/blinkt/openvpn/OpenVPNTileService.java | 151 + .../de/blinkt/openvpn/activities/BaseActivity.java | 43 + .../blinkt/openvpn/activities/ConfigConverter.java | 847 ++++++ .../blinkt/openvpn/activities/CreateShortcuts.java | 159 ++ .../de/blinkt/openvpn/activities/FileSelect.java | 257 ++ .../de/blinkt/openvpn/activities/LogWindow.java | 37 + .../de/blinkt/openvpn/activities/MainActivity.java | 131 + .../de/blinkt/openvpn/activities/OpenSSLSpeed.java | 193 ++ .../blinkt/openvpn/activities/VPNPreferences.java | 244 ++ .../de/blinkt/openvpn/fragments/AboutFragment.java | 333 +++ .../openvpn/fragments/ConnectionsAdapter.java | 413 +++ .../de/blinkt/openvpn/fragments/FaqFragment.java | 216 ++ .../blinkt/openvpn/fragments/FaqViewAdapter.java | 132 + .../openvpn/fragments/FileSelectionFragment.java | 325 +++ .../blinkt/openvpn/fragments/GeneralSettings.java | 190 ++ .../de/blinkt/openvpn/fragments/GraphFragment.java | 400 +++ .../de/blinkt/openvpn/fragments/InlineFileTab.java | 70 + .../openvpn/fragments/KeyChainSettingsFragment.kt | 262 ++ .../de/blinkt/openvpn/fragments/LogFragment.java | 694 +++++ .../fragments/OpenVpnPreferencesFragment.java | 53 + .../blinkt/openvpn/fragments/SendDumpFragment.java | 128 + .../openvpn/fragments/Settings_Allowed_Apps.kt | 323 +++ .../openvpn/fragments/Settings_Authentication.java | 238 ++ .../blinkt/openvpn/fragments/Settings_Basic.java | 227 ++ .../openvpn/fragments/Settings_Connections.java | 101 + .../openvpn/fragments/Settings_Fragment.java | 35 + .../de/blinkt/openvpn/fragments/Settings_IP.java | 137 + .../blinkt/openvpn/fragments/Settings_Obscure.java | 212 ++ .../blinkt/openvpn/fragments/Settings_Routing.java | 109 + .../openvpn/fragments/Settings_UserEditable.java | 63 + .../openvpn/fragments/ShowConfigFragment.java | 134 + .../ui/java/de/blinkt/openvpn/fragments/Utils.java | 288 ++ .../blinkt/openvpn/fragments/VPNProfileList.java | 636 +++++ .../openvpn/views/DefaultVPNListPreference.java | 39 + .../de/blinkt/openvpn/views/FileSelectLayout.java | 189 ++ .../blinkt/openvpn/views/MultiLineRadioGroup.java | 164 ++ .../blinkt/openvpn/views/PagerSlidingTabStrip.java | 732 +++++ .../blinkt/openvpn/views/RemoteCNPreference.java | 146 + .../openvpn/views/ScreenSlidePagerAdapter.java | 79 + .../java/de/blinkt/openvpn/views/SeekBarTicks.java | 73 + .../de/blinkt/openvpn/views/SlidingTabLayout.java | 314 +++ .../de/blinkt/openvpn/views/SlidingTabStrip.java | 207 ++ .../java/de/blinkt/openvpn/views/TabBarView.java | 16 + main/src/ui/res/anim/fab_anim.xml | 23 + .../ic_add_circle_outline_grey600_24dp.png | Bin 0 -> 624 bytes .../ic_add_circle_outline_white_24dp.png | Bin 0 -> 606 bytes .../res/drawable-hdpi/ic_archive_grey600_24dp.png | Bin 0 -> 353 bytes .../ui/res/drawable-hdpi/ic_archive_white_24dp.png | Bin 0 -> 347 bytes .../ui/res/drawable-hdpi/ic_check_white_24dp.png | Bin 0 -> 309 bytes .../ui/res/drawable-hdpi/ic_close_white_24dp.png | Bin 0 -> 221 bytes .../drawable-hdpi/ic_content_copy_white_24dp.png | Bin 0 -> 287 bytes .../res/drawable-hdpi/ic_delete_grey600_24dp.png | Bin 0 -> 248 bytes .../ui/res/drawable-hdpi/ic_delete_white_24dp.png | Bin 0 -> 246 bytes .../src/ui/res/drawable-hdpi/ic_doc_generic_am.png | Bin 0 -> 694 bytes .../ui/res/drawable-hdpi/ic_edit_grey600_24dp.png | Bin 0 -> 341 bytes .../ui/res/drawable-hdpi/ic_edit_white_24dp.png | Bin 0 -> 339 bytes .../drawable-hdpi/ic_filter_list_white_24dp.png | Bin 0 -> 206 bytes .../res/drawable-hdpi/ic_menu_copy_holo_dark.png | Bin 0 -> 186 bytes .../ui/res/drawable-hdpi/ic_pause_white_24dp.png | Bin 0 -> 105 bytes .../res/drawable-hdpi/ic_play_arrow_white_24dp.png | Bin 0 -> 195 bytes .../ui/res/drawable-hdpi/ic_receipt_white_24dp.png | Bin 0 -> 261 bytes .../src/ui/res/drawable-hdpi/ic_root_folder_am.png | Bin 0 -> 508 bytes .../ui/res/drawable-hdpi/ic_search_white_24dp.png | Bin 0 -> 396 bytes .../ui/res/drawable-hdpi/ic_share_white_24dp.png | Bin 0 -> 506 bytes .../ui/res/drawable-hdpi/ic_sort_white_24dp.png | Bin 0 -> 115 bytes .../ui/res/drawable-hdpi/ic_warning_black_36dp.png | Bin 0 -> 549 bytes .../ic_add_circle_outline_grey600_24dp.png | Bin 0 -> 427 bytes .../ic_add_circle_outline_white_24dp.png | Bin 0 -> 409 bytes .../res/drawable-mdpi/ic_archive_grey600_24dp.png | Bin 0 -> 266 bytes .../ui/res/drawable-mdpi/ic_archive_white_24dp.png | Bin 0 -> 264 bytes .../ui/res/drawable-mdpi/ic_check_white_24dp.png | Bin 0 -> 243 bytes .../ui/res/drawable-mdpi/ic_close_white_24dp.png | Bin 0 -> 175 bytes .../drawable-mdpi/ic_content_copy_white_24dp.png | Bin 0 -> 216 bytes .../res/drawable-mdpi/ic_delete_grey600_24dp.png | Bin 0 -> 199 bytes .../ui/res/drawable-mdpi/ic_delete_white_24dp.png | Bin 0 -> 197 bytes .../src/ui/res/drawable-mdpi/ic_doc_generic_am.png | Bin 0 -> 561 bytes .../ui/res/drawable-mdpi/ic_edit_grey600_24dp.png | Bin 0 -> 276 bytes .../ui/res/drawable-mdpi/ic_edit_white_24dp.png | Bin 0 -> 272 bytes .../drawable-mdpi/ic_filter_list_white_24dp.png | Bin 0 -> 181 bytes .../res/drawable-mdpi/ic_menu_copy_holo_dark.png | Bin 0 -> 162 bytes .../ui/res/drawable-mdpi/ic_pause_white_24dp.png | Bin 0 -> 83 bytes .../res/drawable-mdpi/ic_play_arrow_white_24dp.png | Bin 0 -> 157 bytes .../ui/res/drawable-mdpi/ic_receipt_white_24dp.png | Bin 0 -> 194 bytes .../src/ui/res/drawable-mdpi/ic_root_folder_am.png | Bin 0 -> 442 bytes .../ui/res/drawable-mdpi/ic_search_white_24dp.png | Bin 0 -> 247 bytes .../ui/res/drawable-mdpi/ic_share_white_24dp.png | Bin 0 -> 361 bytes .../ui/res/drawable-mdpi/ic_sort_white_24dp.png | Bin 0 -> 90 bytes .../ui/res/drawable-mdpi/ic_warning_black_36dp.png | Bin 0 -> 432 bytes .../ic_add_circle_outline_grey600_24dp.png | Bin 0 -> 781 bytes .../ic_add_circle_outline_white_24dp.png | Bin 0 -> 775 bytes .../res/drawable-xhdpi/ic_archive_grey600_24dp.png | Bin 0 -> 372 bytes .../res/drawable-xhdpi/ic_archive_white_24dp.png | Bin 0 -> 362 bytes .../ui/res/drawable-xhdpi/ic_check_white_24dp.png | Bin 0 -> 363 bytes .../ui/res/drawable-xhdpi/ic_close_white_24dp.png | Bin 0 -> 257 bytes .../drawable-xhdpi/ic_content_copy_white_24dp.png | Bin 0 -> 330 bytes .../res/drawable-xhdpi/ic_delete_grey600_24dp.png | Bin 0 -> 271 bytes .../ui/res/drawable-xhdpi/ic_delete_white_24dp.png | Bin 0 -> 270 bytes .../ui/res/drawable-xhdpi/ic_doc_generic_am.png | Bin 0 -> 831 bytes .../ui/res/drawable-xhdpi/ic_edit_grey600_24dp.png | Bin 0 -> 379 bytes .../ui/res/drawable-xhdpi/ic_edit_white_24dp.png | Bin 0 -> 378 bytes .../drawable-xhdpi/ic_filter_list_white_24dp.png | Bin 0 -> 200 bytes .../res/drawable-xhdpi/ic_menu_copy_holo_dark.png | Bin 0 -> 261 bytes .../ui/res/drawable-xhdpi/ic_pause_white_24dp.png | Bin 0 -> 90 bytes .../drawable-xhdpi/ic_play_arrow_white_24dp.png | Bin 0 -> 220 bytes .../res/drawable-xhdpi/ic_receipt_white_24dp.png | Bin 0 -> 240 bytes .../ui/res/drawable-xhdpi/ic_root_folder_am.png | Bin 0 -> 582 bytes .../ui/res/drawable-xhdpi/ic_search_white_24dp.png | Bin 0 -> 465 bytes .../ui/res/drawable-xhdpi/ic_share_white_24dp.png | Bin 0 -> 625 bytes .../ui/res/drawable-xhdpi/ic_sort_white_24dp.png | Bin 0 -> 101 bytes .../res/drawable-xhdpi/ic_warning_black_36dp.png | Bin 0 -> 655 bytes .../ic_add_circle_outline_grey600_24dp.png | Bin 0 -> 1106 bytes .../ic_add_circle_outline_white_24dp.png | Bin 0 -> 1097 bytes .../drawable-xxhdpi/ic_archive_grey600_24dp.png | Bin 0 -> 529 bytes .../res/drawable-xxhdpi/ic_archive_white_24dp.png | Bin 0 -> 520 bytes .../ui/res/drawable-xxhdpi/ic_check_white_24dp.png | Bin 0 -> 460 bytes .../ui/res/drawable-xxhdpi/ic_close_white_24dp.png | Bin 0 -> 347 bytes .../drawable-xxhdpi/ic_content_copy_white_24dp.png | Bin 0 -> 436 bytes .../res/drawable-xxhdpi/ic_delete_grey600_24dp.png | Bin 0 -> 341 bytes .../res/drawable-xxhdpi/ic_delete_white_24dp.png | Bin 0 -> 338 bytes .../ui/res/drawable-xxhdpi/ic_doc_generic_am.png | Bin 0 -> 585 bytes .../res/drawable-xxhdpi/ic_edit_grey600_24dp.png | Bin 0 -> 493 bytes .../ui/res/drawable-xxhdpi/ic_edit_white_24dp.png | Bin 0 -> 490 bytes .../drawable-xxhdpi/ic_filter_list_white_24dp.png | Bin 0 -> 223 bytes .../res/drawable-xxhdpi/ic_menu_copy_holo_dark.png | Bin 0 -> 1272 bytes .../ui/res/drawable-xxhdpi/ic_pause_white_24dp.png | Bin 0 -> 92 bytes .../drawable-xxhdpi/ic_play_arrow_white_24dp.png | Bin 0 -> 283 bytes .../res/drawable-xxhdpi/ic_receipt_white_24dp.png | Bin 0 -> 292 bytes .../ui/res/drawable-xxhdpi/ic_root_folder_am.png | Bin 0 -> 1263 bytes .../res/drawable-xxhdpi/ic_search_white_24dp.png | Bin 0 -> 728 bytes .../ui/res/drawable-xxhdpi/ic_share_white_24dp.png | Bin 0 -> 857 bytes .../ui/res/drawable-xxhdpi/ic_sort_white_24dp.png | Bin 0 -> 103 bytes .../res/drawable-xxhdpi/ic_warning_black_36dp.png | Bin 0 -> 873 bytes .../ic_add_circle_outline_grey600_24dp.png | Bin 0 -> 1508 bytes .../ic_add_circle_outline_white_24dp.png | Bin 0 -> 1634 bytes .../drawable-xxxhdpi/ic_archive_grey600_24dp.png | Bin 0 -> 773 bytes .../res/drawable-xxxhdpi/ic_archive_white_24dp.png | Bin 0 -> 763 bytes .../res/drawable-xxxhdpi/ic_check_white_24dp.png | Bin 0 -> 587 bytes .../res/drawable-xxxhdpi/ic_close_white_24dp.png | Bin 0 -> 436 bytes .../ic_content_copy_white_24dp.png | Bin 0 -> 522 bytes .../drawable-xxxhdpi/ic_delete_grey600_24dp.png | Bin 0 -> 402 bytes .../res/drawable-xxxhdpi/ic_delete_white_24dp.png | Bin 0 -> 397 bytes .../res/drawable-xxxhdpi/ic_edit_grey600_24dp.png | Bin 0 -> 639 bytes .../ui/res/drawable-xxxhdpi/ic_edit_white_24dp.png | Bin 0 -> 632 bytes .../drawable-xxxhdpi/ic_filter_list_white_24dp.png | Bin 0 -> 254 bytes .../res/drawable-xxxhdpi/ic_pause_white_24dp.png | Bin 0 -> 94 bytes .../drawable-xxxhdpi/ic_play_arrow_white_24dp.png | Bin 0 -> 343 bytes .../res/drawable-xxxhdpi/ic_receipt_white_24dp.png | Bin 0 -> 334 bytes .../res/drawable-xxxhdpi/ic_search_white_24dp.png | Bin 0 -> 915 bytes .../res/drawable-xxxhdpi/ic_share_white_24dp.png | Bin 0 -> 1115 bytes .../ui/res/drawable-xxxhdpi/ic_sort_white_24dp.png | Bin 0 -> 107 bytes .../res/drawable-xxxhdpi/ic_warning_black_36dp.png | Bin 0 -> 1033 bytes main/src/ui/res/drawable/bg_rect_round.xml | 12 + main/src/ui/res/drawable/bg_switchbar.xml | 9 + main/src/ui/res/drawable/bg_tabs.xml | 9 + main/src/ui/res/drawable/ic_shortcut_cancel.xml | 21 + main/src/ui/res/drawable/ic_shortcut_vpn_key.xml | 21 + main/src/ui/res/drawable/oval_ripple.xml | 15 + main/src/ui/res/drawable/slidingtab_background.xml | 13 + main/src/ui/res/drawable/white_rect.xml | 10 + .../ui/res/layout-sw600dp-port/log_fragment.xml | 45 + main/src/ui/res/layout-sw600dp/log_fragment.xml | 37 + main/src/ui/res/layout-v21/connection_fab.xml | 24 + main/src/ui/res/layout-v21/profile_list_fabs.xml | 37 + main/src/ui/res/layout-v21/save_fab.xml | 22 + main/src/ui/res/layout-v21/share_fab.xml | 22 + main/src/ui/res/layout-v21/tabs.xml | 15 + main/src/ui/res/layout/about.xml | 207 ++ .../ui/res/layout/allowed_application_layout.xml | 61 + .../ui/res/layout/allowed_application_settings.xml | 65 + main/src/ui/res/layout/allowed_vpn_apps.xml | 47 + main/src/ui/res/layout/basic_settings.xml | 244 ++ main/src/ui/res/layout/config_converter.xml | 81 + main/src/ui/res/layout/connection_fab.xml | 11 + main/src/ui/res/layout/connections.xml | 74 + main/src/ui/res/layout/extauth_provider.xml | 70 + main/src/ui/res/layout/faq.xml | 15 + main/src/ui/res/layout/faqcard.xml | 41 + main/src/ui/res/layout/file_dialog.xml | 19 + main/src/ui/res/layout/file_dialog_inline.xml | 27 + main/src/ui/res/layout/file_dialog_main.xml | 71 + main/src/ui/res/layout/file_dialog_row.xml | 31 + main/src/ui/res/layout/file_select.xml | 77 + main/src/ui/res/layout/fragment_senddump.xml | 38 + main/src/ui/res/layout/graph.xml | 33 + main/src/ui/res/layout/graph_item.xml | 30 + main/src/ui/res/layout/keystore_selector.xml | 85 + main/src/ui/res/layout/log_fragment.xml | 37 + main/src/ui/res/layout/log_silders.xml | 73 + main/src/ui/res/layout/log_window.xml | 12 + main/src/ui/res/layout/main_activity.xml | 18 + main/src/ui/res/layout/openssl_speed.xml | 40 + main/src/ui/res/layout/padersliding_tab.xml | 13 + main/src/ui/res/layout/profile_list_fabs.xml | 7 + main/src/ui/res/layout/save_fab.xml | 11 + main/src/ui/res/layout/server_card.xml | 403 +++ main/src/ui/res/layout/server_footer.xml | 13 + main/src/ui/res/layout/settings_usereditable.xml | 30 + main/src/ui/res/layout/share_fab.xml | 9 + main/src/ui/res/layout/speedviewitem.xml | 54 + main/src/ui/res/layout/tabs.xml | 12 + main/src/ui/res/layout/tlsremote.xml | 50 + main/src/ui/res/layout/viewconfig.xml | 23 + main/src/ui/res/layout/vpn_list_item.xml | 86 + main/src/ui/res/layout/vpn_profile_list.xml | 79 + main/src/ui/res/layout/vpnstatus.xml | 52 + main/src/ui/res/menu/allowed_apps.xml | 14 + main/src/ui/res/menu/configmenu.xml | 16 + main/src/ui/res/menu/connections.xml | 15 + main/src/ui/res/menu/import_menu.xml | 23 + main/src/ui/res/menu/logmenu.xml | 42 + main/src/ui/res/menu/main_menu.xml | 14 + main/src/ui/res/menu/vpnpreferences_menu.xml | 22 + main/src/ui/res/values-be/arrays.xml | 32 + main/src/ui/res/values-be/plurals.xml | 28 + main/src/ui/res/values-be/strings.xml | 491 ++++ main/src/ui/res/values-ca/arrays.xml | 27 + main/src/ui/res/values-ca/plurals.xml | 3 + main/src/ui/res/values-ca/strings.xml | 119 + main/src/ui/res/values-cs/arrays.xml | 39 + main/src/ui/res/values-cs/plurals.xml | 3 + main/src/ui/res/values-cs/strings.xml | 434 +++ main/src/ui/res/values-da/arrays.xml | 32 + main/src/ui/res/values-da/plurals.xml | 20 + main/src/ui/res/values-da/strings.xml | 484 ++++ main/src/ui/res/values-de/arrays.xml | 39 + main/src/ui/res/values-de/plurals.xml | 20 + main/src/ui/res/values-de/strings.xml | 484 ++++ main/src/ui/res/values-es/arrays.xml | 32 + main/src/ui/res/values-es/plurals.xml | 20 + main/src/ui/res/values-es/strings.xml | 485 ++++ main/src/ui/res/values-et/arrays.xml | 32 + main/src/ui/res/values-et/plurals.xml | 20 + main/src/ui/res/values-et/strings.xml | 420 +++ main/src/ui/res/values-fr/arrays.xml | 32 + main/src/ui/res/values-fr/plurals.xml | 20 + main/src/ui/res/values-fr/strings.xml | 493 ++++ main/src/ui/res/values-hu/arrays.xml | 32 + main/src/ui/res/values-hu/plurals.xml | 20 + main/src/ui/res/values-hu/strings.xml | 480 ++++ main/src/ui/res/values-in/arrays.xml | 32 + main/src/ui/res/values-in/plurals.xml | 10 + main/src/ui/res/values-in/strings.xml | 463 ++++ main/src/ui/res/values-it/arrays.xml | 32 + main/src/ui/res/values-it/plurals.xml | 20 + main/src/ui/res/values-it/strings.xml | 485 ++++ main/src/ui/res/values-ja/arrays.xml | 39 + main/src/ui/res/values-ja/plurals.xml | 16 + main/src/ui/res/values-ja/strings.xml | 520 ++++ main/src/ui/res/values-ko/arrays.xml | 32 + main/src/ui/res/values-ko/plurals.xml | 16 + main/src/ui/res/values-ko/strings.xml | 480 ++++ main/src/ui/res/values-nl/arrays.xml | 32 + main/src/ui/res/values-nl/plurals.xml | 20 + main/src/ui/res/values-nl/strings.xml | 470 ++++ main/src/ui/res/values-no/arrays.xml | 32 + main/src/ui/res/values-no/plurals.xml | 20 + main/src/ui/res/values-no/strings.xml | 291 ++ main/src/ui/res/values-pl/arrays.xml | 32 + main/src/ui/res/values-pl/plurals.xml | 28 + main/src/ui/res/values-pl/strings.xml | 486 ++++ main/src/ui/res/values-pt/arrays.xml | 32 + main/src/ui/res/values-pt/plurals.xml | 20 + main/src/ui/res/values-pt/strings.xml | 308 +++ main/src/ui/res/values-ro/arrays.xml | 32 + main/src/ui/res/values-ro/plurals.xml | 24 + main/src/ui/res/values-ro/strings.xml | 444 +++ main/src/ui/res/values-ru/arrays.xml | 32 + main/src/ui/res/values-ru/plurals.xml | 28 + main/src/ui/res/values-ru/strings.xml | 483 ++++ main/src/ui/res/values-sl/arrays.xml | 32 + main/src/ui/res/values-sl/plurals.xml | 28 + main/src/ui/res/values-sl/strings.xml | 434 +++ main/src/ui/res/values-sv/arrays.xml | 32 + main/src/ui/res/values-sv/plurals.xml | 20 + main/src/ui/res/values-sv/strings.xml | 489 ++++ main/src/ui/res/values-tr/arrays.xml | 39 + main/src/ui/res/values-tr/plurals.xml | 20 + main/src/ui/res/values-tr/strings.xml | 503 ++++ main/src/ui/res/values-uk/arrays.xml | 32 + main/src/ui/res/values-uk/plurals.xml | 22 + main/src/ui/res/values-uk/strings.xml | 465 ++++ main/src/ui/res/values-v21/colours.xml | 9 + main/src/ui/res/values-v21/refs.xml | 27 + main/src/ui/res/values-v21/styles.xml | 29 + main/src/ui/res/values-vi/arrays.xml | 32 + main/src/ui/res/values-vi/plurals.xml | 16 + main/src/ui/res/values-vi/strings.xml | 492 ++++ main/src/ui/res/values-zh-rCN/arrays.xml | 32 + main/src/ui/res/values-zh-rCN/plurals.xml | 16 + main/src/ui/res/values-zh-rCN/strings.xml | 492 ++++ main/src/ui/res/values-zh-rTW/arrays.xml | 32 + main/src/ui/res/values-zh-rTW/plurals.xml | 16 + main/src/ui/res/values-zh-rTW/strings.xml | 456 +++ main/src/ui/res/xml/general_settings.xml | 90 + main/src/ui/res/xml/vpn_authentification.xml | 64 + main/src/ui/res/xml/vpn_ipsettings.xml | 53 + main/src/ui/res/xml/vpn_obscure.xml | 84 + main/src/ui/res/xml/vpn_routing.xml | 66 + 611 files changed, 29543 insertions(+), 29475 deletions(-) delete mode 100644 main/src/main/java/android/support/v4n/app/FragmentStatePagerAdapter.java delete mode 100644 main/src/main/java/android/support/v4n/view/PagerAdapter.java delete mode 100644 main/src/main/java/android/support/v4n/view/ViewPager.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/activities/BaseActivity.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/activities/ConfigConverter.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/activities/FileSelect.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/activities/MainActivity.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/activities/OpenSSLSpeed.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/AboutFragment.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/ConnectionsAdapter.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/FaqViewAdapter.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/FileSelectionFragment.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/GraphFragment.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/InlineFileTab.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/KeyChainSettingsFragment.kt delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/SendDumpFragment.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/Settings_Allowed_Apps.kt delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/Settings_Authentication.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/Settings_Connections.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/Settings_Fragment.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/Settings_IP.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/Settings_Routing.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/Settings_UserEditable.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/ShowConfigFragment.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/Utils.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/views/DefaultVPNListPreference.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/views/FileSelectLayout.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/views/MultiLineRadioGroup.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/views/PagerSlidingTabStrip.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/views/RemoteCNPreference.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/views/ScreenSlidePagerAdapter.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/views/SlidingTabLayout.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/views/SlidingTabStrip.java delete mode 100644 main/src/main/java/de/blinkt/openvpn/views/TabBarView.java delete mode 100644 main/src/main/res/anim/fab_anim.xml delete mode 100644 main/src/main/res/drawable-hdpi/ic_add_circle_outline_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_add_circle_outline_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_archive_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_archive_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_check_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_close_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_content_copy_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_delete_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_delete_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_doc_generic_am.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_edit_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_edit_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_filter_list_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_menu_copy_holo_dark.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_pause_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_receipt_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_root_folder_am.png delete mode 100755 main/src/main/res/drawable-hdpi/ic_search_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_share_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_sort_white_24dp.png delete mode 100644 main/src/main/res/drawable-hdpi/ic_warning_black_36dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_add_circle_outline_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_add_circle_outline_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_archive_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_archive_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_check_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_close_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_content_copy_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_delete_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_delete_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_doc_generic_am.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_edit_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_edit_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_filter_list_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_menu_copy_holo_dark.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_pause_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_receipt_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_root_folder_am.png delete mode 100755 main/src/main/res/drawable-mdpi/ic_search_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_share_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_sort_white_24dp.png delete mode 100644 main/src/main/res/drawable-mdpi/ic_warning_black_36dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_add_circle_outline_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_add_circle_outline_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_archive_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_archive_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_check_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_close_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_content_copy_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_delete_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_doc_generic_am.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_edit_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_edit_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_filter_list_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_menu_copy_holo_dark.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_receipt_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_root_folder_am.png delete mode 100755 main/src/main/res/drawable-xhdpi/ic_search_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_share_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_sort_white_24dp.png delete mode 100644 main/src/main/res/drawable-xhdpi/ic_warning_black_36dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_add_circle_outline_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_add_circle_outline_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_archive_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_archive_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_content_copy_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_delete_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_doc_generic_am.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_edit_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_edit_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_filter_list_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_menu_copy_holo_dark.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_pause_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_receipt_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_root_folder_am.png delete mode 100755 main/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_share_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_sort_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxhdpi/ic_warning_black_36dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_add_circle_outline_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_add_circle_outline_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_archive_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_archive_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_content_copy_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_delete_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_edit_grey600_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_edit_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_filter_list_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_pause_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_receipt_white_24dp.png delete mode 100755 main/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_share_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_sort_white_24dp.png delete mode 100644 main/src/main/res/drawable-xxxhdpi/ic_warning_black_36dp.png delete mode 100644 main/src/main/res/drawable/bg_rect_round.xml delete mode 100644 main/src/main/res/drawable/bg_switchbar.xml delete mode 100644 main/src/main/res/drawable/bg_tabs.xml delete mode 100644 main/src/main/res/drawable/ic_shortcut_cancel.xml delete mode 100644 main/src/main/res/drawable/ic_shortcut_vpn_key.xml delete mode 100644 main/src/main/res/drawable/oval_ripple.xml delete mode 100644 main/src/main/res/drawable/slidingtab_background.xml delete mode 100644 main/src/main/res/drawable/white_rect.xml delete mode 100644 main/src/main/res/layout-sw600dp-port/log_fragment.xml delete mode 100644 main/src/main/res/layout-sw600dp/log_fragment.xml delete mode 100644 main/src/main/res/layout-v21/connection_fab.xml delete mode 100644 main/src/main/res/layout-v21/profile_list_fabs.xml delete mode 100644 main/src/main/res/layout-v21/save_fab.xml delete mode 100644 main/src/main/res/layout-v21/share_fab.xml delete mode 100644 main/src/main/res/layout-v21/tabs.xml delete mode 100644 main/src/main/res/layout/about.xml delete mode 100644 main/src/main/res/layout/allowed_application_layout.xml delete mode 100644 main/src/main/res/layout/allowed_application_settings.xml delete mode 100644 main/src/main/res/layout/allowed_vpn_apps.xml delete mode 100644 main/src/main/res/layout/basic_settings.xml delete mode 100644 main/src/main/res/layout/config_converter.xml delete mode 100644 main/src/main/res/layout/connection_fab.xml delete mode 100644 main/src/main/res/layout/connections.xml delete mode 100644 main/src/main/res/layout/extauth_provider.xml delete mode 100644 main/src/main/res/layout/faq.xml delete mode 100644 main/src/main/res/layout/faqcard.xml delete mode 100644 main/src/main/res/layout/file_dialog.xml delete mode 100644 main/src/main/res/layout/file_dialog_inline.xml delete mode 100644 main/src/main/res/layout/file_dialog_main.xml delete mode 100644 main/src/main/res/layout/file_dialog_row.xml delete mode 100644 main/src/main/res/layout/file_select.xml delete mode 100644 main/src/main/res/layout/fragment_senddump.xml delete mode 100644 main/src/main/res/layout/graph.xml delete mode 100644 main/src/main/res/layout/graph_item.xml delete mode 100644 main/src/main/res/layout/keystore_selector.xml delete mode 100644 main/src/main/res/layout/log_fragment.xml delete mode 100644 main/src/main/res/layout/log_silders.xml delete mode 100644 main/src/main/res/layout/log_window.xml delete mode 100644 main/src/main/res/layout/main_activity.xml delete mode 100644 main/src/main/res/layout/openssl_speed.xml delete mode 100644 main/src/main/res/layout/padersliding_tab.xml delete mode 100644 main/src/main/res/layout/profile_list_fabs.xml delete mode 100644 main/src/main/res/layout/save_fab.xml delete mode 100644 main/src/main/res/layout/server_card.xml delete mode 100644 main/src/main/res/layout/server_footer.xml delete mode 100644 main/src/main/res/layout/settings_usereditable.xml delete mode 100644 main/src/main/res/layout/share_fab.xml delete mode 100644 main/src/main/res/layout/speedviewitem.xml delete mode 100644 main/src/main/res/layout/tabs.xml delete mode 100644 main/src/main/res/layout/tlsremote.xml delete mode 100644 main/src/main/res/layout/viewconfig.xml delete mode 100644 main/src/main/res/layout/vpn_list_item.xml delete mode 100644 main/src/main/res/layout/vpn_profile_list.xml delete mode 100644 main/src/main/res/layout/vpnstatus.xml delete mode 100644 main/src/main/res/menu/allowed_apps.xml delete mode 100644 main/src/main/res/menu/configmenu.xml delete mode 100644 main/src/main/res/menu/connections.xml delete mode 100644 main/src/main/res/menu/import_menu.xml delete mode 100644 main/src/main/res/menu/logmenu.xml delete mode 100644 main/src/main/res/menu/main_menu.xml delete mode 100644 main/src/main/res/menu/vpnpreferences_menu.xml delete mode 100755 main/src/main/res/values-be/arrays.xml delete mode 100755 main/src/main/res/values-be/plurals.xml delete mode 100755 main/src/main/res/values-be/strings.xml delete mode 100755 main/src/main/res/values-ca/arrays.xml delete mode 100755 main/src/main/res/values-ca/plurals.xml delete mode 100755 main/src/main/res/values-ca/strings.xml delete mode 100755 main/src/main/res/values-cs/arrays.xml delete mode 100755 main/src/main/res/values-cs/plurals.xml delete mode 100755 main/src/main/res/values-cs/strings.xml delete mode 100755 main/src/main/res/values-da/arrays.xml delete mode 100755 main/src/main/res/values-da/plurals.xml delete mode 100755 main/src/main/res/values-da/strings.xml delete mode 100755 main/src/main/res/values-de/arrays.xml delete mode 100755 main/src/main/res/values-de/plurals.xml delete mode 100755 main/src/main/res/values-de/strings.xml delete mode 100755 main/src/main/res/values-es/arrays.xml delete mode 100755 main/src/main/res/values-es/plurals.xml delete mode 100755 main/src/main/res/values-es/strings.xml delete mode 100755 main/src/main/res/values-et/arrays.xml delete mode 100755 main/src/main/res/values-et/plurals.xml delete mode 100755 main/src/main/res/values-et/strings.xml delete mode 100755 main/src/main/res/values-fr/arrays.xml delete mode 100755 main/src/main/res/values-fr/plurals.xml delete mode 100755 main/src/main/res/values-fr/strings.xml delete mode 100755 main/src/main/res/values-hu/arrays.xml delete mode 100755 main/src/main/res/values-hu/plurals.xml delete mode 100755 main/src/main/res/values-hu/strings.xml delete mode 100755 main/src/main/res/values-in/arrays.xml delete mode 100755 main/src/main/res/values-in/plurals.xml delete mode 100755 main/src/main/res/values-in/strings.xml delete mode 100755 main/src/main/res/values-it/arrays.xml delete mode 100755 main/src/main/res/values-it/plurals.xml delete mode 100755 main/src/main/res/values-it/strings.xml delete mode 100755 main/src/main/res/values-ja/arrays.xml delete mode 100755 main/src/main/res/values-ja/plurals.xml delete mode 100755 main/src/main/res/values-ja/strings.xml delete mode 100755 main/src/main/res/values-ko/arrays.xml delete mode 100755 main/src/main/res/values-ko/plurals.xml delete mode 100755 main/src/main/res/values-ko/strings.xml delete mode 100755 main/src/main/res/values-nl/arrays.xml delete mode 100755 main/src/main/res/values-nl/plurals.xml delete mode 100755 main/src/main/res/values-nl/strings.xml delete mode 100755 main/src/main/res/values-no/arrays.xml delete mode 100755 main/src/main/res/values-no/plurals.xml delete mode 100755 main/src/main/res/values-no/strings.xml delete mode 100755 main/src/main/res/values-pl/arrays.xml delete mode 100755 main/src/main/res/values-pl/plurals.xml delete mode 100755 main/src/main/res/values-pl/strings.xml delete mode 100755 main/src/main/res/values-pt/arrays.xml delete mode 100755 main/src/main/res/values-pt/plurals.xml delete mode 100755 main/src/main/res/values-pt/strings.xml delete mode 100755 main/src/main/res/values-ro/arrays.xml delete mode 100755 main/src/main/res/values-ro/plurals.xml delete mode 100755 main/src/main/res/values-ro/strings.xml delete mode 100755 main/src/main/res/values-ru/arrays.xml delete mode 100755 main/src/main/res/values-ru/plurals.xml delete mode 100755 main/src/main/res/values-ru/strings.xml delete mode 100755 main/src/main/res/values-sl/arrays.xml delete mode 100755 main/src/main/res/values-sl/plurals.xml delete mode 100755 main/src/main/res/values-sl/strings.xml delete mode 100755 main/src/main/res/values-sv/arrays.xml delete mode 100755 main/src/main/res/values-sv/plurals.xml delete mode 100755 main/src/main/res/values-sv/strings.xml delete mode 100755 main/src/main/res/values-tr/arrays.xml delete mode 100755 main/src/main/res/values-tr/plurals.xml delete mode 100755 main/src/main/res/values-tr/strings.xml delete mode 100755 main/src/main/res/values-uk/arrays.xml delete mode 100755 main/src/main/res/values-uk/plurals.xml delete mode 100755 main/src/main/res/values-uk/strings.xml delete mode 100644 main/src/main/res/values-v21/colours.xml delete mode 100644 main/src/main/res/values-v21/refs.xml delete mode 100644 main/src/main/res/values-v21/styles.xml delete mode 100755 main/src/main/res/values-vi/arrays.xml delete mode 100755 main/src/main/res/values-vi/plurals.xml delete mode 100755 main/src/main/res/values-vi/strings.xml delete mode 100755 main/src/main/res/values-zh-rCN/arrays.xml delete mode 100755 main/src/main/res/values-zh-rCN/plurals.xml delete mode 100755 main/src/main/res/values-zh-rCN/strings.xml delete mode 100755 main/src/main/res/values-zh-rTW/arrays.xml delete mode 100755 main/src/main/res/values-zh-rTW/plurals.xml delete mode 100755 main/src/main/res/values-zh-rTW/strings.xml delete mode 100644 main/src/main/res/xml/general_settings.xml delete mode 100644 main/src/main/res/xml/vpn_authentification.xml delete mode 100644 main/src/main/res/xml/vpn_ipsettings.xml delete mode 100644 main/src/main/res/xml/vpn_obscure.xml delete mode 100644 main/src/main/res/xml/vpn_routing.xml create mode 100644 main/src/skeleton/AndroidManifest.xml create mode 100644 main/src/skeleton/java/de/blinkt/openvpn/activities/LogWindow.java create mode 100644 main/src/skeleton/java/de/blinkt/openvpn/activities/MainActivity.java create mode 100644 main/src/ui/AndroidManifest.xml create mode 100644 main/src/ui/java/android/support/v4n/app/FragmentStatePagerAdapter.java create mode 100644 main/src/ui/java/android/support/v4n/view/PagerAdapter.java create mode 100644 main/src/ui/java/android/support/v4n/view/ViewPager.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/OpenVPNTileService.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/activities/BaseActivity.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/activities/ConfigConverter.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/activities/CreateShortcuts.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/activities/FileSelect.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/activities/LogWindow.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/activities/MainActivity.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/activities/OpenSSLSpeed.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/activities/VPNPreferences.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/AboutFragment.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/ConnectionsAdapter.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/FaqFragment.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/FaqViewAdapter.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/FileSelectionFragment.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/GeneralSettings.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/GraphFragment.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/InlineFileTab.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/KeyChainSettingsFragment.kt create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/LogFragment.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/SendDumpFragment.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/Settings_Allowed_Apps.kt create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/Settings_Authentication.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/Settings_Basic.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/Settings_Connections.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/Settings_Fragment.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/Settings_IP.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/Settings_Obscure.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/Settings_Routing.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/Settings_UserEditable.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/ShowConfigFragment.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/Utils.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/fragments/VPNProfileList.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/views/DefaultVPNListPreference.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/views/FileSelectLayout.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/views/MultiLineRadioGroup.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/views/PagerSlidingTabStrip.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/views/RemoteCNPreference.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/views/ScreenSlidePagerAdapter.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/views/SeekBarTicks.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/views/SlidingTabLayout.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/views/SlidingTabStrip.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/views/TabBarView.java create mode 100644 main/src/ui/res/anim/fab_anim.xml create mode 100644 main/src/ui/res/drawable-hdpi/ic_add_circle_outline_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_add_circle_outline_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_archive_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_archive_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_check_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_close_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_content_copy_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_delete_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_delete_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_doc_generic_am.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_edit_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_edit_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_filter_list_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_menu_copy_holo_dark.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_pause_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_play_arrow_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_receipt_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_root_folder_am.png create mode 100755 main/src/ui/res/drawable-hdpi/ic_search_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_share_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_sort_white_24dp.png create mode 100644 main/src/ui/res/drawable-hdpi/ic_warning_black_36dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_add_circle_outline_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_add_circle_outline_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_archive_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_archive_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_check_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_close_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_content_copy_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_delete_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_delete_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_doc_generic_am.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_edit_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_edit_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_filter_list_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_menu_copy_holo_dark.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_pause_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_play_arrow_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_receipt_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_root_folder_am.png create mode 100755 main/src/ui/res/drawable-mdpi/ic_search_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_share_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_sort_white_24dp.png create mode 100644 main/src/ui/res/drawable-mdpi/ic_warning_black_36dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_add_circle_outline_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_add_circle_outline_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_archive_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_archive_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_check_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_close_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_content_copy_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_delete_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_delete_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_doc_generic_am.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_edit_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_edit_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_filter_list_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_menu_copy_holo_dark.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_pause_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_play_arrow_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_receipt_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_root_folder_am.png create mode 100755 main/src/ui/res/drawable-xhdpi/ic_search_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_share_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_sort_white_24dp.png create mode 100644 main/src/ui/res/drawable-xhdpi/ic_warning_black_36dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_add_circle_outline_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_add_circle_outline_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_archive_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_archive_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_check_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_close_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_content_copy_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_delete_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_delete_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_doc_generic_am.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_edit_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_edit_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_filter_list_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_menu_copy_holo_dark.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_pause_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_receipt_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_root_folder_am.png create mode 100755 main/src/ui/res/drawable-xxhdpi/ic_search_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_share_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_sort_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxhdpi/ic_warning_black_36dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_add_circle_outline_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_add_circle_outline_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_archive_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_archive_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_check_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_close_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_content_copy_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_delete_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_delete_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_edit_grey600_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_edit_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_filter_list_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_pause_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_receipt_white_24dp.png create mode 100755 main/src/ui/res/drawable-xxxhdpi/ic_search_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_share_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_sort_white_24dp.png create mode 100644 main/src/ui/res/drawable-xxxhdpi/ic_warning_black_36dp.png create mode 100644 main/src/ui/res/drawable/bg_rect_round.xml create mode 100644 main/src/ui/res/drawable/bg_switchbar.xml create mode 100644 main/src/ui/res/drawable/bg_tabs.xml create mode 100644 main/src/ui/res/drawable/ic_shortcut_cancel.xml create mode 100644 main/src/ui/res/drawable/ic_shortcut_vpn_key.xml create mode 100644 main/src/ui/res/drawable/oval_ripple.xml create mode 100644 main/src/ui/res/drawable/slidingtab_background.xml create mode 100644 main/src/ui/res/drawable/white_rect.xml create mode 100644 main/src/ui/res/layout-sw600dp-port/log_fragment.xml create mode 100644 main/src/ui/res/layout-sw600dp/log_fragment.xml create mode 100644 main/src/ui/res/layout-v21/connection_fab.xml create mode 100644 main/src/ui/res/layout-v21/profile_list_fabs.xml create mode 100644 main/src/ui/res/layout-v21/save_fab.xml create mode 100644 main/src/ui/res/layout-v21/share_fab.xml create mode 100644 main/src/ui/res/layout-v21/tabs.xml create mode 100644 main/src/ui/res/layout/about.xml create mode 100644 main/src/ui/res/layout/allowed_application_layout.xml create mode 100644 main/src/ui/res/layout/allowed_application_settings.xml create mode 100644 main/src/ui/res/layout/allowed_vpn_apps.xml create mode 100644 main/src/ui/res/layout/basic_settings.xml create mode 100644 main/src/ui/res/layout/config_converter.xml create mode 100644 main/src/ui/res/layout/connection_fab.xml create mode 100644 main/src/ui/res/layout/connections.xml create mode 100644 main/src/ui/res/layout/extauth_provider.xml create mode 100644 main/src/ui/res/layout/faq.xml create mode 100644 main/src/ui/res/layout/faqcard.xml create mode 100644 main/src/ui/res/layout/file_dialog.xml create mode 100644 main/src/ui/res/layout/file_dialog_inline.xml create mode 100644 main/src/ui/res/layout/file_dialog_main.xml create mode 100644 main/src/ui/res/layout/file_dialog_row.xml create mode 100644 main/src/ui/res/layout/file_select.xml create mode 100644 main/src/ui/res/layout/fragment_senddump.xml create mode 100644 main/src/ui/res/layout/graph.xml create mode 100644 main/src/ui/res/layout/graph_item.xml create mode 100644 main/src/ui/res/layout/keystore_selector.xml create mode 100644 main/src/ui/res/layout/log_fragment.xml create mode 100644 main/src/ui/res/layout/log_silders.xml create mode 100644 main/src/ui/res/layout/log_window.xml create mode 100644 main/src/ui/res/layout/main_activity.xml create mode 100644 main/src/ui/res/layout/openssl_speed.xml create mode 100644 main/src/ui/res/layout/padersliding_tab.xml create mode 100644 main/src/ui/res/layout/profile_list_fabs.xml create mode 100644 main/src/ui/res/layout/save_fab.xml create mode 100644 main/src/ui/res/layout/server_card.xml create mode 100644 main/src/ui/res/layout/server_footer.xml create mode 100644 main/src/ui/res/layout/settings_usereditable.xml create mode 100644 main/src/ui/res/layout/share_fab.xml create mode 100644 main/src/ui/res/layout/speedviewitem.xml create mode 100644 main/src/ui/res/layout/tabs.xml create mode 100644 main/src/ui/res/layout/tlsremote.xml create mode 100644 main/src/ui/res/layout/viewconfig.xml create mode 100644 main/src/ui/res/layout/vpn_list_item.xml create mode 100644 main/src/ui/res/layout/vpn_profile_list.xml create mode 100644 main/src/ui/res/layout/vpnstatus.xml create mode 100644 main/src/ui/res/menu/allowed_apps.xml create mode 100644 main/src/ui/res/menu/configmenu.xml create mode 100644 main/src/ui/res/menu/connections.xml create mode 100644 main/src/ui/res/menu/import_menu.xml create mode 100644 main/src/ui/res/menu/logmenu.xml create mode 100644 main/src/ui/res/menu/main_menu.xml create mode 100644 main/src/ui/res/menu/vpnpreferences_menu.xml create mode 100755 main/src/ui/res/values-be/arrays.xml create mode 100755 main/src/ui/res/values-be/plurals.xml create mode 100755 main/src/ui/res/values-be/strings.xml create mode 100755 main/src/ui/res/values-ca/arrays.xml create mode 100755 main/src/ui/res/values-ca/plurals.xml create mode 100755 main/src/ui/res/values-ca/strings.xml create mode 100755 main/src/ui/res/values-cs/arrays.xml create mode 100755 main/src/ui/res/values-cs/plurals.xml create mode 100755 main/src/ui/res/values-cs/strings.xml create mode 100755 main/src/ui/res/values-da/arrays.xml create mode 100755 main/src/ui/res/values-da/plurals.xml create mode 100755 main/src/ui/res/values-da/strings.xml create mode 100755 main/src/ui/res/values-de/arrays.xml create mode 100755 main/src/ui/res/values-de/plurals.xml create mode 100755 main/src/ui/res/values-de/strings.xml create mode 100755 main/src/ui/res/values-es/arrays.xml create mode 100755 main/src/ui/res/values-es/plurals.xml create mode 100755 main/src/ui/res/values-es/strings.xml create mode 100755 main/src/ui/res/values-et/arrays.xml create mode 100755 main/src/ui/res/values-et/plurals.xml create mode 100755 main/src/ui/res/values-et/strings.xml create mode 100755 main/src/ui/res/values-fr/arrays.xml create mode 100755 main/src/ui/res/values-fr/plurals.xml create mode 100755 main/src/ui/res/values-fr/strings.xml create mode 100755 main/src/ui/res/values-hu/arrays.xml create mode 100755 main/src/ui/res/values-hu/plurals.xml create mode 100755 main/src/ui/res/values-hu/strings.xml create mode 100755 main/src/ui/res/values-in/arrays.xml create mode 100755 main/src/ui/res/values-in/plurals.xml create mode 100755 main/src/ui/res/values-in/strings.xml create mode 100755 main/src/ui/res/values-it/arrays.xml create mode 100755 main/src/ui/res/values-it/plurals.xml create mode 100755 main/src/ui/res/values-it/strings.xml create mode 100755 main/src/ui/res/values-ja/arrays.xml create mode 100755 main/src/ui/res/values-ja/plurals.xml create mode 100755 main/src/ui/res/values-ja/strings.xml create mode 100755 main/src/ui/res/values-ko/arrays.xml create mode 100755 main/src/ui/res/values-ko/plurals.xml create mode 100755 main/src/ui/res/values-ko/strings.xml create mode 100755 main/src/ui/res/values-nl/arrays.xml create mode 100755 main/src/ui/res/values-nl/plurals.xml create mode 100755 main/src/ui/res/values-nl/strings.xml create mode 100755 main/src/ui/res/values-no/arrays.xml create mode 100755 main/src/ui/res/values-no/plurals.xml create mode 100755 main/src/ui/res/values-no/strings.xml create mode 100755 main/src/ui/res/values-pl/arrays.xml create mode 100755 main/src/ui/res/values-pl/plurals.xml create mode 100755 main/src/ui/res/values-pl/strings.xml create mode 100755 main/src/ui/res/values-pt/arrays.xml create mode 100755 main/src/ui/res/values-pt/plurals.xml create mode 100755 main/src/ui/res/values-pt/strings.xml create mode 100755 main/src/ui/res/values-ro/arrays.xml create mode 100755 main/src/ui/res/values-ro/plurals.xml create mode 100755 main/src/ui/res/values-ro/strings.xml create mode 100755 main/src/ui/res/values-ru/arrays.xml create mode 100755 main/src/ui/res/values-ru/plurals.xml create mode 100755 main/src/ui/res/values-ru/strings.xml create mode 100755 main/src/ui/res/values-sl/arrays.xml create mode 100755 main/src/ui/res/values-sl/plurals.xml create mode 100755 main/src/ui/res/values-sl/strings.xml create mode 100755 main/src/ui/res/values-sv/arrays.xml create mode 100755 main/src/ui/res/values-sv/plurals.xml create mode 100755 main/src/ui/res/values-sv/strings.xml create mode 100755 main/src/ui/res/values-tr/arrays.xml create mode 100755 main/src/ui/res/values-tr/plurals.xml create mode 100755 main/src/ui/res/values-tr/strings.xml create mode 100755 main/src/ui/res/values-uk/arrays.xml create mode 100755 main/src/ui/res/values-uk/plurals.xml create mode 100755 main/src/ui/res/values-uk/strings.xml create mode 100644 main/src/ui/res/values-v21/colours.xml create mode 100644 main/src/ui/res/values-v21/refs.xml create mode 100644 main/src/ui/res/values-v21/styles.xml create mode 100755 main/src/ui/res/values-vi/arrays.xml create mode 100755 main/src/ui/res/values-vi/plurals.xml create mode 100755 main/src/ui/res/values-vi/strings.xml create mode 100755 main/src/ui/res/values-zh-rCN/arrays.xml create mode 100755 main/src/ui/res/values-zh-rCN/plurals.xml create mode 100755 main/src/ui/res/values-zh-rCN/strings.xml create mode 100755 main/src/ui/res/values-zh-rTW/arrays.xml create mode 100755 main/src/ui/res/values-zh-rTW/plurals.xml create mode 100755 main/src/ui/res/values-zh-rTW/strings.xml create mode 100644 main/src/ui/res/xml/general_settings.xml create mode 100644 main/src/ui/res/xml/vpn_authentification.xml create mode 100644 main/src/ui/res/xml/vpn_ipsettings.xml create mode 100644 main/src/ui/res/xml/vpn_obscure.xml create mode 100644 main/src/ui/res/xml/vpn_routing.xml (limited to 'main/src') diff --git a/main/src/main/AndroidManifest.xml b/main/src/main/AndroidManifest.xml index a9a08bf4..8df4ed79 100644 --- a/main/src/main/AndroidManifest.xml +++ b/main/src/main/AndroidManifest.xml @@ -8,18 +8,11 @@ - - - - - - - - - - - - - This version of the pager is more useful when there are a large number - * of pages, working more like a list view. When pages are not visible to - * the user, their entire fragment may be destroyed, only keeping the saved - * state of that fragment. This allows the pager to hold on to much less - * memory associated with each visited page as compared to - * {@link FragmentPagerAdapter} at the cost of potentially more overhead when - * switching between pages. - * - *

When using FragmentPagerAdapter the host ViewPager must have a - * valid ID set.

- * - *

Subclasses only need to implement {@link #getItem(int)} - * and {@link #getCount()} to have a working adapter. - * - *

Here is an example implementation of a pager containing fragments of - * lists: - * - * {@sample development/samples/Support13Demos/src/com/example/android/supportv13/app/FragmentStatePagerSupport.java - * complete} - * - *

The R.layout.fragment_pager resource of the top-level fragment is: - * - * {@sample development/samples/Support13Demos/res/layout/fragment_pager.xml - * complete} - * - *

The R.layout.fragment_pager_list resource containing each - * individual fragment's layout is: - * - * {@sample development/samples/Support13Demos/res/layout/fragment_pager_list.xml - * complete} - */ -public abstract class FragmentStatePagerAdapter extends PagerAdapter { - private static final String TAG = "FragmentStatePagerAdptr"; - private static final boolean DEBUG = false; - - private final FragmentManager mFragmentManager; - private FragmentTransaction mCurTransaction = null; - - private ArrayList mSavedState = new ArrayList(); - private ArrayList mFragments = new ArrayList(); - private Fragment mCurrentPrimaryItem = null; - - public FragmentStatePagerAdapter(FragmentManager fm) { - mFragmentManager = fm; - } - - /** - * Return the Fragment associated with a specified position. - */ - public abstract Fragment getItem(int position); - - @Override - public void startUpdate(ViewGroup container) { - } - - @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) - @Override - public Object instantiateItem(ViewGroup container, int position) { - // If we already have this item instantiated, there is nothing - // to do. This can happen when we are restoring the entire pager - // from its saved state, where the fragment manager has already - // taken care of restoring the fragments we previously had instantiated. - if (mFragments.size() > position) { - Fragment f = mFragments.get(position); - if (f != null) { - return f; - } - } - - if (mCurTransaction == null) { - mCurTransaction = mFragmentManager.beginTransaction(); - } - - Fragment fragment = getItem(position); - if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment); - if (mSavedState.size() > position) { - Fragment.SavedState fss = mSavedState.get(position); - if (fss != null) { - fragment.setInitialSavedState(fss); - } - } - while (mFragments.size() <= position) { - mFragments.add(null); - } - fragment.setMenuVisibility(false); - fragment.setUserVisibleHint(false); - mFragments.set(position, fragment); - mCurTransaction.add(container.getId(), fragment); - - return fragment; - } - - @Override - public void destroyItem(ViewGroup container, int position, Object object) { - Fragment fragment = (Fragment)object; - - if (mCurTransaction == null) { - mCurTransaction = mFragmentManager.beginTransaction(); - } - if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object - + " v=" + ((Fragment)object).getView()); - while (mSavedState.size() <= position) { - mSavedState.add(null); - } - mSavedState.set(position, mFragmentManager.saveFragmentInstanceState(fragment)); - mFragments.set(position, null); - - mCurTransaction.remove(fragment); - } - - @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) - @Override - public void setPrimaryItem(ViewGroup container, int position, Object object) { - Fragment fragment = (Fragment)object; - if (fragment != mCurrentPrimaryItem) { - if (mCurrentPrimaryItem != null) { - mCurrentPrimaryItem.setMenuVisibility(false); - mCurrentPrimaryItem.setUserVisibleHint(false); - } - if (fragment != null) { - fragment.setMenuVisibility(true); - fragment.setUserVisibleHint(true); - } - mCurrentPrimaryItem = fragment; - } - } - - @Override - public void finishUpdate(ViewGroup container) { - if (mCurTransaction != null) { - mCurTransaction.commitAllowingStateLoss(); - mCurTransaction = null; - mFragmentManager.executePendingTransactions(); - } - } - - @Override - public boolean isViewFromObject(View view, Object object) { - return ((Fragment)object).getView() == view; - } - - @Override - public Parcelable saveState() { - Bundle state = null; - if (mSavedState.size() > 0) { - state = new Bundle(); - Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()]; - mSavedState.toArray(fss); - state.putParcelableArray("states", fss); - } - for (int i=0; i keys = bundle.keySet(); - for (String key: keys) { - if (key.startsWith("f")) { - int index = Integer.parseInt(key.substring(1)); - Fragment f = mFragmentManager.getFragment(bundle, key); - if (f != null) { - while (mFragments.size() <= index) { - mFragments.add(null); - } - f.setMenuVisibility(false); - mFragments.set(index, f); - } else { - Log.w(TAG, "Bad fragment at key " + key); - } - } - } - } - } -} diff --git a/main/src/main/java/android/support/v4n/view/PagerAdapter.java b/main/src/main/java/android/support/v4n/view/PagerAdapter.java deleted file mode 100644 index 70ed75f3..00000000 --- a/main/src/main/java/android/support/v4n/view/PagerAdapter.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * 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 android.support.v4n.view; - -import android.database.DataSetObservable; -import android.database.DataSetObserver; -import android.os.Parcelable; -import android.view.View; -import android.view.ViewGroup; - -/** - * Base class providing the adapter to populate pages inside of - * a {@link ViewPager}. You will most likely want to use a more - * specific implementation of this, such as - * {@link android.support.v4n.app.FragmentPagerAdapter} or - * {@link android.support.v4.app.FragmentStatePagerAdapter}. - * - *

When you implement a PagerAdapter, you must override the following methods - * at minimum:

- *
    - *
  • {@link #instantiateItem(ViewGroup, int)}
  • - *
  • {@link #destroyItem(ViewGroup, int, Object)}
  • - *
  • {@link #getCount()}
  • - *
  • {@link #isViewFromObject(View, Object)}
  • - *
- * - *

PagerAdapter is more general than the adapters used for - * {@link android.widget.AdapterView AdapterViews}. Instead of providing a - * View recycling mechanism directly ViewPager uses callbacks to indicate the - * steps taken during an update. A PagerAdapter may implement a form of View - * recycling if desired or use a more sophisticated method of managing page - * Views such as Fragment transactions where each page is represented by its - * own Fragment.

- * - *

ViewPager associates each page with a key Object instead of working with - * Views directly. This key is used to track and uniquely identify a given page - * independent of its position in the adapter. A call to the PagerAdapter method - * {@link #startUpdate(ViewGroup)} indicates that the contents of the ViewPager - * are about to change. One or more calls to {@link #instantiateItem(ViewGroup, int)} - * and/or {@link #destroyItem(ViewGroup, int, Object)} will follow, and the end - * of an update will be signaled by a call to {@link #finishUpdate(ViewGroup)}. - * By the time {@link #finishUpdate(ViewGroup) finishUpdate} returns the views - * associated with the key objects returned by - * {@link #instantiateItem(ViewGroup, int) instantiateItem} should be added to - * the parent ViewGroup passed to these methods and the views associated with - * the keys passed to {@link #destroyItem(ViewGroup, int, Object) destroyItem} - * should be removed. The method {@link #isViewFromObject(View, Object)} identifies - * whether a page View is associated with a given key object.

- * - *

A very simple PagerAdapter may choose to use the page Views themselves - * as key objects, returning them from {@link #instantiateItem(ViewGroup, int)} - * after creation and adding them to the parent ViewGroup. A matching - * {@link #destroyItem(ViewGroup, int, Object)} implementation would remove the - * View from the parent ViewGroup and {@link #isViewFromObject(View, Object)} - * could be implemented as return view == object;.

- * - *

PagerAdapter supports data set changes. Data set changes must occur on the - * main thread and must end with a call to {@link #notifyDataSetChanged()} similar - * to AdapterView adapters derived from {@link android.widget.BaseAdapter}. A data - * set change may involve pages being added, removed, or changing position. The - * ViewPager will keep the current page active provided the adapter implements - * the method {@link #getItemPosition(Object)}.

- */ -public abstract class PagerAdapter { - private DataSetObservable mObservable = new DataSetObservable(); - - public static final int POSITION_UNCHANGED = -1; - public static final int POSITION_NONE = -2; - - /** - * Return the number of views available. - */ - public abstract int getCount(); - - /** - * Called when a change in the shown pages is going to start being made. - * @param container The containing View which is displaying this adapter's - * page views. - */ - public void startUpdate(ViewGroup container) { - startUpdate((View) container); - } - - /** - * Create the page for the given position. The adapter is responsible - * for adding the view to the container given here, although it only - * must ensure this is done by the time it returns from - * {@link #finishUpdate(ViewGroup)}. - * - * @param container The containing View in which the page will be shown. - * @param position The page position to be instantiated. - * @return Returns an Object representing the new page. This does not - * need to be a View, but can be some other container of the page. - */ - public Object instantiateItem(ViewGroup container, int position) { - return instantiateItem((View) container, position); - } - - /** - * Remove a page for the given position. The adapter is responsible - * for removing the view from its container, although it only must ensure - * this is done by the time it returns from {@link #finishUpdate(ViewGroup)}. - * - * @param container The containing View from which the page will be removed. - * @param position The page position to be removed. - * @param object The same object that was returned by - * {@link #instantiateItem(View, int)}. - */ - public void destroyItem(ViewGroup container, int position, Object object) { - destroyItem((View) container, position, object); - } - - /** - * Called to inform the adapter of which item is currently considered to - * be the "primary", that is the one show to the user as the current page. - * - * @param container The containing View from which the page will be removed. - * @param position The page position that is now the primary. - * @param object The same object that was returned by - * {@link #instantiateItem(View, int)}. - */ - public void setPrimaryItem(ViewGroup container, int position, Object object) { - setPrimaryItem((View) container, position, object); - } - - /** - * Called when the a change in the shown pages has been completed. At this - * point you must ensure that all of the pages have actually been added or - * removed from the container as appropriate. - * @param container The containing View which is displaying this adapter's - * page views. - */ - public void finishUpdate(ViewGroup container) { - finishUpdate((View) container); - } - - /** - * Called when a change in the shown pages is going to start being made. - * @param container The containing View which is displaying this adapter's - * page views. - * - * @deprecated Use {@link #startUpdate(ViewGroup)} - */ - public void startUpdate(View container) { - } - - /** - * Create the page for the given position. The adapter is responsible - * for adding the view to the container given here, although it only - * must ensure this is done by the time it returns from - * {@link #finishUpdate(ViewGroup)}. - * - * @param container The containing View in which the page will be shown. - * @param position The page position to be instantiated. - * @return Returns an Object representing the new page. This does not - * need to be a View, but can be some other container of the page. - * - * @deprecated Use {@link #instantiateItem(ViewGroup, int)} - */ - public Object instantiateItem(View container, int position) { - throw new UnsupportedOperationException( - "Required method instantiateItem was not overridden"); - } - - /** - * Remove a page for the given position. The adapter is responsible - * for removing the view from its container, although it only must ensure - * this is done by the time it returns from {@link #finishUpdate(View)}. - * - * @param container The containing View from which the page will be removed. - * @param position The page position to be removed. - * @param object The same object that was returned by - * {@link #instantiateItem(View, int)}. - * - * @deprecated Use {@link #destroyItem(ViewGroup, int, Object)} - */ - public void destroyItem(View container, int position, Object object) { - throw new UnsupportedOperationException("Required method destroyItem was not overridden"); - } - - /** - * Called to inform the adapter of which item is currently considered to - * be the "primary", that is the one show to the user as the current page. - * - * @param container The containing View from which the page will be removed. - * @param position The page position that is now the primary. - * @param object The same object that was returned by - * {@link #instantiateItem(View, int)}. - * - * @deprecated Use {@link #setPrimaryItem(ViewGroup, int, Object)} - */ - public void setPrimaryItem(View container, int position, Object object) { - } - - /** - * Called when the a change in the shown pages has been completed. At this - * point you must ensure that all of the pages have actually been added or - * removed from the container as appropriate. - * @param container The containing View which is displaying this adapter's - * page views. - * - * @deprecated Use {@link #finishUpdate(ViewGroup)} - */ - public void finishUpdate(View container) { - } - - /** - * Determines whether a page View is associated with a specific key object - * as returned by {@link #instantiateItem(ViewGroup, int)}. This method is - * required for a PagerAdapter to function properly. - * - * @param view Page View to check for association with object - * @param object Object to check for association with view - * @return true if view is associated with the key object object - */ - public abstract boolean isViewFromObject(View view, Object object); - - /** - * Save any instance state associated with this adapter and its pages that should be - * restored if the current UI state needs to be reconstructed. - * - * @return Saved state for this adapter - */ - public Parcelable saveState() { - return null; - } - - /** - * Restore any instance state associated with this adapter and its pages - * that was previously saved by {@link #saveState()}. - * - * @param state State previously saved by a call to {@link #saveState()} - * @param loader A ClassLoader that should be used to instantiate any restored objects - */ - public void restoreState(Parcelable state, ClassLoader loader) { - } - - /** - * Called when the host view is attempting to determine if an item's position - * has changed. Returns {@link #POSITION_UNCHANGED} if the position of the given - * item has not changed or {@link #POSITION_NONE} if the item is no longer present - * in the adapter. - * - *

The default implementation assumes that items will never - * change position and always returns {@link #POSITION_UNCHANGED}. - * - * @param object Object representing an item, previously returned by a call to - * {@link #instantiateItem(View, int)}. - * @return object's new position index from [0, {@link #getCount()}), - * {@link #POSITION_UNCHANGED} if the object's position has not changed, - * or {@link #POSITION_NONE} if the item is no longer present. - */ - public int getItemPosition(Object object) { - return POSITION_UNCHANGED; - } - - /** - * This method should be called by the application if the data backing this adapter has changed - * and associated views should update. - */ - public void notifyDataSetChanged() { - mObservable.notifyChanged(); - } - - /** - * Register an observer to receive callbacks related to the adapter's data changing. - * - * @param observer The {@link android.database.DataSetObserver} which will receive callbacks. - */ - public void registerDataSetObserver(DataSetObserver observer) { - mObservable.registerObserver(observer); - } - - /** - * Unregister an observer from callbacks related to the adapter's data changing. - * - * @param observer The {@link android.database.DataSetObserver} which will be unregistered. - */ - public void unregisterDataSetObserver(DataSetObserver observer) { - mObservable.unregisterObserver(observer); - } - - /** - * This method may be called by the ViewPager to obtain a title string - * to describe the specified page. This method may return null - * indicating no title for this page. The default implementation returns - * null. - * - * @param position The position of the title requested - * @return A title for the requested page - */ - public CharSequence getPageTitle(int position) { - return null; - } - - /** - * Returns the proportional width of a given page as a percentage of the - * ViewPager's measured width from (0.f-1.f] - * - * @param position The position of the page requested - * @return Proportional width for the given page position - */ - public float getPageWidth(int position) { - return 1.f; - } -} diff --git a/main/src/main/java/android/support/v4n/view/ViewPager.java b/main/src/main/java/android/support/v4n/view/ViewPager.java deleted file mode 100644 index 6009af62..00000000 --- a/main/src/main/java/android/support/v4n/view/ViewPager.java +++ /dev/null @@ -1,2895 +0,0 @@ -/* - * 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 android.support.v4n.view; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.database.DataSetObserver; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.SystemClock; -import android.support.annotation.DrawableRes; -import android.support.v4.os.ParcelableCompat; -import android.support.v4.os.ParcelableCompatCreatorCallbacks; -import android.support.v4.view.AccessibilityDelegateCompat; -import android.support.v4.view.MotionEventCompat; -import android.support.v4.view.VelocityTrackerCompat; -import android.support.v4.view.ViewCompat; -import android.support.v4.view.ViewConfigurationCompat; -import android.support.v4.view.accessibility.AccessibilityEventCompat; -import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; -import android.support.v4.view.accessibility.AccessibilityRecordCompat; -import android.support.v4.widget.EdgeEffectCompat; -import android.util.AttributeSet; -import android.util.Log; -import android.view.FocusFinder; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.SoundEffectConstants; -import android.view.VelocityTracker; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.view.accessibility.AccessibilityEvent; -import android.view.animation.Interpolator; -import android.widget.Scroller; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; - -/** - * Layout manager that allows the user to flip left and right - * through pages of data. You supply an implementation of a - * {@link PagerAdapter} to generate the pages that the view shows. - * - *

Note this class is currently under early design and - * development. The API will likely change in later updates of - * the compatibility library, requiring changes to the source code - * of apps when they are compiled against the newer version.

- * - *

ViewPager is most often used in conjunction with {@link android.app.Fragment}, - * which is a convenient way to supply and manage the lifecycle of each page. - * There are standard adapters implemented for using fragments with the ViewPager, - * which cover the most common use cases. These are - * {@link android.support.v4n.app.FragmentPagerAdapter} and - * {@link android.support.v4.app.FragmentStatePagerAdapter}; each of these - * classes have simple code showing how to build a full user interface - * with them. - * - *

For more information about how to use ViewPager, read Creating Swipe Views with - * Tabs.

- * - *

Below is a more complicated example of ViewPager, using it in conjunction - * with {@link android.app.ActionBar} tabs. You can find other examples of using - * ViewPager in the API 4+ Support Demos and API 13+ Support Demos sample code. - * - * {@sample development/samples/Support13Demos/src/com/example/android/supportv13/app/ActionBarTabsPager.java - * complete} - */ -public class ViewPager extends ViewGroup { - private static final String TAG = "ViewPager"; - private static final boolean DEBUG = false; - - private static final boolean USE_CACHE = false; - - private static final int DEFAULT_OFFSCREEN_PAGES = 1; - private static final int MAX_SETTLE_DURATION = 600; // ms - private static final int MIN_DISTANCE_FOR_FLING = 25; // dips - - private static final int DEFAULT_GUTTER_SIZE = 16; // dips - - private static final int MIN_FLING_VELOCITY = 400; // dips - - private static final int[] LAYOUT_ATTRS = new int[] { - android.R.attr.layout_gravity - }; - - /** - * Used to track what the expected number of items in the adapter should be. - * If the app changes this when we don't expect it, we'll throw a big obnoxious exception. - */ - private int mExpectedAdapterCount; - - static class ItemInfo { - Object object; - int position; - boolean scrolling; - float widthFactor; - float offset; - } - - private static final Comparator COMPARATOR = new Comparator(){ - @Override - public int compare(ItemInfo lhs, ItemInfo rhs) { - return lhs.position - rhs.position; - } - }; - - private static final Interpolator sInterpolator = new Interpolator() { - public float getInterpolation(float t) { - t -= 1.0f; - return t * t * t * t * t + 1.0f; - } - }; - - private final ArrayList mItems = new ArrayList(); - private final ItemInfo mTempItem = new ItemInfo(); - - private final Rect mTempRect = new Rect(); - - private PagerAdapter mAdapter; - private int mCurItem; // Index of currently displayed page. - private int mRestoredCurItem = -1; - private Parcelable mRestoredAdapterState = null; - private ClassLoader mRestoredClassLoader = null; - private Scroller mScroller; - private PagerObserver mObserver; - - private int mPageMargin; - private Drawable mMarginDrawable; - private int mTopPageBounds; - private int mBottomPageBounds; - - // Offsets of the first and last items, if known. - // Set during population, used to determine if we are at the beginning - // or end of the pager data set during touch scrolling. - private float mFirstOffset = -Float.MAX_VALUE; - private float mLastOffset = Float.MAX_VALUE; - - private int mChildWidthMeasureSpec; - private int mChildHeightMeasureSpec; - private boolean mInLayout; - - private boolean mScrollingCacheEnabled; - - private boolean mPopulatePending; - private int mOffscreenPageLimit = DEFAULT_OFFSCREEN_PAGES; - - private boolean mIsBeingDragged; - private boolean mIsUnableToDrag; - private boolean mIgnoreGutter; - private int mDefaultGutterSize; - private int mGutterSize; - private int mTouchSlop; - /** - * Position of the last motion event. - */ - private float mLastMotionX; - private float mLastMotionY; - private float mInitialMotionX; - private float mInitialMotionY; - /** - * ID of the active pointer. This is used to retain consistency during - * drags/flings if multiple pointers are used. - */ - private int mActivePointerId = INVALID_POINTER; - /** - * Sentinel value for no current active pointer. - * Used by {@link #mActivePointerId}. - */ - private static final int INVALID_POINTER = -1; - - /** - * Determines speed during touch scrolling - */ - private VelocityTracker mVelocityTracker; - private int mMinimumVelocity; - private int mMaximumVelocity; - private int mFlingDistance; - private int mCloseEnough; - - // If the pager is at least this close to its final position, complete the scroll - // on touch down and let the user interact with the content inside instead of - // "catching" the flinging pager. - private static final int CLOSE_ENOUGH = 2; // dp - - private boolean mFakeDragging; - private long mFakeDragBeginTime; - - private EdgeEffectCompat mLeftEdge; - private EdgeEffectCompat mRightEdge; - - private boolean mFirstLayout = true; - private boolean mNeedCalculatePageOffsets = false; - private boolean mCalledSuper; - private int mDecorChildCount; - - private OnPageChangeListener mOnPageChangeListener; - private OnPageChangeListener mInternalPageChangeListener; - private OnAdapterChangeListener mAdapterChangeListener; - private PageTransformer mPageTransformer; - private Method mSetChildrenDrawingOrderEnabled; - - private static final int DRAW_ORDER_DEFAULT = 0; - private static final int DRAW_ORDER_FORWARD = 1; - private static final int DRAW_ORDER_REVERSE = 2; - private int mDrawingOrder; - private ArrayList mDrawingOrderedChildren; - private static final ViewPositionComparator sPositionComparator = new ViewPositionComparator(); - - /** - * Indicates that the pager is in an idle, settled state. The current page - * is fully in view and no animation is in progress. - */ - public static final int SCROLL_STATE_IDLE = 0; - - /** - * Indicates that the pager is currently being dragged by the user. - */ - public static final int SCROLL_STATE_DRAGGING = 1; - - /** - * Indicates that the pager is in the process of settling to a final position. - */ - public static final int SCROLL_STATE_SETTLING = 2; - - private final Runnable mEndScrollRunnable = new Runnable() { - public void run() { - setScrollState(SCROLL_STATE_IDLE); - populate(); - } - }; - - private int mScrollState = SCROLL_STATE_IDLE; - - /** - * Callback interface for responding to changing state of the selected page. - */ - public interface OnPageChangeListener { - - /** - * This method will be invoked when the current page is scrolled, either as part - * of a programmatically initiated smooth scroll or a user initiated touch scroll. - * - * @param position Position index of the first page currently being displayed. - * Page position+1 will be visible if positionOffset is nonzero. - * @param positionOffset Value from [0, 1) indicating the offset from the page at position. - * @param positionOffsetPixels Value in pixels indicating the offset from position. - */ - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels); - - /** - * This method will be invoked when a new page becomes selected. Animation is not - * necessarily complete. - * - * @param position Position index of the new selected page. - */ - public void onPageSelected(int position); - - /** - * Called when the scroll state changes. Useful for discovering when the user - * begins dragging, when the pager is automatically settling to the current page, - * or when it is fully stopped/idle. - * - * @param state The new scroll state. - * @see ViewPager#SCROLL_STATE_IDLE - * @see ViewPager#SCROLL_STATE_DRAGGING - * @see ViewPager#SCROLL_STATE_SETTLING - */ - public void onPageScrollStateChanged(int state); - } - - /** - * Simple implementation of the {@link OnPageChangeListener} interface with stub - * implementations of each method. Extend this if you do not intend to override - * every method of {@link OnPageChangeListener}. - */ - public static class SimpleOnPageChangeListener implements OnPageChangeListener { - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - // This space for rent - } - - @Override - public void onPageSelected(int position) { - // This space for rent - } - - @Override - public void onPageScrollStateChanged(int state) { - // This space for rent - } - } - - /** - * A PageTransformer is invoked whenever a visible/attached page is scrolled. - * This offers an opportunity for the application to apply a custom transformation - * to the page views using animation properties. - * - *

As property animation is only supported as of Android 3.0 and forward, - * setting a PageTransformer on a ViewPager on earlier platform versions will - * be ignored.

- */ - public interface PageTransformer { - /** - * Apply a property transformation to the given page. - * - * @param page Apply the transformation to this page - * @param position Position of page relative to the current front-and-center - * position of the pager. 0 is front and center. 1 is one full - * page position to the right, and -1 is one page position to the left. - */ - public void transformPage(View page, float position); - } - - /** - * Used internally to monitor when adapters are switched. - */ - interface OnAdapterChangeListener { - public void onAdapterChanged(PagerAdapter oldAdapter, PagerAdapter newAdapter); - } - - /** - * Used internally to tag special types of child views that should be added as - * pager decorations by default. - */ - interface Decor {} - - public ViewPager(Context context) { - super(context); - initViewPager(); - } - - public ViewPager(Context context, AttributeSet attrs) { - super(context, attrs); - initViewPager(); - } - - void initViewPager() { - setWillNotDraw(false); - setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); - setFocusable(true); - final Context context = getContext(); - mScroller = new Scroller(context, sInterpolator); - final ViewConfiguration configuration = ViewConfiguration.get(context); - final float density = context.getResources().getDisplayMetrics().density; - - mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration); - mMinimumVelocity = (int) (MIN_FLING_VELOCITY * density); - mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); - mLeftEdge = new EdgeEffectCompat(context); - mRightEdge = new EdgeEffectCompat(context); - - mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density); - mCloseEnough = (int) (CLOSE_ENOUGH * density); - mDefaultGutterSize = (int) (DEFAULT_GUTTER_SIZE * density); - - ViewCompat.setAccessibilityDelegate(this, new MyAccessibilityDelegate()); - - if (ViewCompat.getImportantForAccessibility(this) - == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { - ViewCompat.setImportantForAccessibility(this, - ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); - } - } - - @Override - protected void onDetachedFromWindow() { - removeCallbacks(mEndScrollRunnable); - super.onDetachedFromWindow(); - } - - private void setScrollState(int newState) { - if (mScrollState == newState) { - return; - } - - mScrollState = newState; - if (mPageTransformer != null) { - // PageTransformers can do complex things that benefit from hardware layers. - enableLayers(newState != SCROLL_STATE_IDLE); - } - if (mOnPageChangeListener != null) { - mOnPageChangeListener.onPageScrollStateChanged(newState); - } - } - - /** - * Set a PagerAdapter that will supply views for this pager as needed. - * - * @param adapter Adapter to use - */ - public void setAdapter(PagerAdapter adapter) { - if (mAdapter != null) { - mAdapter.unregisterDataSetObserver(mObserver); - mAdapter.startUpdate(this); - for (int i = 0; i < mItems.size(); i++) { - final ItemInfo ii = mItems.get(i); - mAdapter.destroyItem(this, ii.position, ii.object); - } - mAdapter.finishUpdate(this); - mItems.clear(); - removeNonDecorViews(); - mCurItem = 0; - scrollTo(0, 0); - } - - final PagerAdapter oldAdapter = mAdapter; - mAdapter = adapter; - mExpectedAdapterCount = 0; - - if (mAdapter != null) { - if (mObserver == null) { - mObserver = new PagerObserver(); - } - mAdapter.registerDataSetObserver(mObserver); - mPopulatePending = false; - final boolean wasFirstLayout = mFirstLayout; - mFirstLayout = true; - mExpectedAdapterCount = mAdapter.getCount(); - if (mRestoredCurItem >= 0) { - mAdapter.restoreState(mRestoredAdapterState, mRestoredClassLoader); - setCurrentItemInternal(mRestoredCurItem, false, true); - mRestoredCurItem = -1; - mRestoredAdapterState = null; - mRestoredClassLoader = null; - } else if (!wasFirstLayout) { - populate(); - } else { - requestLayout(); - } - } - - if (mAdapterChangeListener != null && oldAdapter != adapter) { - mAdapterChangeListener.onAdapterChanged(oldAdapter, adapter); - } - } - - private void removeNonDecorViews() { - for (int i = 0; i < getChildCount(); i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if (!lp.isDecor) { - removeViewAt(i); - i--; - } - } - } - - /** - * Retrieve the current adapter supplying pages. - * - * @return The currently registered PagerAdapter - */ - public PagerAdapter getAdapter() { - return mAdapter; - } - - void setOnAdapterChangeListener(OnAdapterChangeListener listener) { - mAdapterChangeListener = listener; - } - - private int getClientWidth() { - return getMeasuredWidth() - getPaddingLeft() - getPaddingRight(); - } - - /** - * Set the currently selected page. If the ViewPager has already been through its first - * layout with its current adapter there will be a smooth animated transition between - * the current item and the specified item. - * - * @param item Item index to select - */ - public void setCurrentItem(int item) { - mPopulatePending = false; - setCurrentItemInternal(item, !mFirstLayout, false); - } - - /** - * Set the currently selected page. - * - * @param item Item index to select - * @param smoothScroll True to smoothly scroll to the new item, false to transition immediately - */ - public void setCurrentItem(int item, boolean smoothScroll) { - mPopulatePending = false; - setCurrentItemInternal(item, smoothScroll, false); - } - - public int getCurrentItem() { - return mCurItem; - } - - void setCurrentItemInternal(int item, boolean smoothScroll, boolean always) { - setCurrentItemInternal(item, smoothScroll, always, 0); - } - - void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) { - if (mAdapter == null || mAdapter.getCount() <= 0) { - setScrollingCacheEnabled(false); - return; - } - if (!always && mCurItem == item && mItems.size() != 0) { - setScrollingCacheEnabled(false); - return; - } - - if (item < 0) { - item = 0; - } else if (item >= mAdapter.getCount()) { - item = mAdapter.getCount() - 1; - } - final int pageLimit = mOffscreenPageLimit; - if (item > (mCurItem + pageLimit) || item < (mCurItem - pageLimit)) { - // We are doing a jump by more than one page. To avoid - // glitches, we want to keep all current pages in the view - // until the scroll ends. - for (int i=0; iNote: Prior to Android 3.0 the property animation APIs did not exist. - * As a result, setting a PageTransformer prior to Android 3.0 (API 11) will have no effect.

- * - * @param reverseDrawingOrder true if the supplied PageTransformer requires page views - * to be drawn from last to first instead of first to last. - * @param transformer PageTransformer that will modify each page's animation properties - */ - public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) { - if (Build.VERSION.SDK_INT >= 11) { - final boolean hasTransformer = transformer != null; - final boolean needsPopulate = hasTransformer != (mPageTransformer != null); - mPageTransformer = transformer; - setChildrenDrawingOrderEnabledCompat(hasTransformer); - if (hasTransformer) { - mDrawingOrder = reverseDrawingOrder ? DRAW_ORDER_REVERSE : DRAW_ORDER_FORWARD; - } else { - mDrawingOrder = DRAW_ORDER_DEFAULT; - } - if (needsPopulate) populate(); - } - } - - void setChildrenDrawingOrderEnabledCompat(boolean enable) { - if (Build.VERSION.SDK_INT >= 7) { - if (mSetChildrenDrawingOrderEnabled == null) { - try { - mSetChildrenDrawingOrderEnabled = ViewGroup.class.getDeclaredMethod( - "setChildrenDrawingOrderEnabled", new Class[] { Boolean.TYPE }); - } catch (NoSuchMethodException e) { - Log.e(TAG, "Can't find setChildrenDrawingOrderEnabled", e); - } - } - try { - mSetChildrenDrawingOrderEnabled.invoke(this, enable); - } catch (Exception e) { - Log.e(TAG, "Error changing children drawing order", e); - } - } - } - - @Override - protected int getChildDrawingOrder(int childCount, int i) { - final int index = mDrawingOrder == DRAW_ORDER_REVERSE ? childCount - 1 - i : i; - final int result = ((LayoutParams) mDrawingOrderedChildren.get(index).getLayoutParams()).childIndex; - return result; - } - - /** - * Set a separate OnPageChangeListener for internal use by the support library. - * - * @param listener Listener to set - * @return The old listener that was set, if any. - */ - OnPageChangeListener setInternalPageChangeListener(OnPageChangeListener listener) { - OnPageChangeListener oldListener = mInternalPageChangeListener; - mInternalPageChangeListener = listener; - return oldListener; - } - - /** - * Returns the number of pages that will be retained to either side of the - * current page in the view hierarchy in an idle state. Defaults to 1. - * - * @return How many pages will be kept offscreen on either side - * @see #setOffscreenPageLimit(int) - */ - public int getOffscreenPageLimit() { - return mOffscreenPageLimit; - } - - /** - * Set the number of pages that should be retained to either side of the - * current page in the view hierarchy in an idle state. Pages beyond this - * limit will be recreated from the adapter when needed. - * - *

This is offered as an optimization. If you know in advance the number - * of pages you will need to support or have lazy-loading mechanisms in place - * on your pages, tweaking this setting can have benefits in perceived smoothness - * of paging animations and interaction. If you have a small number of pages (3-4) - * that you can keep active all at once, less time will be spent in layout for - * newly created view subtrees as the user pages back and forth.

- * - *

You should keep this limit low, especially if your pages have complex layouts. - * This setting defaults to 1.

- * - * @param limit How many pages will be kept offscreen in an idle state. - */ - public void setOffscreenPageLimit(int limit) { - if (limit < DEFAULT_OFFSCREEN_PAGES) { - Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " + - DEFAULT_OFFSCREEN_PAGES); - limit = DEFAULT_OFFSCREEN_PAGES; - } - if (limit != mOffscreenPageLimit) { - mOffscreenPageLimit = limit; - populate(); - } - } - - /** - * Set the margin between pages. - * - * @param marginPixels Distance between adjacent pages in pixels - * @see #getPageMargin() - * @see #setPageMarginDrawable(Drawable) - * @see #setPageMarginDrawable(int) - */ - public void setPageMargin(int marginPixels) { - final int oldMargin = mPageMargin; - mPageMargin = marginPixels; - - final int width = getWidth(); - recomputeScrollPosition(width, width, marginPixels, oldMargin); - - requestLayout(); - } - - /** - * Return the margin between pages. - * - * @return The size of the margin in pixels - */ - public int getPageMargin() { - return mPageMargin; - } - - /** - * Set a drawable that will be used to fill the margin between pages. - * - * @param d Drawable to display between pages - */ - public void setPageMarginDrawable(Drawable d) { - mMarginDrawable = d; - if (d != null) refreshDrawableState(); - setWillNotDraw(d == null); - invalidate(); - } - - /** - * Set a drawable that will be used to fill the margin between pages. - * - * @param resId Resource ID of a drawable to display between pages - */ - public void setPageMarginDrawable(@DrawableRes int resId) { - setPageMarginDrawable(getContext().getResources().getDrawable(resId)); - } - - @Override - protected boolean verifyDrawable(Drawable who) { - return super.verifyDrawable(who) || who == mMarginDrawable; - } - - @Override - protected void drawableStateChanged() { - super.drawableStateChanged(); - final Drawable d = mMarginDrawable; - if (d != null && d.isStateful()) { - d.setState(getDrawableState()); - } - } - - // We want the duration of the page snap animation to be influenced by the distance that - // the screen has to travel, however, we don't want this duration to be effected in a - // purely linear fashion. Instead, we use this method to moderate the effect that the distance - // of travel has on the overall snap duration. - float distanceInfluenceForSnapDuration(float f) { - f -= 0.5f; // center the values about 0. - f *= 0.3f * Math.PI / 2.0f; - return (float) Math.sin(f); - } - - /** - * Like {@link View#scrollBy}, but scroll smoothly instead of immediately. - * - * @param x the number of pixels to scroll by on the X axis - * @param y the number of pixels to scroll by on the Y axis - */ - void smoothScrollTo(int x, int y) { - smoothScrollTo(x, y, 0); - } - - /** - * Like {@link View#scrollBy}, but scroll smoothly instead of immediately. - * - * @param x the number of pixels to scroll by on the X axis - * @param y the number of pixels to scroll by on the Y axis - * @param velocity the velocity associated with a fling, if applicable. (0 otherwise) - */ - void smoothScrollTo(int x, int y, int velocity) { - if (getChildCount() == 0) { - // Nothing to do. - setScrollingCacheEnabled(false); - return; - } - int sx = getScrollX(); - int sy = getScrollY(); - int dx = x - sx; - int dy = y - sy; - if (dx == 0 && dy == 0) { - completeScroll(false); - populate(); - setScrollState(SCROLL_STATE_IDLE); - return; - } - - setScrollingCacheEnabled(true); - setScrollState(SCROLL_STATE_SETTLING); - - final int width = getClientWidth(); - final int halfWidth = width / 2; - final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dx) / width); - final float distance = halfWidth + halfWidth * - distanceInfluenceForSnapDuration(distanceRatio); - - int duration = 0; - velocity = Math.abs(velocity); - if (velocity > 0) { - duration = 4 * Math.round(1000 * Math.abs(distance / velocity)); - } else { - final float pageWidth = width * mAdapter.getPageWidth(mCurItem); - final float pageDelta = (float) Math.abs(dx) / (pageWidth + mPageMargin); - duration = (int) ((pageDelta + 1) * 100); - } - duration = Math.min(duration, MAX_SETTLE_DURATION); - - mScroller.startScroll(sx, sy, dx, dy, duration); - ViewCompat.postInvalidateOnAnimation(this); - } - - ItemInfo addNewItem(int position, int index) { - ItemInfo ii = new ItemInfo(); - ii.position = position; - ii.object = mAdapter.instantiateItem(this, position); - ii.widthFactor = mAdapter.getPageWidth(position); - if (index < 0 || index >= mItems.size()) { - mItems.add(ii); - } else { - mItems.add(index, ii); - } - return ii; - } - - void dataSetChanged() { - // This method only gets called if our observer is attached, so mAdapter is non-null. - - final int adapterCount = mAdapter.getCount(); - mExpectedAdapterCount = adapterCount; - boolean needPopulate = mItems.size() < mOffscreenPageLimit * 2 + 1 && - mItems.size() < adapterCount; - int newCurrItem = mCurItem; - - boolean isUpdating = false; - for (int i = 0; i < mItems.size(); i++) { - final ItemInfo ii = mItems.get(i); - final int newPos = mAdapter.getItemPosition(ii.object); - - if (newPos == PagerAdapter.POSITION_UNCHANGED) { - continue; - } - - if (newPos == PagerAdapter.POSITION_NONE) { - mItems.remove(i); - i--; - - if (!isUpdating) { - mAdapter.startUpdate(this); - isUpdating = true; - } - - mAdapter.destroyItem(this, ii.position, ii.object); - needPopulate = true; - - if (mCurItem == ii.position) { - // Keep the current item in the valid range - newCurrItem = Math.max(0, Math.min(mCurItem, adapterCount - 1)); - needPopulate = true; - } - continue; - } - - if (ii.position != newPos) { - if (ii.position == mCurItem) { - // Our current item changed position. Follow it. - newCurrItem = newPos; - } - - ii.position = newPos; - needPopulate = true; - } - } - - if (isUpdating) { - mAdapter.finishUpdate(this); - } - - Collections.sort(mItems, COMPARATOR); - - if (needPopulate) { - // Reset our known page widths; populate will recompute them. - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if (!lp.isDecor) { - lp.widthFactor = 0.f; - } - } - - setCurrentItemInternal(newCurrItem, false, true); - requestLayout(); - } - } - - void populate() { - populate(mCurItem); - } - - void populate(int newCurrentItem) { - ItemInfo oldCurInfo = null; - int focusDirection = View.FOCUS_FORWARD; - if (mCurItem != newCurrentItem) { - focusDirection = mCurItem < newCurrentItem ? View.FOCUS_RIGHT : View.FOCUS_LEFT; - oldCurInfo = infoForPosition(mCurItem); - mCurItem = newCurrentItem; - } - - if (mAdapter == null) { - sortChildDrawingOrder(); - return; - } - - // Bail now if we are waiting to populate. This is to hold off - // on creating views from the time the user releases their finger to - // fling to a new position until we have finished the scroll to - // that position, avoiding glitches from happening at that point. - if (mPopulatePending) { - if (DEBUG) Log.i(TAG, "populate is pending, skipping for now..."); - sortChildDrawingOrder(); - return; - } - - // Also, don't populate until we are attached to a window. This is to - // avoid trying to populate before we have restored our view hierarchy - // state and conflicting with what is restored. - if (getWindowToken() == null) { - return; - } - - mAdapter.startUpdate(this); - - final int pageLimit = mOffscreenPageLimit; - final int startPos = Math.max(0, mCurItem - pageLimit); - final int N = mAdapter.getCount(); - final int endPos = Math.min(N-1, mCurItem + pageLimit); - - if (N != mExpectedAdapterCount) { - String resName; - try { - resName = getResources().getResourceName(getId()); - } catch (Resources.NotFoundException e) { - resName = Integer.toHexString(getId()); - } - throw new IllegalStateException("The application's PagerAdapter changed the adapter's" + - " contents without calling PagerAdapter#notifyDataSetChanged!" + - " Expected adapter item count: " + mExpectedAdapterCount + ", found: " + N + - " Pager id: " + resName + - " Pager class: " + getClass() + - " Problematic adapter: " + mAdapter.getClass()); - } - - // Locate the currently focused item or add it if needed. - int curIndex = -1; - ItemInfo curItem = null; - for (curIndex = 0; curIndex < mItems.size(); curIndex++) { - final ItemInfo ii = mItems.get(curIndex); - if (ii.position >= mCurItem) { - if (ii.position == mCurItem) curItem = ii; - break; - } - } - - if (curItem == null && N > 0) { - curItem = addNewItem(mCurItem, curIndex); - } - - // Fill 3x the available width or up to the number of offscreen - // pages requested to either side, whichever is larger. - // If we have no current item we have no work to do. - if (curItem != null) { - float extraWidthLeft = 0.f; - int itemIndex = curIndex - 1; - ItemInfo ii = itemIndex >= 0 ? mItems.get(itemIndex) : null; - final int clientWidth = getClientWidth(); - final float leftWidthNeeded = clientWidth <= 0 ? 0 : - 2.f - curItem.widthFactor + (float) getPaddingLeft() / (float) clientWidth; - for (int pos = mCurItem - 1; pos >= 0; pos--) { - if (extraWidthLeft >= leftWidthNeeded && pos < startPos) { - if (ii == null) { - break; - } - if (pos == ii.position && !ii.scrolling) { - mItems.remove(itemIndex); - mAdapter.destroyItem(this, pos, ii.object); - if (DEBUG) { - Log.i(TAG, "populate() - destroyItem() with pos: " + pos + - " view: " + ii.object); - } - itemIndex--; - curIndex--; - ii = itemIndex >= 0 ? mItems.get(itemIndex) : null; - } - } else if (ii != null && pos == ii.position) { - extraWidthLeft += ii.widthFactor; - itemIndex--; - ii = itemIndex >= 0 ? mItems.get(itemIndex) : null; - } else { - ii = addNewItem(pos, itemIndex + 1); - extraWidthLeft += ii.widthFactor; - curIndex++; - ii = itemIndex >= 0 ? mItems.get(itemIndex) : null; - } - } - - float extraWidthRight = curItem.widthFactor; - itemIndex = curIndex + 1; - if (extraWidthRight < 2.f) { - ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null; - final float rightWidthNeeded = clientWidth <= 0 ? 0 : - (float) getPaddingRight() / (float) clientWidth + 2.f; - for (int pos = mCurItem + 1; pos < N; pos++) { - if (extraWidthRight >= rightWidthNeeded && pos > endPos) { - if (ii == null) { - break; - } - if (pos == ii.position && !ii.scrolling) { - mItems.remove(itemIndex); - mAdapter.destroyItem(this, pos, ii.object); - if (DEBUG) { - Log.i(TAG, "populate() - destroyItem() with pos: " + pos + - " view: " + (ii.object)); - } - ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null; - } - } else if (ii != null && pos == ii.position) { - extraWidthRight += ii.widthFactor; - itemIndex++; - ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null; - } else { - ii = addNewItem(pos, itemIndex); - itemIndex++; - extraWidthRight += ii.widthFactor; - ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null; - } - } - } - - calculatePageOffsets(curItem, curIndex, oldCurInfo); - } - - if (DEBUG) { - Log.i(TAG, "Current page list:"); - for (int i=0; i(); - } else { - mDrawingOrderedChildren.clear(); - } - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - mDrawingOrderedChildren.add(child); - } - Collections.sort(mDrawingOrderedChildren, sPositionComparator); - } - } - - private void calculatePageOffsets(ItemInfo curItem, int curIndex, ItemInfo oldCurInfo) { - final int N = mAdapter.getCount(); - final int width = getClientWidth(); - final float marginOffset = width > 0 ? (float) mPageMargin / width : 0; - // Fix up offsets for later layout. - if (oldCurInfo != null) { - final int oldCurPosition = oldCurInfo.position; - // Base offsets off of oldCurInfo. - if (oldCurPosition < curItem.position) { - int itemIndex = 0; - ItemInfo ii = null; - float offset = oldCurInfo.offset + oldCurInfo.widthFactor + marginOffset; - for (int pos = oldCurPosition + 1; - pos <= curItem.position && itemIndex < mItems.size(); pos++) { - ii = mItems.get(itemIndex); - while (pos > ii.position && itemIndex < mItems.size() - 1) { - itemIndex++; - ii = mItems.get(itemIndex); - } - while (pos < ii.position) { - // We don't have an item populated for this, - // ask the adapter for an offset. - offset += mAdapter.getPageWidth(pos) + marginOffset; - pos++; - } - ii.offset = offset; - offset += ii.widthFactor + marginOffset; - } - } else if (oldCurPosition > curItem.position) { - int itemIndex = mItems.size() - 1; - ItemInfo ii = null; - float offset = oldCurInfo.offset; - for (int pos = oldCurPosition - 1; - pos >= curItem.position && itemIndex >= 0; pos--) { - ii = mItems.get(itemIndex); - while (pos < ii.position && itemIndex > 0) { - itemIndex--; - ii = mItems.get(itemIndex); - } - while (pos > ii.position) { - // We don't have an item populated for this, - // ask the adapter for an offset. - offset -= mAdapter.getPageWidth(pos) + marginOffset; - pos--; - } - offset -= ii.widthFactor + marginOffset; - ii.offset = offset; - } - } - } - - // Base all offsets off of curItem. - final int itemCount = mItems.size(); - float offset = curItem.offset; - int pos = curItem.position - 1; - mFirstOffset = curItem.position == 0 ? curItem.offset : -Float.MAX_VALUE; - mLastOffset = curItem.position == N - 1 ? - curItem.offset + curItem.widthFactor - 1 : Float.MAX_VALUE; - // Previous pages - for (int i = curIndex - 1; i >= 0; i--, pos--) { - final ItemInfo ii = mItems.get(i); - while (pos > ii.position) { - offset -= mAdapter.getPageWidth(pos--) + marginOffset; - } - offset -= ii.widthFactor + marginOffset; - ii.offset = offset; - if (ii.position == 0) mFirstOffset = offset; - } - offset = curItem.offset + curItem.widthFactor + marginOffset; - pos = curItem.position + 1; - // Next pages - for (int i = curIndex + 1; i < itemCount; i++, pos++) { - final ItemInfo ii = mItems.get(i); - while (pos < ii.position) { - offset += mAdapter.getPageWidth(pos++) + marginOffset; - } - if (ii.position == N - 1) { - mLastOffset = offset + ii.widthFactor - 1; - } - ii.offset = offset; - offset += ii.widthFactor + marginOffset; - } - - mNeedCalculatePageOffsets = false; - } - - /** - * This is the persistent state that is saved by ViewPager. Only needed - * if you are creating a sublass of ViewPager that must save its own - * state, in which case it should implement a subclass of this which - * contains that state. - */ - public static class SavedState extends BaseSavedState { - int position; - Parcelable adapterState; - ClassLoader loader; - - public SavedState(Parcelable superState) { - super(superState); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeInt(position); - out.writeParcelable(adapterState, flags); - } - - @Override - public String toString() { - return "FragmentPager.SavedState{" - + Integer.toHexString(System.identityHashCode(this)) - + " position=" + position + "}"; - } - - public static final Parcelable.Creator CREATOR - = ParcelableCompat.newCreator(new ParcelableCompatCreatorCallbacks() { - @TargetApi(24) - @Override - public SavedState createFromParcel(Parcel in, ClassLoader loader) { - return new SavedState(in, loader); - } - - @Override - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }); - - SavedState(Parcel in, ClassLoader loader) { - super(in); - if (loader == null) { - loader = getClass().getClassLoader(); - } - position = in.readInt(); - adapterState = in.readParcelable(loader); - this.loader = loader; - } - } - - @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.position = mCurItem; - if (mAdapter != null) { - ss.adapterState = mAdapter.saveState(); - } - return ss; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - if (!(state instanceof SavedState)) { - super.onRestoreInstanceState(state); - return; - } - - SavedState ss = (SavedState)state; - super.onRestoreInstanceState(ss.getSuperState()); - - if (mAdapter != null) { - mAdapter.restoreState(ss.adapterState, ss.loader); - setCurrentItemInternal(ss.position, false, true); - } else { - mRestoredCurItem = ss.position; - mRestoredAdapterState = ss.adapterState; - mRestoredClassLoader = ss.loader; - } - } - - @Override - public void addView(View child, int index, ViewGroup.LayoutParams params) { - if (!checkLayoutParams(params)) { - params = generateLayoutParams(params); - } - final LayoutParams lp = (LayoutParams) params; - lp.isDecor |= child instanceof Decor; - if (mInLayout) { - if (lp != null && lp.isDecor) { - throw new IllegalStateException("Cannot add pager decor view during layout"); - } - lp.needsMeasure = true; - addViewInLayout(child, index, params); - } else { - super.addView(child, index, params); - } - - if (USE_CACHE) { - if (child.getVisibility() != GONE) { - child.setDrawingCacheEnabled(mScrollingCacheEnabled); - } else { - child.setDrawingCacheEnabled(false); - } - } - } - - @Override - public void removeView(View view) { - if (mInLayout) { - removeViewInLayout(view); - } else { - super.removeView(view); - } - } - - ItemInfo infoForChild(View child) { - for (int i=0; i 0 && !mItems.isEmpty()) { - final int widthWithMargin = width - getPaddingLeft() - getPaddingRight() + margin; - final int oldWidthWithMargin = oldWidth - getPaddingLeft() - getPaddingRight() - + oldMargin; - final int xpos = getScrollX(); - final float pageOffset = (float) xpos / oldWidthWithMargin; - final int newOffsetPixels = (int) (pageOffset * widthWithMargin); - - scrollTo(newOffsetPixels, getScrollY()); - if (!mScroller.isFinished()) { - // We now return to your regularly scheduled scroll, already in progress. - final int newDuration = mScroller.getDuration() - mScroller.timePassed(); - ItemInfo targetInfo = infoForPosition(mCurItem); - mScroller.startScroll(newOffsetPixels, 0, - (int) (targetInfo.offset * width), 0, newDuration); - } - } else { - final ItemInfo ii = infoForPosition(mCurItem); - final float scrollOffset = ii != null ? Math.min(ii.offset, mLastOffset) : 0; - final int scrollPos = (int) (scrollOffset * - (width - getPaddingLeft() - getPaddingRight())); - if (scrollPos != getScrollX()) { - completeScroll(false); - scrollTo(scrollPos, getScrollY()); - } - } - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - final int count = getChildCount(); - int width = r - l; - int height = b - t; - int paddingLeft = getPaddingLeft(); - int paddingTop = getPaddingTop(); - int paddingRight = getPaddingRight(); - int paddingBottom = getPaddingBottom(); - final int scrollX = getScrollX(); - - int decorCount = 0; - - // First pass - decor views. We need to do this in two passes so that - // we have the proper offsets for non-decor views later. - for (int i = 0; i < count; i++) { - final View child = getChildAt(i); - if (child.getVisibility() != GONE) { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - int childLeft = 0; - int childTop = 0; - if (lp.isDecor) { - final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK; - final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK; - switch (hgrav) { - default: - childLeft = paddingLeft; - break; - case Gravity.LEFT: - childLeft = paddingLeft; - paddingLeft += child.getMeasuredWidth(); - break; - case Gravity.CENTER_HORIZONTAL: - childLeft = Math.max((width - child.getMeasuredWidth()) / 2, - paddingLeft); - break; - case Gravity.RIGHT: - childLeft = width - paddingRight - child.getMeasuredWidth(); - paddingRight += child.getMeasuredWidth(); - break; - } - switch (vgrav) { - default: - childTop = paddingTop; - break; - case Gravity.TOP: - childTop = paddingTop; - paddingTop += child.getMeasuredHeight(); - break; - case Gravity.CENTER_VERTICAL: - childTop = Math.max((height - child.getMeasuredHeight()) / 2, - paddingTop); - break; - case Gravity.BOTTOM: - childTop = height - paddingBottom - child.getMeasuredHeight(); - paddingBottom += child.getMeasuredHeight(); - break; - } - childLeft += scrollX; - child.layout(childLeft, childTop, - childLeft + child.getMeasuredWidth(), - childTop + child.getMeasuredHeight()); - decorCount++; - } - } - } - - final int childWidth = width - paddingLeft - paddingRight; - // Page views. Do this once we have the right padding offsets from above. - for (int i = 0; i < count; i++) { - final View child = getChildAt(i); - if (child.getVisibility() != GONE) { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - ItemInfo ii; - if (!lp.isDecor && (ii = infoForChild(child)) != null) { - int loff = (int) (childWidth * ii.offset); - int childLeft = paddingLeft + loff; - int childTop = paddingTop; - if (lp.needsMeasure) { - // This was added during layout and needs measurement. - // Do it now that we know what we're working with. - lp.needsMeasure = false; - final int widthSpec = MeasureSpec.makeMeasureSpec( - (int) (childWidth * lp.widthFactor), - MeasureSpec.EXACTLY); - final int heightSpec = MeasureSpec.makeMeasureSpec( - (int) (height - paddingTop - paddingBottom), - MeasureSpec.EXACTLY); - child.measure(widthSpec, heightSpec); - } - int id = -1; - - if (DEBUG) Log.v(TAG, "Positioning #" + i + " " + child + " f=" + ii.object - + ":" + childLeft + "," + childTop + " " + child.getMeasuredWidth() - + "x" + child.getMeasuredHeight()); - - child.layout(childLeft, childTop, - childLeft + child.getMeasuredWidth(), - childTop + child.getMeasuredHeight()); - } - } - } - mTopPageBounds = paddingTop; - mBottomPageBounds = height - paddingBottom; - mDecorChildCount = decorCount; - - if (mFirstLayout) { - scrollToItem(mCurItem, false, 0, false); - } - mFirstLayout = false; - } - - @Override - public void computeScroll() { - if (!mScroller.isFinished() && mScroller.computeScrollOffset()) { - int oldX = getScrollX(); - int oldY = getScrollY(); - int x = mScroller.getCurrX(); - int y = mScroller.getCurrY(); - - if (oldX != x || oldY != y) { - scrollTo(x, y); - if (!pageScrolled(x)) { - mScroller.abortAnimation(); - scrollTo(0, y); - } - } - - // Keep on drawing until the animation has finished. - ViewCompat.postInvalidateOnAnimation(this); - return; - } - - // Done with scroll, clean up state. - completeScroll(true); - } - - private boolean pageScrolled(int xpos) { - if (mItems.size() == 0) { - mCalledSuper = false; - onPageScrolled(0, 0, 0); - if (!mCalledSuper) { - throw new IllegalStateException( - "onPageScrolled did not call superclass implementation"); - } - return false; - } - final ItemInfo ii = infoForCurrentScrollPosition(); - final int width = getClientWidth(); - final int widthWithMargin = width + mPageMargin; - final float marginOffset = (float) mPageMargin / width; - final int currentPage = ii.position; - final float pageOffset = (((float) xpos / width) - ii.offset) / - (ii.widthFactor + marginOffset); - final int offsetPixels = (int) (pageOffset * widthWithMargin); - - mCalledSuper = false; - onPageScrolled(currentPage, pageOffset, offsetPixels); - if (!mCalledSuper) { - throw new IllegalStateException( - "onPageScrolled did not call superclass implementation"); - } - return true; - } - - /** - * This method will be invoked when the current page is scrolled, either as part - * of a programmatically initiated smooth scroll or a user initiated touch scroll. - * If you override this method you must call through to the superclass implementation - * (e.g. super.onPageScrolled(position, offset, offsetPixels)) before onPageScrolled - * returns. - * - * @param position Position index of the first page currently being displayed. - * Page position+1 will be visible if positionOffset is nonzero. - * @param offset Value from [0, 1) indicating the offset from the page at position. - * @param offsetPixels Value in pixels indicating the offset from position. - */ - protected void onPageScrolled(int position, float offset, int offsetPixels) { - // Offset any decor views if needed - keep them on-screen at all times. - if (mDecorChildCount > 0) { - final int scrollX = getScrollX(); - int paddingLeft = getPaddingLeft(); - int paddingRight = getPaddingRight(); - final int width = getWidth(); - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if (!lp.isDecor) continue; - - final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK; - int childLeft = 0; - switch (hgrav) { - default: - childLeft = paddingLeft; - break; - case Gravity.LEFT: - childLeft = paddingLeft; - paddingLeft += child.getWidth(); - break; - case Gravity.CENTER_HORIZONTAL: - childLeft = Math.max((width - child.getMeasuredWidth()) / 2, - paddingLeft); - break; - case Gravity.RIGHT: - childLeft = width - paddingRight - child.getMeasuredWidth(); - paddingRight += child.getMeasuredWidth(); - break; - } - childLeft += scrollX; - - final int childOffset = childLeft - child.getLeft(); - if (childOffset != 0) { - child.offsetLeftAndRight(childOffset); - } - } - } - - if (mOnPageChangeListener != null) { - mOnPageChangeListener.onPageScrolled(position, offset, offsetPixels); - } - if (mInternalPageChangeListener != null) { - mInternalPageChangeListener.onPageScrolled(position, offset, offsetPixels); - } - - if (mPageTransformer != null) { - final int scrollX = getScrollX(); - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - - if (lp.isDecor) continue; - - final float transformPos = (float) (child.getLeft() - scrollX) / getClientWidth(); - mPageTransformer.transformPage(child, transformPos); - } - } - - mCalledSuper = true; - } - - private void completeScroll(boolean postEvents) { - boolean needPopulate = mScrollState == SCROLL_STATE_SETTLING; - if (needPopulate) { - // Done with scroll, no longer want to cache view drawing. - setScrollingCacheEnabled(false); - mScroller.abortAnimation(); - int oldX = getScrollX(); - int oldY = getScrollY(); - int x = mScroller.getCurrX(); - int y = mScroller.getCurrY(); - if (oldX != x || oldY != y) { - scrollTo(x, y); - } - } - mPopulatePending = false; - for (int i=0; i 0) || (x > getWidth() - mGutterSize && dx < 0); - } - - private void enableLayers(boolean enable) { - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - final int layerType = enable ? - ViewCompat.LAYER_TYPE_HARDWARE : ViewCompat.LAYER_TYPE_NONE; - ViewCompat.setLayerType(getChildAt(i), layerType, null); - } - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - /* - * This method JUST determines whether we want to intercept the motion. - * If we return true, onMotionEvent will be called and we do the actual - * scrolling there. - */ - - final int action = ev.getAction() & MotionEventCompat.ACTION_MASK; - - // Always take care of the touch gesture being complete. - if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { - // Release the drag. - if (DEBUG) Log.v(TAG, "Intercept done!"); - mIsBeingDragged = false; - mIsUnableToDrag = false; - mActivePointerId = INVALID_POINTER; - if (mVelocityTracker != null) { - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - return false; - } - - // Nothing more to do here if we have decided whether or not we - // are dragging. - if (action != MotionEvent.ACTION_DOWN) { - if (mIsBeingDragged) { - if (DEBUG) Log.v(TAG, "Intercept returning true!"); - return true; - } - if (mIsUnableToDrag) { - if (DEBUG) Log.v(TAG, "Intercept returning false!"); - return false; - } - } - - switch (action) { - case MotionEvent.ACTION_MOVE: { - /* - * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check - * whether the user has moved far enough from his original down touch. - */ - - /* - * Locally do absolute value. mLastMotionY is set to the y value - * of the down event. - */ - final int activePointerId = mActivePointerId; - if (activePointerId == INVALID_POINTER) { - // If we don't have a valid id, the touch down wasn't on content. - break; - } - - final int pointerIndex = MotionEventCompat.findPointerIndex(ev, activePointerId); - final float x = MotionEventCompat.getX(ev, pointerIndex); - final float dx = x - mLastMotionX; - final float xDiff = Math.abs(dx); - final float y = MotionEventCompat.getY(ev, pointerIndex); - final float yDiff = Math.abs(y - mInitialMotionY); - if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); - - if (dx != 0 && !isGutterDrag(mLastMotionX, dx) && - canScroll(this, false, (int) dx, (int) x, (int) y)) { - // Nested view has scrollable area under this point. Let it be handled there. - mLastMotionX = x; - mLastMotionY = y; - mIsUnableToDrag = true; - return false; - } - if (xDiff > mTouchSlop && xDiff * 0.5f > yDiff) { - if (DEBUG) Log.v(TAG, "Starting drag!"); - mIsBeingDragged = true; - requestParentDisallowInterceptTouchEvent(true); - setScrollState(SCROLL_STATE_DRAGGING); - mLastMotionX = dx > 0 ? mInitialMotionX + mTouchSlop : - mInitialMotionX - mTouchSlop; - mLastMotionY = y; - setScrollingCacheEnabled(true); - } else if (yDiff > mTouchSlop) { - // The finger has moved enough in the vertical - // direction to be counted as a drag... abort - // any attempt to drag horizontally, to work correctly - // with children that have scrolling containers. - if (DEBUG) Log.v(TAG, "Starting unable to drag!"); - mIsUnableToDrag = true; - } - if (mIsBeingDragged) { - // Scroll to follow the motion event - if (performDrag(x)) { - ViewCompat.postInvalidateOnAnimation(this); - } - } - break; - } - - case MotionEvent.ACTION_DOWN: { - /* - * Remember location of down touch. - * ACTION_DOWN always refers to pointer index 0. - */ - mLastMotionX = mInitialMotionX = ev.getX(); - mLastMotionY = mInitialMotionY = ev.getY(); - mActivePointerId = MotionEventCompat.getPointerId(ev, 0); - mIsUnableToDrag = false; - - mScroller.computeScrollOffset(); - if (mScrollState == SCROLL_STATE_SETTLING && - Math.abs(mScroller.getFinalX() - mScroller.getCurrX()) > mCloseEnough) { - // Let the user 'catch' the pager as it animates. - mScroller.abortAnimation(); - mPopulatePending = false; - populate(); - mIsBeingDragged = true; - requestParentDisallowInterceptTouchEvent(true); - setScrollState(SCROLL_STATE_DRAGGING); - } else { - completeScroll(false); - mIsBeingDragged = false; - } - - if (DEBUG) Log.v(TAG, "Down at " + mLastMotionX + "," + mLastMotionY - + " mIsBeingDragged=" + mIsBeingDragged - + "mIsUnableToDrag=" + mIsUnableToDrag); - break; - } - - case MotionEventCompat.ACTION_POINTER_UP: - onSecondaryPointerUp(ev); - break; - } - - if (mVelocityTracker == null) { - mVelocityTracker = VelocityTracker.obtain(); - } - mVelocityTracker.addMovement(ev); - - /* - * The only time we want to intercept motion events is if we are in the - * drag mode. - */ - return mIsBeingDragged; - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - if (mFakeDragging) { - // A fake drag is in progress already, ignore this real one - // but still eat the touch events. - // (It is likely that the user is multi-touching the screen.) - return true; - } - - if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) { - // Don't handle edge touches immediately -- they may actually belong to one of our - // descendants. - return false; - } - - if (mAdapter == null || mAdapter.getCount() == 0) { - // Nothing to present or scroll; nothing to touch. - return false; - } - - if (mVelocityTracker == null) { - mVelocityTracker = VelocityTracker.obtain(); - } - mVelocityTracker.addMovement(ev); - - final int action = ev.getAction(); - boolean needsInvalidate = false; - - switch (action & MotionEventCompat.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: { - mScroller.abortAnimation(); - mPopulatePending = false; - populate(); - - // Remember where the motion event started - mLastMotionX = mInitialMotionX = ev.getX(); - mLastMotionY = mInitialMotionY = ev.getY(); - mActivePointerId = MotionEventCompat.getPointerId(ev, 0); - break; - } - case MotionEvent.ACTION_MOVE: - if (!mIsBeingDragged) { - final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); - final float x = MotionEventCompat.getX(ev, pointerIndex); - final float xDiff = Math.abs(x - mLastMotionX); - final float y = MotionEventCompat.getY(ev, pointerIndex); - final float yDiff = Math.abs(y - mLastMotionY); - if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); - if (xDiff > mTouchSlop && xDiff > yDiff) { - if (DEBUG) Log.v(TAG, "Starting drag!"); - mIsBeingDragged = true; - requestParentDisallowInterceptTouchEvent(true); - mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop : - mInitialMotionX - mTouchSlop; - mLastMotionY = y; - setScrollState(SCROLL_STATE_DRAGGING); - setScrollingCacheEnabled(true); - - // Disallow Parent Intercept, just in case - ViewParent parent = getParent(); - if (parent != null) { - parent.requestDisallowInterceptTouchEvent(true); - } - } - } - // Not else! Note that mIsBeingDragged can be set above. - if (mIsBeingDragged) { - // Scroll to follow the motion event - final int activePointerIndex = MotionEventCompat.findPointerIndex( - ev, mActivePointerId); - final float x = MotionEventCompat.getX(ev, activePointerIndex); - needsInvalidate |= performDrag(x); - } - break; - case MotionEvent.ACTION_UP: - if (mIsBeingDragged) { - final VelocityTracker velocityTracker = mVelocityTracker; - velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); - int initialVelocity = (int) VelocityTrackerCompat.getXVelocity( - velocityTracker, mActivePointerId); - mPopulatePending = true; - final int width = getClientWidth(); - final int scrollX = getScrollX(); - final ItemInfo ii = infoForCurrentScrollPosition(); - final int currentPage = ii.position; - final float pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor; - final int activePointerIndex = - MotionEventCompat.findPointerIndex(ev, mActivePointerId); - final float x = MotionEventCompat.getX(ev, activePointerIndex); - final int totalDelta = (int) (x - mInitialMotionX); - int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, - totalDelta); - setCurrentItemInternal(nextPage, true, true, initialVelocity); - - mActivePointerId = INVALID_POINTER; - endDrag(); - needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease(); - } - break; - case MotionEvent.ACTION_CANCEL: - if (mIsBeingDragged) { - scrollToItem(mCurItem, true, 0, false); - mActivePointerId = INVALID_POINTER; - endDrag(); - needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease(); - } - break; - case MotionEventCompat.ACTION_POINTER_DOWN: { - final int index = MotionEventCompat.getActionIndex(ev); - final float x = MotionEventCompat.getX(ev, index); - mLastMotionX = x; - mActivePointerId = MotionEventCompat.getPointerId(ev, index); - break; - } - case MotionEventCompat.ACTION_POINTER_UP: - onSecondaryPointerUp(ev); - mLastMotionX = MotionEventCompat.getX(ev, - MotionEventCompat.findPointerIndex(ev, mActivePointerId)); - break; - } - if (needsInvalidate) { - ViewCompat.postInvalidateOnAnimation(this); - } - return true; - } - - private void requestParentDisallowInterceptTouchEvent(boolean disallowIntercept) { - final ViewParent parent = getParent(); - if (parent != null) { - parent.requestDisallowInterceptTouchEvent(disallowIntercept); - } - } - - private boolean performDrag(float x) { - boolean needsInvalidate = false; - - final float deltaX = mLastMotionX - x; - mLastMotionX = x; - - float oldScrollX = getScrollX(); - float scrollX = oldScrollX + deltaX; - final int width = getClientWidth(); - - float leftBound = width * mFirstOffset; - float rightBound = width * mLastOffset; - boolean leftAbsolute = true; - boolean rightAbsolute = true; - - final ItemInfo firstItem = mItems.get(0); - final ItemInfo lastItem = mItems.get(mItems.size() - 1); - if (firstItem.position != 0) { - leftAbsolute = false; - leftBound = firstItem.offset * width; - } - if (lastItem.position != mAdapter.getCount() - 1) { - rightAbsolute = false; - rightBound = lastItem.offset * width; - } - - if (scrollX < leftBound) { - if (leftAbsolute) { - float over = leftBound - scrollX; - needsInvalidate = mLeftEdge.onPull(Math.abs(over) / width); - } - scrollX = leftBound; - } else if (scrollX > rightBound) { - if (rightAbsolute) { - float over = scrollX - rightBound; - needsInvalidate = mRightEdge.onPull(Math.abs(over) / width); - } - scrollX = rightBound; - } - // Don't lose the rounded component - mLastMotionX += scrollX - (int) scrollX; - scrollTo((int) scrollX, getScrollY()); - pageScrolled((int) scrollX); - - return needsInvalidate; - } - - /** - * @return Info about the page at the current scroll position. - * This can be synthetic for a missing middle page; the 'object' field can be null. - */ - private ItemInfo infoForCurrentScrollPosition() { - final int width = getClientWidth(); - final float scrollOffset = width > 0 ? (float) getScrollX() / width : 0; - final float marginOffset = width > 0 ? (float) mPageMargin / width : 0; - int lastPos = -1; - float lastOffset = 0.f; - float lastWidth = 0.f; - boolean first = true; - - ItemInfo lastItem = null; - for (int i = 0; i < mItems.size(); i++) { - ItemInfo ii = mItems.get(i); - float offset; - if (!first && ii.position != lastPos + 1) { - // Create a synthetic item for a missing page. - ii = mTempItem; - ii.offset = lastOffset + lastWidth + marginOffset; - ii.position = lastPos + 1; - ii.widthFactor = mAdapter.getPageWidth(ii.position); - i--; - } - offset = ii.offset; - - final float leftBound = offset; - final float rightBound = offset + ii.widthFactor + marginOffset; - if (first || scrollOffset >= leftBound) { - if (scrollOffset < rightBound || i == mItems.size() - 1) { - return ii; - } - } else { - return lastItem; - } - first = false; - lastPos = ii.position; - lastOffset = offset; - lastWidth = ii.widthFactor; - lastItem = ii; - } - - return lastItem; - } - - private int determineTargetPage(int currentPage, float pageOffset, int velocity, int deltaX) { - int targetPage; - if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity) { - targetPage = velocity > 0 ? currentPage : currentPage + 1; - } else { - final float truncator = currentPage >= mCurItem ? 0.4f : 0.6f; - targetPage = (int) (currentPage + pageOffset + truncator); - } - - if (mItems.size() > 0) { - final ItemInfo firstItem = mItems.get(0); - final ItemInfo lastItem = mItems.get(mItems.size() - 1); - - // Only let the user target pages we have items for - targetPage = Math.max(firstItem.position, Math.min(targetPage, lastItem.position)); - } - - return targetPage; - } - - @Override - public void draw(Canvas canvas) { - super.draw(canvas); - boolean needsInvalidate = false; - - final int overScrollMode = ViewCompat.getOverScrollMode(this); - if (overScrollMode == ViewCompat.OVER_SCROLL_ALWAYS || - (overScrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS && - mAdapter != null && mAdapter.getCount() > 1)) { - if (!mLeftEdge.isFinished()) { - final int restoreCount = canvas.save(); - final int height = getHeight() - getPaddingTop() - getPaddingBottom(); - final int width = getWidth(); - - canvas.rotate(270); - canvas.translate(-height + getPaddingTop(), mFirstOffset * width); - mLeftEdge.setSize(height, width); - needsInvalidate |= mLeftEdge.draw(canvas); - canvas.restoreToCount(restoreCount); - } - if (!mRightEdge.isFinished()) { - final int restoreCount = canvas.save(); - final int width = getWidth(); - final int height = getHeight() - getPaddingTop() - getPaddingBottom(); - - canvas.rotate(90); - canvas.translate(-getPaddingTop(), -(mLastOffset + 1) * width); - mRightEdge.setSize(height, width); - needsInvalidate |= mRightEdge.draw(canvas); - canvas.restoreToCount(restoreCount); - } - } else { - mLeftEdge.finish(); - mRightEdge.finish(); - } - - if (needsInvalidate) { - // Keep animating - ViewCompat.postInvalidateOnAnimation(this); - } - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - - // Draw the margin drawable between pages if needed. - if (mPageMargin > 0 && mMarginDrawable != null && mItems.size() > 0 && mAdapter != null) { - final int scrollX = getScrollX(); - final int width = getWidth(); - - final float marginOffset = (float) mPageMargin / width; - int itemIndex = 0; - ItemInfo ii = mItems.get(0); - float offset = ii.offset; - final int itemCount = mItems.size(); - final int firstPos = ii.position; - final int lastPos = mItems.get(itemCount - 1).position; - for (int pos = firstPos; pos < lastPos; pos++) { - while (pos > ii.position && itemIndex < itemCount) { - ii = mItems.get(++itemIndex); - } - - float drawAt; - if (pos == ii.position) { - drawAt = (ii.offset + ii.widthFactor) * width; - offset = ii.offset + ii.widthFactor + marginOffset; - } else { - float widthFactor = mAdapter.getPageWidth(pos); - drawAt = (offset + widthFactor) * width; - offset += widthFactor + marginOffset; - } - - if (drawAt + mPageMargin > scrollX) { - mMarginDrawable.setBounds((int) drawAt, mTopPageBounds, - (int) (drawAt + mPageMargin + 0.5f), mBottomPageBounds); - mMarginDrawable.draw(canvas); - } - - if (drawAt > scrollX + width) { - break; // No more visible, no sense in continuing - } - } - } - } - - /** - * Start a fake drag of the pager. - * - *

A fake drag can be useful if you want to synchronize the motion of the ViewPager - * with the touch scrolling of another view, while still letting the ViewPager - * control the snapping motion and fling behavior. (e.g. parallax-scrolling tabs.) - * Call {@link #fakeDragBy(float)} to simulate the actual drag motion. Call - * {@link #endFakeDrag()} to complete the fake drag and fling as necessary. - * - *

During a fake drag the ViewPager will ignore all touch events. If a real drag - * is already in progress, this method will return false. - * - * @return true if the fake drag began successfully, false if it could not be started. - * - * @see #fakeDragBy(float) - * @see #endFakeDrag() - */ - public boolean beginFakeDrag() { - if (mIsBeingDragged) { - return false; - } - mFakeDragging = true; - setScrollState(SCROLL_STATE_DRAGGING); - mInitialMotionX = mLastMotionX = 0; - if (mVelocityTracker == null) { - mVelocityTracker = VelocityTracker.obtain(); - } else { - mVelocityTracker.clear(); - } - final long time = SystemClock.uptimeMillis(); - final MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0); - mVelocityTracker.addMovement(ev); - ev.recycle(); - mFakeDragBeginTime = time; - return true; - } - - /** - * End a fake drag of the pager. - * - * @see #beginFakeDrag() - * @see #fakeDragBy(float) - */ - public void endFakeDrag() { - if (!mFakeDragging) { - throw new IllegalStateException("No fake drag in progress. Call beginFakeDrag first."); - } - - final VelocityTracker velocityTracker = mVelocityTracker; - velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); - int initialVelocity = (int) VelocityTrackerCompat.getXVelocity( - velocityTracker, mActivePointerId); - mPopulatePending = true; - final int width = getClientWidth(); - final int scrollX = getScrollX(); - final ItemInfo ii = infoForCurrentScrollPosition(); - final int currentPage = ii.position; - final float pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor; - final int totalDelta = (int) (mLastMotionX - mInitialMotionX); - int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, - totalDelta); - setCurrentItemInternal(nextPage, true, true, initialVelocity); - endDrag(); - - mFakeDragging = false; - } - - /** - * Fake drag by an offset in pixels. You must have called {@link #beginFakeDrag()} first. - * - * @param xOffset Offset in pixels to drag by. - * @see #beginFakeDrag() - * @see #endFakeDrag() - */ - public void fakeDragBy(float xOffset) { - if (!mFakeDragging) { - throw new IllegalStateException("No fake drag in progress. Call beginFakeDrag first."); - } - - mLastMotionX += xOffset; - - float oldScrollX = getScrollX(); - float scrollX = oldScrollX - xOffset; - final int width = getClientWidth(); - - float leftBound = width * mFirstOffset; - float rightBound = width * mLastOffset; - - final ItemInfo firstItem = mItems.get(0); - final ItemInfo lastItem = mItems.get(mItems.size() - 1); - if (firstItem.position != 0) { - leftBound = firstItem.offset * width; - } - if (lastItem.position != mAdapter.getCount() - 1) { - rightBound = lastItem.offset * width; - } - - if (scrollX < leftBound) { - scrollX = leftBound; - } else if (scrollX > rightBound) { - scrollX = rightBound; - } - // Don't lose the rounded component - mLastMotionX += scrollX - (int) scrollX; - scrollTo((int) scrollX, getScrollY()); - pageScrolled((int) scrollX); - - // Synthesize an event for the VelocityTracker. - final long time = SystemClock.uptimeMillis(); - final MotionEvent ev = MotionEvent.obtain(mFakeDragBeginTime, time, MotionEvent.ACTION_MOVE, - mLastMotionX, 0, 0); - mVelocityTracker.addMovement(ev); - ev.recycle(); - } - - /** - * Returns true if a fake drag is in progress. - * - * @return true if currently in a fake drag, false otherwise. - * - * @see #beginFakeDrag() - * @see #fakeDragBy(float) - * @see #endFakeDrag() - */ - public boolean isFakeDragging() { - return mFakeDragging; - } - - private void onSecondaryPointerUp(MotionEvent ev) { - final int pointerIndex = MotionEventCompat.getActionIndex(ev); - final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex); - if (pointerId == mActivePointerId) { - // This was our active pointer going up. Choose a new - // active pointer and adjust accordingly. - final int newPointerIndex = pointerIndex == 0 ? 1 : 0; - mLastMotionX = MotionEventCompat.getX(ev, newPointerIndex); - mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex); - if (mVelocityTracker != null) { - mVelocityTracker.clear(); - } - } - } - - private void endDrag() { - mIsBeingDragged = false; - mIsUnableToDrag = false; - - if (mVelocityTracker != null) { - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - } - - private void setScrollingCacheEnabled(boolean enabled) { - if (mScrollingCacheEnabled != enabled) { - mScrollingCacheEnabled = enabled; - if (USE_CACHE) { - final int size = getChildCount(); - for (int i = 0; i < size; ++i) { - final View child = getChildAt(i); - if (child.getVisibility() != GONE) { - child.setDrawingCacheEnabled(enabled); - } - } - } - } - } - - public boolean canScrollHorizontally(int direction) { - if (mAdapter == null) { - return false; - } - - final int width = getClientWidth(); - final int scrollX = getScrollX(); - if (direction < 0) { - return (scrollX > (int) (width * mFirstOffset)); - } else if (direction > 0) { - return (scrollX < (int) (width * mLastOffset)); - } else { - return false; - } - } - - /** - * Tests scrollability within child views of v given a delta of dx. - * - * @param v View to test for horizontal scrollability - * @param checkV Whether the view v passed should itself be checked for scrollability (true), - * or just its children (false). - * @param dx Delta scrolled in pixels - * @param x X coordinate of the active touch point - * @param y Y coordinate of the active touch point - * @return true if child views of v can be scrolled by delta of dx. - */ - protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { - if (v instanceof ViewGroup) { - final ViewGroup group = (ViewGroup) v; - final int scrollX = v.getScrollX(); - final int scrollY = v.getScrollY(); - final int count = group.getChildCount(); - // Count backwards - let topmost views consume scroll distance first. - for (int i = count - 1; i >= 0; i--) { - // TODO: Add versioned support here for transformed views. - // This will not work for transformed views in Honeycomb+ - final View child = group.getChildAt(i); - if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight() && - y + scrollY >= child.getTop() && y + scrollY < child.getBottom() && - canScroll(child, true, dx, x + scrollX - child.getLeft(), - y + scrollY - child.getTop())) { - return true; - } - } - } - - return checkV && ViewCompat.canScrollHorizontally(v, -dx); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - // Let the focused view and/or our descendants get the key first - return super.dispatchKeyEvent(event) || executeKeyEvent(event); - } - - /** - * You can call this function yourself to have the scroll view perform - * scrolling from a key event, just as if the event had been dispatched to - * it by the view hierarchy. - * - * @param event The key event to execute. - * @return Return true if the event was handled, else false. - */ - public boolean executeKeyEvent(KeyEvent event) { - boolean handled = false; - if (event.getAction() == KeyEvent.ACTION_DOWN) { - switch (event.getKeyCode()) { - case KeyEvent.KEYCODE_DPAD_LEFT: - handled = arrowScroll(FOCUS_LEFT); - break; - case KeyEvent.KEYCODE_DPAD_RIGHT: - handled = arrowScroll(FOCUS_RIGHT); - break; - } - } - return handled; - } - - public boolean arrowScroll(int direction) { - View currentFocused = findFocus(); - if (currentFocused == this) { - currentFocused = null; - } else if (currentFocused != null) { - boolean isChild = false; - for (ViewParent parent = currentFocused.getParent(); parent instanceof ViewGroup; - parent = parent.getParent()) { - if (parent == this) { - isChild = true; - break; - } - } - if (!isChild) { - // This would cause the focus search down below to fail in fun ways. - final StringBuilder sb = new StringBuilder(); - sb.append(currentFocused.getClass().getSimpleName()); - for (ViewParent parent = currentFocused.getParent(); parent instanceof ViewGroup; - parent = parent.getParent()) { - sb.append(" => ").append(parent.getClass().getSimpleName()); - } - Log.e(TAG, "arrowScroll tried to find focus based on non-child " + - "current focused view " + sb.toString()); - currentFocused = null; - } - } - - boolean handled = false; - - View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, - direction); - if (nextFocused != null && nextFocused != currentFocused) { - if (direction == View.FOCUS_LEFT) { - // If there is nothing to the left, or this is causing us to - // jump to the right, then what we really want to do is page left. - final int nextLeft = getChildRectInPagerCoordinates(mTempRect, nextFocused).left; - final int currLeft = getChildRectInPagerCoordinates(mTempRect, currentFocused).left; - if (currentFocused != null && nextLeft >= currLeft) { - handled = pageLeft(); - } else { - handled = nextFocused.requestFocus(); - } - } else if (direction == View.FOCUS_RIGHT) { - // If there is nothing to the right, or this is causing us to - // jump to the left, then what we really want to do is page right. - final int nextLeft = getChildRectInPagerCoordinates(mTempRect, nextFocused).left; - final int currLeft = getChildRectInPagerCoordinates(mTempRect, currentFocused).left; - if (currentFocused != null && nextLeft <= currLeft) { - handled = pageRight(); - } else { - handled = nextFocused.requestFocus(); - } - } - } else if (direction == FOCUS_LEFT || direction == FOCUS_BACKWARD) { - // Trying to move left and nothing there; try to page. - handled = pageLeft(); - } else if (direction == FOCUS_RIGHT || direction == FOCUS_FORWARD) { - // Trying to move right and nothing there; try to page. - handled = pageRight(); - } - if (handled) { - playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction)); - } - return handled; - } - - private Rect getChildRectInPagerCoordinates(Rect outRect, View child) { - if (outRect == null) { - outRect = new Rect(); - } - if (child == null) { - outRect.set(0, 0, 0, 0); - return outRect; - } - outRect.left = child.getLeft(); - outRect.right = child.getRight(); - outRect.top = child.getTop(); - outRect.bottom = child.getBottom(); - - ViewParent parent = child.getParent(); - while (parent instanceof ViewGroup && parent != this) { - final ViewGroup group = (ViewGroup) parent; - outRect.left += group.getLeft(); - outRect.right += group.getRight(); - outRect.top += group.getTop(); - outRect.bottom += group.getBottom(); - - parent = group.getParent(); - } - return outRect; - } - - boolean pageLeft() { - if (mCurItem > 0) { - setCurrentItem(mCurItem-1, true); - return true; - } - return false; - } - - boolean pageRight() { - if (mAdapter != null && mCurItem < (mAdapter.getCount()-1)) { - setCurrentItem(mCurItem+1, true); - return true; - } - return false; - } - - /** - * We only want the current page that is being shown to be focusable. - */ - @Override - public void addFocusables(ArrayList views, int direction, int focusableMode) { - final int focusableCount = views.size(); - - final int descendantFocusability = getDescendantFocusability(); - - if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) { - for (int i = 0; i < getChildCount(); i++) { - final View child = getChildAt(i); - if (child.getVisibility() == VISIBLE) { - ItemInfo ii = infoForChild(child); - if (ii != null && ii.position == mCurItem) { - child.addFocusables(views, direction, focusableMode); - } - } - } - } - - // we add ourselves (if focusable) in all cases except for when we are - // FOCUS_AFTER_DESCENDANTS and there are some descendants focusable. this is - // to avoid the focus search finding layouts when a more precise search - // among the focusable children would be more interesting. - if ( - descendantFocusability != FOCUS_AFTER_DESCENDANTS || - // No focusable descendants - (focusableCount == views.size())) { - // Note that we can't call the superclass here, because it will - // add all views in. So we need to do the same thing View does. - if (!isFocusable()) { - return; - } - if ((focusableMode & FOCUSABLES_TOUCH_MODE) == FOCUSABLES_TOUCH_MODE && - isInTouchMode() && !isFocusableInTouchMode()) { - return; - } - if (views != null) { - views.add(this); - } - } - } - - /** - * We only want the current page that is being shown to be touchable. - */ - @Override - public void addTouchables(ArrayList views) { - // Note that we don't call super.addTouchables(), which means that - // we don't call View.addTouchables(). This is okay because a ViewPager - // is itself not touchable. - for (int i = 0; i < getChildCount(); i++) { - final View child = getChildAt(i); - if (child.getVisibility() == VISIBLE) { - ItemInfo ii = infoForChild(child); - if (ii != null && ii.position == mCurItem) { - child.addTouchables(views); - } - } - } - } - - /** - * We only want the current page that is being shown to be focusable. - */ - @Override - protected boolean onRequestFocusInDescendants(int direction, - Rect previouslyFocusedRect) { - int index; - int increment; - int end; - int count = getChildCount(); - if ((direction & FOCUS_FORWARD) != 0) { - index = 0; - increment = 1; - end = count; - } else { - index = count - 1; - increment = -1; - end = -1; - } - for (int i = index; i != end; i += increment) { - View child = getChildAt(i); - if (child.getVisibility() == VISIBLE) { - ItemInfo ii = infoForChild(child); - if (ii != null && ii.position == mCurItem) { - if (child.requestFocus(direction, previouslyFocusedRect)) { - return true; - } - } - } - } - return false; - } - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - // Dispatch scroll events from this ViewPager. - if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) { - return super.dispatchPopulateAccessibilityEvent(event); - } - - // Dispatch all other accessibility events from the current page. - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - if (child.getVisibility() == VISIBLE) { - final ItemInfo ii = infoForChild(child); - if (ii != null && ii.position == mCurItem && - child.dispatchPopulateAccessibilityEvent(event)) { - return true; - } - } - } - - return false; - } - - @Override - protected ViewGroup.LayoutParams generateDefaultLayoutParams() { - return new LayoutParams(); - } - - @Override - protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { - return generateDefaultLayoutParams(); - } - - @Override - protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { - return p instanceof LayoutParams && super.checkLayoutParams(p); - } - - @Override - public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { - return new LayoutParams(getContext(), attrs); - } - - class MyAccessibilityDelegate extends AccessibilityDelegateCompat { - - @Override - public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { - super.onInitializeAccessibilityEvent(host, event); - event.setClassName(ViewPager.class.getName()); - final AccessibilityRecordCompat recordCompat = AccessibilityRecordCompat.obtain(); - recordCompat.setScrollable(canScroll()); - if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED - && mAdapter != null) { - recordCompat.setItemCount(mAdapter.getCount()); - recordCompat.setFromIndex(mCurItem); - recordCompat.setToIndex(mCurItem); - } - } - - @Override - public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) { - super.onInitializeAccessibilityNodeInfo(host, info); - info.setClassName(ViewPager.class.getName()); - info.setScrollable(canScroll()); - if (canScrollHorizontally(1)) { - info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD); - } - if (canScrollHorizontally(-1)) { - info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD); - } - } - - @Override - public boolean performAccessibilityAction(View host, int action, Bundle args) { - if (super.performAccessibilityAction(host, action, args)) { - return true; - } - switch (action) { - case AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD: { - if (canScrollHorizontally(1)) { - setCurrentItem(mCurItem + 1); - return true; - } - } return false; - case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD: { - if (canScrollHorizontally(-1)) { - setCurrentItem(mCurItem - 1); - return true; - } - } return false; - } - return false; - } - - private boolean canScroll() { - return (mAdapter != null) && (mAdapter.getCount() > 1); - } - } - - private class PagerObserver extends DataSetObserver { - @Override - public void onChanged() { - dataSetChanged(); - } - @Override - public void onInvalidated() { - dataSetChanged(); - } - } - - /** - * Layout parameters that should be supplied for views added to a - * ViewPager. - */ - public static class LayoutParams extends ViewGroup.LayoutParams { - /** - * true if this view is a decoration on the pager itself and not - * a view supplied by the adapter. - */ - public boolean isDecor; - - /** - * Gravity setting for use on decor views only: - * Where to position the view page within the overall ViewPager - * container; constants are defined in {@link android.view.Gravity}. - */ - public int gravity; - - /** - * Width as a 0-1 multiplier of the measured pager width - */ - float widthFactor = 0.f; - - /** - * true if this view was added during layout and needs to be measured - * before being positioned. - */ - boolean needsMeasure; - - /** - * Adapter position this view is for if !isDecor - */ - int position; - - /** - * Current child index within the ViewPager that this view occupies - */ - int childIndex; - - public LayoutParams() { - super(FILL_PARENT, FILL_PARENT); - } - - public LayoutParams(Context context, AttributeSet attrs) { - super(context, attrs); - - final TypedArray a = context.obtainStyledAttributes(attrs, LAYOUT_ATTRS); - gravity = a.getInteger(0, Gravity.TOP); - a.recycle(); - } - } - - static class ViewPositionComparator implements Comparator { - @Override - public int compare(View lhs, View rhs) { - final LayoutParams llp = (LayoutParams) lhs.getLayoutParams(); - final LayoutParams rlp = (LayoutParams) rhs.getLayoutParams(); - if (llp.isDecor != rlp.isDecor) { - return llp.isDecor ? 1 : -1; - } - return llp.position - rlp.position; - } - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java b/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java deleted file mode 100644 index ce14cc98..00000000 --- a/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn; - -import android.annotation.SuppressLint; -import android.annotation.TargetApi; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.Build; -import android.os.IBinder; -import android.os.RemoteException; -import android.service.quicksettings.Tile; -import android.service.quicksettings.TileService; -import android.widget.Toast; - -import de.blinkt.openvpn.core.ConnectionStatus; -import de.blinkt.openvpn.core.IOpenVPNServiceInternal; -import de.blinkt.openvpn.core.OpenVPNService; -import de.blinkt.openvpn.core.ProfileManager; -import de.blinkt.openvpn.core.VpnStatus; - - -/** - * Created by arne on 22.04.16. - */ -@TargetApi(Build.VERSION_CODES.N) -public class OpenVPNTileService extends TileService implements VpnStatus.StateListener { - - @SuppressLint("Override") - @TargetApi(Build.VERSION_CODES.N) - @Override - public void onClick() { - super.onClick(); - final VpnProfile bootProfile = getQSVPN(); - if (bootProfile == null) { - Toast.makeText(this, R.string.novpn_selected, Toast.LENGTH_SHORT).show(); - } else { - if (!isLocked()) - clickAction(bootProfile); - else - unlockAndRun(new Runnable() { - @Override - public void run() { - clickAction(bootProfile); - } - }); - } - } - - private void clickAction(VpnProfile bootProfile) { - if (VpnStatus.isVPNActive()) { - Intent intent = new Intent(this, OpenVPNService.class); - intent.setAction(OpenVPNService.START_SERVICE); - bindService(intent, new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName componentName, IBinder binder) { - IOpenVPNServiceInternal service = IOpenVPNServiceInternal.Stub.asInterface(binder); - - if (service != null) - try { - service.stopVPN(false); - } catch (RemoteException e) { - VpnStatus.logException(e); - } - - unbindService(this); - } - - @Override - public void onServiceDisconnected(ComponentName componentName) { - - } - }, Context.BIND_AUTO_CREATE); - } else - launchVPN(bootProfile, this); - } - - - @SuppressLint("Override") - @TargetApi(Build.VERSION_CODES.N) - void launchVPN(VpnProfile profile, Context context) { - Intent startVpnIntent = new Intent(Intent.ACTION_MAIN); - startVpnIntent.setClass(context, LaunchVPN.class); - startVpnIntent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUIDString()); - startVpnIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startVpnIntent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); - - context.startActivity(startVpnIntent); - } - - @TargetApi(Build.VERSION_CODES.N) - @Override - public void onTileAdded() { - } - - @Override - public void onStartListening() { - super.onStartListening(); - VpnStatus.addStateListener(this); - } - - - @TargetApi(Build.VERSION_CODES.N) - public VpnProfile getQSVPN() { - return ProfileManager.getAlwaysOnVPN(this); - } - - @Override - public void updateState(String state, String logmessage, int localizedResId, ConnectionStatus level) { - VpnProfile vpn; - Tile t = getQsTile(); - if (level == ConnectionStatus.LEVEL_AUTH_FAILED || level == ConnectionStatus.LEVEL_NOTCONNECTED) { - // No VPN connected, use stadnard VPN - vpn = getQSVPN(); - if (vpn == null) { - t.setLabel(getString(R.string.novpn_selected)); - t.setState(Tile.STATE_UNAVAILABLE); - } else { - t.setLabel(getString(R.string.qs_connect, vpn.getName())); - t.setState(Tile.STATE_INACTIVE); - } - } else { - vpn = ProfileManager.get(getBaseContext(), VpnStatus.getLastConnectedVPNProfile()); - String name; - if (vpn == null) - name = "null?!"; - else - name = vpn.getName(); - t.setLabel(getString(R.string.qs_disconnect, name)); - t.setState(Tile.STATE_ACTIVE); - } - - t.updateTile(); - } - - @Override - public void setConnectedVPN(String uuid) { - - } - - @Override - public void onStopListening() { - VpnStatus.removeStateListener(this); - super.onStopListening(); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/BaseActivity.java b/main/src/main/java/de/blinkt/openvpn/activities/BaseActivity.java deleted file mode 100644 index 7258d8d6..00000000 --- a/main/src/main/java/de/blinkt/openvpn/activities/BaseActivity.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2012-2015 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.activities; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.UiModeManager; -import android.content.Context; -import android.content.RestrictionsManager; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.os.UserManager; -import android.view.Window; -import de.blinkt.openvpn.api.AppRestrictions; - -public class BaseActivity extends Activity { - private boolean isAndroidTV() { - final UiModeManager uiModeManager = (UiModeManager) getSystemService(Activity.UI_MODE_SERVICE); - return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - if (isAndroidTV()) { - requestWindowFeature(Window.FEATURE_OPTIONS_PANEL); - } - super.onCreate(savedInstanceState); - } - - @Override - protected void onResume() { - super.onResume(); - } - - @Override - protected void onPause() { - super.onPause(); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/ConfigConverter.java b/main/src/main/java/de/blinkt/openvpn/activities/ConfigConverter.java deleted file mode 100644 index 38b47b5a..00000000 --- a/main/src/main/java/de/blinkt/openvpn/activities/ConfigConverter.java +++ /dev/null @@ -1,847 +0,0 @@ - -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.activities; - -import android.Manifest; -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.provider.OpenableColumns; -import android.security.KeyChain; -import android.security.KeyChainAliasCallback; -import android.support.annotation.NonNull; -import android.text.TextUtils; -import android.util.Base64; -import android.util.Pair; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.TextView; -import android.widget.Toast; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.ConfigParser; -import de.blinkt.openvpn.core.ConfigParser.ConfigParseError; -import de.blinkt.openvpn.core.ProfileManager; -import de.blinkt.openvpn.fragments.Utils; -import de.blinkt.openvpn.views.FileSelectLayout; - -import static de.blinkt.openvpn.views.FileSelectLayout.FileSelectCallback; - -public class ConfigConverter extends BaseActivity implements FileSelectCallback, View.OnClickListener { - - public static final String IMPORT_PROFILE = "de.blinkt.openvpn.IMPORT_PROFILE"; - private static final int RESULT_INSTALLPKCS12 = 7; - private static final int CHOOSE_FILE_OFFSET = 1000; - public static final String VPNPROFILE = "vpnProfile"; - private static final int PERMISSION_REQUEST_EMBED_FILES = 37231; - private static final int PERMISSION_REQUEST_READ_URL = PERMISSION_REQUEST_EMBED_FILES + 1; - - private VpnProfile mResult; - - private transient List mPathsegments; - - private String mAliasName = null; - - - private Map fileSelectMap = new HashMap<>(); - private String mEmbeddedPwFile; - private Vector mLogEntries = new Vector<>(); - private Uri mSourceUri; - private EditText mProfilename; - private AsyncTask mImportTask; - private LinearLayout mLogLayout; - private TextView mProfilenameLabel; - - @Override - public void onClick(View v) { - if (v.getId() == R.id.fab_save) - userActionSaveProfile(); - if (v.getId() == R.id.permssion_hint && Build.VERSION.SDK_INT == Build.VERSION_CODES.M) - doRequestSDCardPermission(PERMISSION_REQUEST_EMBED_FILES); - - } - - @TargetApi(Build.VERSION_CODES.M) - private void doRequestSDCardPermission(int requestCode) { - requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, requestCode); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - // Permission declined, do nothing - if (grantResults.length == 0 || grantResults[0] == PackageManager.PERMISSION_DENIED) - return; - - // Reset file select dialogs - findViewById(R.id.files_missing_hint).setVisibility(View.GONE); - findViewById(R.id.permssion_hint).setVisibility(View.GONE); - LinearLayout fileroot = (LinearLayout) findViewById(R.id.config_convert_root); - for (int i = 0; i < fileroot.getChildCount(); ) { - if (fileroot.getChildAt(i) instanceof FileSelectLayout) - fileroot.removeViewAt(i); - else - i++; - } - - if (requestCode == PERMISSION_REQUEST_EMBED_FILES) - embedFiles(null); - - else if (requestCode == PERMISSION_REQUEST_READ_URL) { - if (mSourceUri != null) - doImportUri(mSourceUri); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.cancel) { - setResult(Activity.RESULT_CANCELED); - finish(); - } else if (item.getItemId() == R.id.ok) { - return userActionSaveProfile(); - } - - return super.onOptionsItemSelected(item); - - } - - private boolean userActionSaveProfile() { - if (mResult == null) { - log(R.string.import_config_error); - Toast.makeText(this, R.string.import_config_error, Toast.LENGTH_LONG).show(); - return true; - } - - mResult.mName = mProfilename.getText().toString(); - ProfileManager vpl = ProfileManager.getInstance(this); - if (vpl.getProfileByName(mResult.mName) != null) { - mProfilename.setError(getString(R.string.duplicate_profile_name)); - return true; - } - - Intent in = installPKCS12(); - - if (in != null) - startActivityForResult(in, RESULT_INSTALLPKCS12); - else - saveProfile(); - - return true; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - if (mResult != null) - outState.putSerializable(VPNPROFILE, mResult); - outState.putString("mAliasName", mAliasName); - - - String[] logentries = mLogEntries.toArray(new String[mLogEntries.size()]); - - outState.putStringArray("logentries", logentries); - - int[] fileselects = new int[fileSelectMap.size()]; - int k = 0; - for (Utils.FileType key : fileSelectMap.keySet()) { - fileselects[k] = key.getValue(); - k++; - } - outState.putIntArray("fileselects", fileselects); - outState.putString("pwfile", mEmbeddedPwFile); - outState.putParcelable("mSourceUri", mSourceUri); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent result) { - if (requestCode == RESULT_INSTALLPKCS12 && resultCode == Activity.RESULT_OK) { - showCertDialog(); - } - - if (resultCode == Activity.RESULT_OK && requestCode >= CHOOSE_FILE_OFFSET) { - Utils.FileType type = Utils.FileType.getFileTypeByValue(requestCode - CHOOSE_FILE_OFFSET); - - - FileSelectLayout fs = fileSelectMap.get(type); - fs.parseResponse(result, this); - - String data = fs.getData(); - - switch (type) { - case USERPW_FILE: - mEmbeddedPwFile = data; - break; - case PKCS12: - mResult.mPKCS12Filename = data; - break; - case TLS_AUTH_FILE: - mResult.mTLSAuthFilename = data; - break; - case CA_CERTIFICATE: - mResult.mCaFilename = data; - break; - case CLIENT_CERTIFICATE: - mResult.mClientCertFilename = data; - break; - case KEYFILE: - mResult.mClientKeyFilename = data; - break; - case CRL_FILE: - mResult.mCrlFilename = data; - break; - default: - throw new RuntimeException("Type is wrong somehow?"); - } - } - - super.onActivityResult(requestCode, resultCode, result); - } - - private void saveProfile() { - Intent result = new Intent(); - ProfileManager vpl = ProfileManager.getInstance(this); - - if (!TextUtils.isEmpty(mEmbeddedPwFile)) - ConfigParser.useEmbbedUserAuth(mResult, mEmbeddedPwFile); - - vpl.addProfile(mResult); - vpl.saveProfile(this, mResult); - vpl.saveProfileList(this); - result.putExtra(VpnProfile.EXTRA_PROFILEUUID, mResult.getUUID().toString()); - setResult(Activity.RESULT_OK, result); - finish(); - } - - public void showCertDialog() { - try { - //noinspection WrongConstant - KeyChain.choosePrivateKeyAlias(this, - new KeyChainAliasCallback() { - - public void alias(String alias) { - // Credential alias selected. Remember the alias selection for future use. - mResult.mAlias = alias; - saveProfile(); - } - - - }, - new String[]{"RSA", "EC"}, // List of acceptable key types. null for any - null, // issuer, null for any - mResult.mServerName, // host name of server requesting the cert, null if unavailable - -1, // port of server requesting the cert, -1 if unavailable - mAliasName); // alias to preselect, null if unavailable - } catch (ActivityNotFoundException anf) { - Builder ab = new AlertDialog.Builder(this); - ab.setTitle(R.string.broken_image_cert_title); - ab.setMessage(R.string.broken_image_cert); - ab.setPositiveButton(android.R.string.ok, null); - ab.show(); - } - } - - - private Intent installPKCS12() { - - if (!((CheckBox) findViewById(R.id.importpkcs12)).isChecked()) { - setAuthTypeToEmbeddedPKCS12(); - return null; - - } - String pkcs12datastr = mResult.mPKCS12Filename; - if (VpnProfile.isEmbedded(pkcs12datastr)) { - Intent inkeyIntent = KeyChain.createInstallIntent(); - - pkcs12datastr = VpnProfile.getEmbeddedContent(pkcs12datastr); - - - byte[] pkcs12data = Base64.decode(pkcs12datastr, Base64.DEFAULT); - - - inkeyIntent.putExtra(KeyChain.EXTRA_PKCS12, pkcs12data); - - if (mAliasName.equals("")) - mAliasName = null; - - if (mAliasName != null) { - inkeyIntent.putExtra(KeyChain.EXTRA_NAME, mAliasName); - } - return inkeyIntent; - - } - return null; - } - - - private void setAuthTypeToEmbeddedPKCS12() { - if (VpnProfile.isEmbedded(mResult.mPKCS12Filename)) { - if (mResult.mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) - mResult.mAuthenticationType = VpnProfile.TYPE_USERPASS_PKCS12; - - if (mResult.mAuthenticationType == VpnProfile.TYPE_KEYSTORE) - mResult.mAuthenticationType = VpnProfile.TYPE_PKCS12; - - } - } - - - private String getUniqueProfileName(String possibleName) { - - int i = 0; - - ProfileManager vpl = ProfileManager.getInstance(this); - - String newname = possibleName; - - // Default to - if (mResult.mName != null && !ConfigParser.CONVERTED_PROFILE.equals(mResult.mName)) - newname = mResult.mName; - - while (newname == null || vpl.getProfileByName(newname) != null) { - i++; - if (i == 1) - newname = getString(R.string.converted_profile); - else - newname = getString(R.string.converted_profile_i, i); - } - - return newname; - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.import_menu, menu); - return true; - } - - private String embedFile(String filename, Utils.FileType type, boolean onlyFindFileAndNullonNotFound) { - if (filename == null) - return null; - - // Already embedded, nothing to do - if (VpnProfile.isEmbedded(filename)) - return filename; - - File possibleFile = findFile(filename, type); - if (possibleFile == null) - if (onlyFindFileAndNullonNotFound) - return null; - else - return filename; - else if (onlyFindFileAndNullonNotFound) - return possibleFile.getAbsolutePath(); - else - return readFileContent(possibleFile, type == Utils.FileType.PKCS12); - - } - - - private Pair getFileDialogInfo(Utils.FileType type) { - int titleRes = 0; - String value = null; - switch (type) { - case KEYFILE: - titleRes = R.string.client_key_title; - if (mResult != null) - value = mResult.mClientKeyFilename; - break; - case CLIENT_CERTIFICATE: - titleRes = R.string.client_certificate_title; - if (mResult != null) - value = mResult.mClientCertFilename; - break; - case CA_CERTIFICATE: - titleRes = R.string.ca_title; - if (mResult != null) - value = mResult.mCaFilename; - break; - case TLS_AUTH_FILE: - titleRes = R.string.tls_auth_file; - if (mResult != null) - value = mResult.mTLSAuthFilename; - break; - case PKCS12: - titleRes = R.string.client_pkcs12_title; - if (mResult != null) - value = mResult.mPKCS12Filename; - break; - - case USERPW_FILE: - titleRes = R.string.userpw_file; - value = mEmbeddedPwFile; - break; - - case CRL_FILE: - titleRes = R.string.crl_file; - value = mResult.mCrlFilename; - break; - } - - return Pair.create(titleRes, value); - - } - - private File findFile(String filename, Utils.FileType fileType) { - File foundfile = findFileRaw(filename); - - if (foundfile == null && filename != null && !filename.equals("")) { - log(R.string.import_could_not_open, filename); - } - fileSelectMap.put(fileType, null); - - return foundfile; - } - - private void addMissingFileDialogs() - { - for (Map.Entry item: fileSelectMap.entrySet()) { - if (item.getValue()==null) - addFileSelectDialog(item.getKey()); - } - } - - private void addFileSelectDialog(Utils.FileType type) { - - Pair fileDialogInfo = getFileDialogInfo(type); - - boolean isCert = type == Utils.FileType.CA_CERTIFICATE || type == Utils.FileType.CLIENT_CERTIFICATE; - FileSelectLayout fl = new FileSelectLayout(this, getString(fileDialogInfo.first), isCert, false); - fileSelectMap.put(type, fl); - fl.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - - ((LinearLayout) findViewById(R.id.config_convert_root)).addView(fl, 2); - findViewById(R.id.files_missing_hint).setVisibility(View.VISIBLE); - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) - checkPermission(); - - fl.setData(fileDialogInfo.second, this); - int i = getFileLayoutOffset(type); - fl.setCaller(this, i, type); - - } - - @TargetApi(Build.VERSION_CODES.M) - private void checkPermission() { - if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - findViewById(R.id.permssion_hint).setVisibility(View.VISIBLE); - findViewById(R.id.permssion_hint).setOnClickListener(this); - } - } - - private int getFileLayoutOffset(Utils.FileType type) { - return CHOOSE_FILE_OFFSET + type.getValue(); - } - - - private File findFileRaw(String filename) { - if (filename == null || filename.equals("")) - return null; - - // Try diffent path relative to /mnt/sdcard - File sdcard = Environment.getExternalStorageDirectory(); - File root = new File("/"); - - HashSet dirlist = new HashSet<>(); - - for (int i = mPathsegments.size() - 1; i >= 0; i--) { - String path = ""; - for (int j = 0; j <= i; j++) { - path += "/" + mPathsegments.get(j); - } - // Do a little hackish dance for the Android File Importer - // /document/primary:ovpn/openvpn-imt.conf - - - if (path.indexOf(':') != -1 && path.lastIndexOf('/') > path.indexOf(':')) { - String possibleDir = path.substring(path.indexOf(':') + 1, path.length()); - // Unquote chars in the path - try { - possibleDir = URLDecoder.decode(possibleDir, "UTF-8"); - } catch (UnsupportedEncodingException ignored) {} - - possibleDir = possibleDir.substring(0, possibleDir.lastIndexOf('/')); - - - - - dirlist.add(new File(sdcard, possibleDir)); - - } - dirlist.add(new File(path)); - - - } - dirlist.add(sdcard); - dirlist.add(root); - - - String[] fileparts = filename.split("/"); - for (File rootdir : dirlist) { - String suffix = ""; - for (int i = fileparts.length - 1; i >= 0; i--) { - if (i == fileparts.length - 1) - suffix = fileparts[i]; - else - suffix = fileparts[i] + "/" + suffix; - - File possibleFile = new File(rootdir, suffix); - if (possibleFile.canRead()) - return possibleFile; - - } - } - return null; - } - - String readFileContent(File possibleFile, boolean base64encode) { - byte[] filedata; - try { - filedata = readBytesFromFile(possibleFile); - } catch (IOException e) { - log(e.getLocalizedMessage()); - return null; - } - - String data; - if (base64encode) { - data = Base64.encodeToString(filedata, Base64.DEFAULT); - } else { - data = new String(filedata); - - } - - return VpnProfile.DISPLAYNAME_TAG + possibleFile.getName() + VpnProfile.INLINE_TAG + data; - - } - - - private byte[] readBytesFromFile(File file) throws IOException { - InputStream input = new FileInputStream(file); - - long len = file.length(); - if (len > VpnProfile.MAX_EMBED_FILE_SIZE) - throw new IOException("File size of file to import too large."); - - // Create the byte array to hold the data - byte[] bytes = new byte[(int) len]; - - // Read in the bytes - int offset = 0; - int bytesRead; - while (offset < bytes.length - && (bytesRead = input.read(bytes, offset, bytes.length - offset)) >= 0) { - offset += bytesRead; - } - - input.close(); - return bytes; - } - - void embedFiles(ConfigParser cp) { - // This where I would like to have a c++ style - // void embedFile(std::string & option) - - if (mResult.mPKCS12Filename != null) { - File pkcs12file = findFileRaw(mResult.mPKCS12Filename); - if (pkcs12file != null) { - mAliasName = pkcs12file.getName().replace(".p12", ""); - } else { - mAliasName = "Imported PKCS12"; - } - } - - - mResult.mCaFilename = embedFile(mResult.mCaFilename, Utils.FileType.CA_CERTIFICATE, false); - mResult.mClientCertFilename = embedFile(mResult.mClientCertFilename, Utils.FileType.CLIENT_CERTIFICATE, false); - mResult.mClientKeyFilename = embedFile(mResult.mClientKeyFilename, Utils.FileType.KEYFILE, false); - mResult.mTLSAuthFilename = embedFile(mResult.mTLSAuthFilename, Utils.FileType.TLS_AUTH_FILE, false); - mResult.mPKCS12Filename = embedFile(mResult.mPKCS12Filename, Utils.FileType.PKCS12, false); - mResult.mCrlFilename = embedFile(mResult.mCrlFilename, Utils.FileType.CRL_FILE, true); - if (cp != null) { - mEmbeddedPwFile = cp.getAuthUserPassFile(); - mEmbeddedPwFile = embedFile(cp.getAuthUserPassFile(), Utils.FileType.USERPW_FILE, false); - } - - } - - private void updateFileSelectDialogs() { - for (Map.Entry fl : fileSelectMap.entrySet()) { - fl.getValue().setData(getFileDialogInfo(fl.getKey()).second, this); - } - } - - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.config_converter); - - ImageButton fab_button = (ImageButton) findViewById(R.id.fab_save); - if (fab_button != null) { - fab_button.setOnClickListener(this); - findViewById(R.id.fab_footerspace).setVisibility(View.VISIBLE); - } - - mLogLayout = (LinearLayout) findViewById(R.id.config_convert_root); - - - mProfilename = (EditText) findViewById(R.id.profilename); - mProfilenameLabel = (TextView) findViewById(R.id.profilename_label); - - if (savedInstanceState != null && savedInstanceState.containsKey(VPNPROFILE)) { - mResult = (VpnProfile) savedInstanceState.getSerializable(VPNPROFILE); - mAliasName = savedInstanceState.getString("mAliasName"); - mEmbeddedPwFile = savedInstanceState.getString("pwfile"); - mSourceUri = savedInstanceState.getParcelable("mSourceUri"); - mProfilename.setText(mResult.mName); - - if (savedInstanceState.containsKey("logentries")) { - //noinspection ConstantConditions - for (String logItem : savedInstanceState.getStringArray("logentries")) - log(logItem); - } - if (savedInstanceState.containsKey("fileselects")) { - //noinspection ConstantConditions - for (int k : savedInstanceState.getIntArray("fileselects")) { - addFileSelectDialog(Utils.FileType.getFileTypeByValue(k)); - } - } - return; - } - - - final android.content.Intent intent = getIntent(); - - if (intent != null) { - doImportIntent(intent); - - // We parsed the intent, relay on saved instance for restoring - setIntent(null); - } - - - } - - private void doImportIntent(Intent intent) { - final Uri data = intent.getData(); - if (data != null) { - mSourceUri = data; - doImportUri(data); - } - } - - private void doImportUri(Uri data) { - //log(R.string.import_experimental); - log(R.string.importing_config, data.toString()); - String possibleName = null; - if ((data.getScheme() != null && data.getScheme().equals("file")) || - (data.getLastPathSegment() != null && - (data.getLastPathSegment().endsWith(".ovpn") || - data.getLastPathSegment().endsWith(".conf"))) - ) { - possibleName = data.getLastPathSegment(); - if (possibleName.lastIndexOf('/') != -1) - possibleName = possibleName.substring(possibleName.lastIndexOf('/') + 1); - - } - - mPathsegments = data.getPathSegments(); - - Cursor cursor = getContentResolver().query(data, null, null, null, null); - - try { - - if (cursor != null && cursor.moveToFirst()) { - int columnIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); - - if (columnIndex != -1) { - String displayName = cursor.getString(columnIndex); - if (displayName != null) - possibleName = displayName; - } - columnIndex = cursor.getColumnIndex("mime_type"); - if (columnIndex != -1) { - log("Mime type: " + cursor.getString(columnIndex)); - } - } - } finally { - if (cursor != null) - cursor.close(); - } - if (possibleName != null) { - possibleName = possibleName.replace(".ovpn", ""); - possibleName = possibleName.replace(".conf", ""); - } - - startImportTask(data, possibleName); - - - } - - private void startImportTask(final Uri data, final String possibleName) { - mImportTask = new AsyncTask() { - private ProgressBar mProgress; - - @Override - protected void onPreExecute() { - mProgress = new ProgressBar(ConfigConverter.this); - addViewToLog(mProgress); - } - - @Override - protected Integer doInBackground(Void... params) { - try { - InputStream is = getContentResolver().openInputStream(data); - - doImport(is); - is.close(); - if (mResult==null) - return -3; - } catch (IOException| SecurityException se) - - { - log(R.string.import_content_resolve_error + ":" + se.getLocalizedMessage()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) - checkMarschmallowFileImportError(data); - return -2; - } - - return 0; - } - - @Override - protected void onPostExecute(Integer errorCode) { - mLogLayout.removeView(mProgress); - addMissingFileDialogs(); - updateFileSelectDialogs(); - - if (errorCode == 0) { - displayWarnings(); - mResult.mName = getUniqueProfileName(possibleName); - mProfilename.setVisibility(View.VISIBLE); - mProfilenameLabel.setVisibility(View.VISIBLE); - mProfilename.setText(mResult.getName()); - - log(R.string.import_done); - } - } - }.execute(); - } - - - @TargetApi(Build.VERSION_CODES.M) - private void checkMarschmallowFileImportError(Uri data) { - // Permission already granted, not the source of the error - if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) - return; - - // We got a file:/// URL and have no permission to read it. Technically an error of the calling app since - // it makes an assumption about other apps being able to read the url but well ... - if (data != null && "file".equals(data.getScheme())) - doRequestSDCardPermission(PERMISSION_REQUEST_READ_URL); - - } - - - @Override - protected void onStart() { - super.onStart(); - } - - private void log(final String logmessage) { - runOnUiThread(new Runnable() { - @Override - public void run() { - TextView tv = new TextView(ConfigConverter.this); - mLogEntries.add(logmessage); - tv.setText(logmessage); - - addViewToLog(tv); - } - }); - } - - private void addViewToLog(View view) { - mLogLayout.addView(view, mLogLayout.getChildCount() - 1); - } - - private void doImport(InputStream is) { - ConfigParser cp = new ConfigParser(); - try { - InputStreamReader isr = new InputStreamReader(is); - - cp.parseConfig(isr); - mResult = cp.convertProfile(); - embedFiles(cp); - return; - - } catch (IOException | ConfigParseError e) { - log(R.string.error_reading_config_file); - log(e.getLocalizedMessage()); - } - mResult = null; - - } - - private void displayWarnings() { - if (mResult.mUseCustomConfig) { - log(R.string.import_warning_custom_options); - String copt = mResult.mCustomConfigOptions; - if (copt.startsWith("#")) { - int until = copt.indexOf('\n'); - copt = copt.substring(until + 1); - } - - log(copt); - } - - if (mResult.mAuthenticationType == VpnProfile.TYPE_KEYSTORE || - mResult.mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) { - findViewById(R.id.importpkcs12).setVisibility(View.VISIBLE); - } - - } - - private void log(int ressourceId, Object... formatArgs) { - log(getString(ressourceId, formatArgs)); - } - -} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java b/main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java deleted file mode 100644 index e1cb8862..00000000 --- a/main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.activities; - -import android.app.ListActivity; -import android.content.Intent; -import android.os.Bundle; -import android.os.Parcelable; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ArrayAdapter; -import android.widget.ListView; -import android.widget.TextView; -import de.blinkt.openvpn.LaunchVPN; -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.ProfileManager; - -import java.util.Collection; -import java.util.Vector; - -/** - * This Activity actually handles two stages of a launcher shortcut's life cycle. - * - * 1. Your application offers to provide shortcuts to the launcher. When - * the user installs a shortcut, an activity within your application - * generates the actual shortcut and returns it to the launcher, where it - * is shown to the user as an icon. - * - * 2. Any time the user clicks on an installed shortcut, an intent is sent. - * Typically this would then be handled as necessary by an activity within - * your application. - * - * We handle stage 1 (creating a shortcut) by simply sending back the information (in the form - * of an {@link android.content.Intent} that the launcher will use to create the shortcut. - * - * You can also implement this in an interactive way, by having your activity actually present - * UI for the user to select the specific nature of the shortcut, such as a contact, picture, URL, - * media item, or action. - * - * We handle stage 2 (responding to a shortcut) in this sample by simply displaying the contents - * of the incoming {@link android.content.Intent}. - * - * In a real application, you would probably use the shortcut intent to display specific content - * or start a particular operation. - */ -public class CreateShortcuts extends ListActivity implements OnItemClickListener { - - - private static final int START_VPN_PROFILE= 70; - - - private ProfileManager mPM; - private VpnProfile mSelectedProfile; - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - mPM =ProfileManager.getInstance(this); - - } - - @Override - protected void onStart() { - super.onStart(); - // Resolve the intent - - createListView(); - } - - private void createListView() { - ListView lv = getListView(); - //lv.setTextFilterEnabled(true); - - Collection vpnList = mPM.getProfiles(); - - Vector vpnNames=new Vector(); - for (VpnProfile vpnProfile : vpnList) { - vpnNames.add(vpnProfile.mName); - } - - - - ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,vpnNames); - lv.setAdapter(adapter); - - lv.setOnItemClickListener(this); - } - - /** - * This function creates a shortcut and returns it to the caller. There are actually two - * intents that you will send back. - * - * The first intent serves as a container for the shortcut and is returned to the launcher by - * setResult(). This intent must contain three fields: - * - *

    - *
  • {@link android.content.Intent#EXTRA_SHORTCUT_INTENT} The shortcut intent.
  • - *
  • {@link android.content.Intent#EXTRA_SHORTCUT_NAME} The text that will be displayed with - * the shortcut.
  • - *
  • {@link android.content.Intent#EXTRA_SHORTCUT_ICON} The shortcut's icon, if provided as a - * bitmap, or {@link android.content.Intent#EXTRA_SHORTCUT_ICON_RESOURCE} if provided as - * a drawable resource.
  • - *
- * - * If you use a simple drawable resource, note that you must wrapper it using - * {@link android.content.Intent.ShortcutIconResource}, as shown below. This is required so - * that the launcher can access resources that are stored in your application's .apk file. If - * you return a bitmap, such as a thumbnail, you can simply put the bitmap into the extras - * bundle using {@link android.content.Intent#EXTRA_SHORTCUT_ICON}. - * - * The shortcut intent can be any intent that you wish the launcher to send, when the user - * clicks on the shortcut. Typically this will be {@link android.content.Intent#ACTION_VIEW} - * with an appropriate Uri for your content, but any Intent will work here as long as it - * triggers the desired action within your Activity. - * @param profile - */ - private void setupShortcut(VpnProfile profile) { - // First, set up the shortcut intent. For this example, we simply create an intent that - // will bring us directly back to this activity. A more typical implementation would use a - // data Uri in order to display a more specific result, or a custom action in order to - // launch a specific operation. - - Intent shortcutIntent = new Intent(Intent.ACTION_MAIN); - shortcutIntent.setClass(this, LaunchVPN.class); - shortcutIntent.putExtra(LaunchVPN.EXTRA_KEY,profile.getUUID().toString()); - - // Then, set up the container intent (the response to the caller) - - Intent intent = new Intent(); - intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); - intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, profile.getName()); - Parcelable iconResource = Intent.ShortcutIconResource.fromContext( - this, R.mipmap.ic_launcher); - intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); - - // Now, return the result to the launcher - - setResult(RESULT_OK, intent); - } - - - @Override - public void onItemClick(AdapterView parent, View view, int position, - long id) { - String profileName = ((TextView) view).getText().toString(); - - VpnProfile profile = mPM.getProfileByName(profileName); - - setupShortcut(profile); - finish(); - } - -} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/FileSelect.java b/main/src/main/java/de/blinkt/openvpn/activities/FileSelect.java deleted file mode 100644 index 44538cb4..00000000 --- a/main/src/main/java/de/blinkt/openvpn/activities/FileSelect.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.activities; - - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - -import android.Manifest; -import android.annotation.TargetApi; -import android.app.ActionBar; -import android.app.ActionBar.Tab; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.util.Base64; -import android.widget.Toast; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.fragments.FileSelectionFragment; -import de.blinkt.openvpn.fragments.InlineFileTab; - -public class FileSelect extends BaseActivity { - public static final String RESULT_DATA = "RESULT_PATH"; - public static final String START_DATA = "START_DATA"; - public static final String WINDOW_TITLE = "WINDOW_TILE"; - public static final String NO_INLINE_SELECTION = "de.blinkt.openvpn.NO_INLINE_SELECTION"; - public static final String SHOW_CLEAR_BUTTON = "de.blinkt.openvpn.SHOW_CLEAR_BUTTON"; - public static final String DO_BASE64_ENCODE = "de.blinkt.openvpn.BASE64ENCODE"; - private static final int PERMISSION_REQUEST = 23621; - - private FileSelectionFragment mFSFragment; - private InlineFileTab mInlineFragment; - private String mData; - private Tab inlineFileTab; - private Tab fileExplorerTab; - private boolean mNoInline; - private boolean mShowClear; - private boolean mBase64Encode; - - - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - setContentView(R.layout.file_dialog); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) - checkPermission(); - - mData = getIntent().getStringExtra(START_DATA); - if(mData==null) - mData=Environment.getExternalStorageDirectory().getPath(); - - String title = getIntent().getStringExtra(WINDOW_TITLE); - int titleId = getIntent().getIntExtra(WINDOW_TITLE, 0); - if(titleId!=0) - title =getString(titleId); - if(title!=null) - setTitle(title); - - mNoInline = getIntent().getBooleanExtra(NO_INLINE_SELECTION, false); - mShowClear = getIntent().getBooleanExtra(SHOW_CLEAR_BUTTON, false); - mBase64Encode = getIntent().getBooleanExtra(DO_BASE64_ENCODE, false); - - ActionBar bar = getActionBar(); - bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); - fileExplorerTab = bar.newTab().setText(R.string.file_explorer_tab); - inlineFileTab = bar.newTab().setText(R.string.inline_file_tab); - - mFSFragment = new FileSelectionFragment(); - fileExplorerTab.setTabListener(new MyTabsListener(this, mFSFragment)); - bar.addTab(fileExplorerTab); - - if(!mNoInline) { - mInlineFragment = new InlineFileTab(); - inlineFileTab.setTabListener(new MyTabsListener(this, mInlineFragment)); - bar.addTab(inlineFileTab); - } else { - mFSFragment.setNoInLine(); - } - - - } - - - @TargetApi(Build.VERSION_CODES.M) - private void checkPermission() { - if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST); - } - } - - @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - - if (grantResults[0] == PackageManager.PERMISSION_DENIED) { - if (mNoInline) { - setResult(RESULT_CANCELED); - finish(); - } else { - if (fileExplorerTab!=null) - getActionBar().removeTab(fileExplorerTab); - } - } else { - mFSFragment.refresh(); - } - } - - public boolean showClear() { - if(mData == null || mData.equals("")) - return false; - else - return mShowClear; - } - - protected class MyTabsListener implements ActionBar.TabListener - { - private Fragment mFragment; - private boolean mAdded=false; - - public MyTabsListener( Activity activity, Fragment fragment){ - this.mFragment = fragment; - } - - public void onTabSelected(Tab tab, FragmentTransaction ft) { - // Check if the fragment is already initialized - if (!mAdded) { - // If not, instantiate and add it to the activity - ft.add(android.R.id.content, mFragment); - mAdded =true; - } else { - // If it exists, simply attach it in order to show it - ft.attach(mFragment); - } - } - - @Override - public void onTabUnselected(Tab tab, FragmentTransaction ft) { - ft.detach(mFragment); - } - - @Override - public void onTabReselected(Tab tab, FragmentTransaction ft) { - - } - } - - public void importFile(String path) { - File ifile = new File(path); - Exception fe = null; - try { - - String data = ""; - - byte[] fileData = readBytesFromFile(ifile) ; - if(mBase64Encode) - data += Base64.encodeToString(fileData, Base64.DEFAULT); - else - data += new String(fileData); - - mData =data; - - /* - mInlineFragment.setData(data); - getActionBar().selectTab(inlineFileTab); */ - saveInlineData(ifile.getName(), data); - } catch (IOException e) { - fe =e; - } - if(fe!=null) { - Builder ab = new AlertDialog.Builder(this); - ab.setTitle(R.string.error_importing_file); - ab.setMessage(getString(R.string.import_error_message) + "\n" + fe.getLocalizedMessage()); - ab.setPositiveButton(android.R.string.ok, null); - ab.show(); - } - } - - static private byte[] readBytesFromFile(File file) throws IOException { - InputStream input = new FileInputStream(file); - - long len= file.length(); - if (len > VpnProfile.MAX_EMBED_FILE_SIZE) - throw new IOException("selected file size too big to embed into profile"); - - // Create the byte array to hold the data - byte[] bytes = new byte[(int) len]; - - // Read in the bytes - int offset = 0; - int bytesRead = 0; - while (offset < bytes.length - && (bytesRead=input.read(bytes, offset, bytes.length-offset)) >= 0) { - offset += bytesRead; - } - - input.close(); - return bytes; - } - - - public void setFile(String path) { - Intent intent = new Intent(); - intent.putExtra(RESULT_DATA, path); - setResult(Activity.RESULT_OK,intent); - finish(); - } - - public String getSelectPath() { - if(VpnProfile.isEmbedded(mData)) - return mData; - else - return Environment.getExternalStorageDirectory().getPath(); - } - - public CharSequence getInlineData() { - if(VpnProfile.isEmbedded(mData)) - return VpnProfile.getEmbeddedContent(mData); - else - return ""; - } - - public void clearData() { - Intent intent = new Intent(); - intent.putExtra(RESULT_DATA, (String)null); - setResult(Activity.RESULT_OK,intent); - finish(); - - } - - public void saveInlineData(String fileName, String string) { - Intent intent = new Intent(); - - if(fileName==null) - intent.putExtra(RESULT_DATA, VpnProfile.INLINE_TAG + string); - else - intent.putExtra(RESULT_DATA,VpnProfile.DISPLAYNAME_TAG + fileName + VpnProfile.INLINE_TAG + string); - setResult(Activity.RESULT_OK, intent); - finish(); - - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java b/main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java deleted file mode 100644 index db70eca9..00000000 --- a/main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.activities; - -import android.app.Activity; -import android.os.Bundle; -import android.view.MenuItem; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.fragments.LogFragment; - -/** - * Created by arne on 13.10.13. - */ -public class LogWindow extends BaseActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.log_window); - getActionBar().setDisplayHomeAsUpEnabled(true); - - if (savedInstanceState == null) { - getFragmentManager().beginTransaction() - .add(R.id.container, new LogFragment()) - .commit(); - } - - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return super.onOptionsItemSelected(item); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/MainActivity.java b/main/src/main/java/de/blinkt/openvpn/activities/MainActivity.java deleted file mode 100644 index f7c46d01..00000000 --- a/main/src/main/java/de/blinkt/openvpn/activities/MainActivity.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.activities; - -import android.annotation.TargetApi; -import android.app.ActionBar; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Build; -import android.os.PowerManager; -import android.provider.Settings; -import android.support.v4n.view.ViewPager; -import android.view.Menu; -import android.view.MenuItem; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.fragments.AboutFragment; -import de.blinkt.openvpn.fragments.FaqFragment; -import de.blinkt.openvpn.fragments.GeneralSettings; -import de.blinkt.openvpn.fragments.GraphFragment; -import de.blinkt.openvpn.fragments.LogFragment; -import de.blinkt.openvpn.fragments.SendDumpFragment; -import de.blinkt.openvpn.fragments.VPNProfileList; -import de.blinkt.openvpn.views.ScreenSlidePagerAdapter; -import de.blinkt.openvpn.views.SlidingTabLayout; -import de.blinkt.openvpn.views.TabBarView; - - -public class MainActivity extends BaseActivity { - - private ViewPager mPager; - private ScreenSlidePagerAdapter mPagerAdapter; - private SlidingTabLayout mSlidingTabLayout; - private TabBarView mTabs; - - protected void onCreate(android.os.Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.main_activity); - - - // Instantiate a ViewPager and a PagerAdapter. - mPager = (ViewPager) findViewById(R.id.pager); - mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager(), this); - - /* Toolbar and slider should have the same elevation */ - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - disableToolbarElevation(); - } - - - mPagerAdapter.addTab(R.string.vpn_list_title, VPNProfileList.class); - mPagerAdapter.addTab(R.string.graph, GraphFragment.class); - - mPagerAdapter.addTab(R.string.generalsettings, GeneralSettings.class); - mPagerAdapter.addTab(R.string.faq, FaqFragment.class); - - if (SendDumpFragment.getLastestDump(this) != null) { - mPagerAdapter.addTab(R.string.crashdump, SendDumpFragment.class); - } - - - if (isDirectToTV()) - mPagerAdapter.addTab(R.string.openvpn_log, LogFragment.class); - - mPagerAdapter.addTab(R.string.about, AboutFragment.class); - mPager.setAdapter(mPagerAdapter); - - mTabs = (TabBarView) findViewById(R.id.sliding_tabs); - mTabs.setViewPager(mPager); - } - - private static final String FEATURE_TELEVISION = "android.hardware.type.television"; - private static final String FEATURE_LEANBACK = "android.software.leanback"; - - private boolean isDirectToTV() { - return(getPackageManager().hasSystemFeature(FEATURE_TELEVISION) - || getPackageManager().hasSystemFeature(FEATURE_LEANBACK)); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private void disableToolbarElevation() { - ActionBar toolbar = getActionBar(); - toolbar.setElevation(0); - } - - @Override - protected void onResume() { - super.onResume(); - if (getIntent()!=null) { - String page = getIntent().getStringExtra("PAGE"); - if ("graph".equals(page)) { - mPager.setCurrentItem(1); - } - setIntent(null); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.main_menu,menu); - return super.onCreateOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId()==R.id.show_log){ - Intent showLog = new Intent(this, LogWindow.class); - startActivity(showLog); - } - return super.onOptionsItemSelected(item); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - System.out.println(data); - - - } - - - -} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/OpenSSLSpeed.java b/main/src/main/java/de/blinkt/openvpn/activities/OpenSSLSpeed.java deleted file mode 100644 index 4720dd60..00000000 --- a/main/src/main/java/de/blinkt/openvpn/activities/OpenSSLSpeed.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2012-2017 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.activities; - -import android.content.Context; -import android.os.AsyncTask; -import android.os.Bundle; -import android.app.Activity; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.util.Pair; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.TextView; - -import java.util.Locale; -import java.util.Vector; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.core.NativeUtils; -import de.blinkt.openvpn.core.OpenVPNService; - -public class OpenSSLSpeed extends Activity { - - private static SpeeedTest runTestAlgorithms; - private EditText mCipher; - private SpeedArrayAdapter mAdapter; - private ListView mListView; - - - static class SpeedArrayAdapter extends ArrayAdapter { - - private final Context mContext; - private final LayoutInflater mInflater; - - public SpeedArrayAdapter(@NonNull Context context) { - super(context, 0); - mContext = context; - mInflater = LayoutInflater.from(context); - - } - - class ViewHolder { - TextView ciphername; - TextView blocksize; - TextView blocksInTime; - TextView speed; - } - - @NonNull - @Override - public View getView(int position, @Nullable View view, @NonNull ViewGroup parent) { - SpeedResult res = getItem(position); - if (view == null) { - view = mInflater.inflate(R.layout.speedviewitem, parent, false); - ViewHolder holder = new ViewHolder(); - holder.ciphername = view.findViewById(R.id.ciphername); - holder.speed = view.findViewById(R.id.speed); - holder.blocksize = view.findViewById(R.id.blocksize); - holder.blocksInTime = view.findViewById(R.id.blocksintime); - view.setTag(holder); - } - - ViewHolder holder = (ViewHolder) view.getTag(); - - double total = res.count * res.length; - String size = OpenVPNService.humanReadableByteCount((long) res.length, false, mContext.getResources()); - - holder.blocksize.setText(size); - holder.ciphername.setText(res.algorithm); - - if (res.failed) { - holder.blocksInTime.setText(R.string.openssl_error); - holder.speed.setText("-"); - } else if (res.running) { - holder.blocksInTime.setText(R.string.running_test); - holder.speed.setText("-"); - } else { - String totalBytes = OpenVPNService.humanReadableByteCount((long) total, false, mContext.getResources()); - // TODO: Fix localisation here - String blockPerSec = OpenVPNService.humanReadableByteCount((long) (total / res.time), false, mContext.getResources()) + "/s"; - holder.speed.setText(blockPerSec); - holder.blocksInTime.setText(String.format(Locale.ENGLISH, "%d blocks (%s) in %2.1fs", (long) res.count, totalBytes, res.time)); - } - - return view; - - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.openssl_speed); - getActionBar().setDisplayHomeAsUpEnabled(true); - - findViewById(R.id.testSpecific).setOnClickListener((view) -> { - runAlgorithms(mCipher.getText().toString()); - }); - mCipher = (EditText) findViewById(R.id.ciphername); - - mListView = findViewById(R.id.results); - - mAdapter = new SpeedArrayAdapter(this); - mListView.setAdapter(mAdapter); - - } - - private void runAlgorithms(String algorithms) { - if (runTestAlgorithms != null) - runTestAlgorithms.cancel(true); - runTestAlgorithms = new SpeeedTest(); - runTestAlgorithms.execute(algorithms.split(" ")); - } - - - static class SpeedResult { - String algorithm; - boolean failed = false; - - double count; - double time; - int length; - public boolean running=true; - - SpeedResult(String algorithm) { - this.algorithm = algorithm; - } - } - - - private class SpeeedTest extends AsyncTask { - - - private boolean mCancel = false; - - @Override - protected SpeedResult[] doInBackground(String... strings) { - Vector mResult = new Vector<>(); - - for (String algorithm : strings) { - - // Skip 16b and 16k as they are not relevevant for VPN - for (int i = 1; i < NativeUtils.openSSLlengths.length -1 && !mCancel; i++) { - SpeedResult result = new SpeedResult(algorithm); - result.length = NativeUtils.openSSLlengths[i]; - mResult.add(result); - publishProgress(result); - double[] resi = NativeUtils.getOpenSSLSpeed(algorithm, i); - if (resi == null) { - result.failed = true; - } else { - result.count = resi[1]; - result.time = resi[2]; - } - result.running = false; - publishProgress(result); - } - } - - return mResult.toArray(new SpeedResult[mResult.size()]); - - } - - @Override - protected void onProgressUpdate(SpeedResult... values) { - for (SpeedResult r : values) { - if (r.running) - mAdapter.add(r); - mAdapter.notifyDataSetChanged(); - } - } - - @Override - protected void onPostExecute(SpeedResult[] speedResult) { - - } - - @Override - protected void onCancelled(SpeedResult[] speedResults) { - mCancel = true; - } - } - - -} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java b/main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java deleted file mode 100644 index 65acdaa6..00000000 --- a/main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.activities; - -import android.annotation.TargetApi; -import android.app.ActionBar; -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.preference.PreferenceActivity; -import android.support.v4n.view.ViewPager; -import android.view.Menu; -import android.view.MenuItem; - -import android.widget.Toast; -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.ProfileManager; -import de.blinkt.openvpn.fragments.Settings_Allowed_Apps; -import de.blinkt.openvpn.fragments.Settings_Authentication; -import de.blinkt.openvpn.fragments.Settings_Basic; -import de.blinkt.openvpn.fragments.Settings_Connections; -import de.blinkt.openvpn.fragments.Settings_IP; -import de.blinkt.openvpn.fragments.Settings_Obscure; -import de.blinkt.openvpn.fragments.Settings_Routing; -import de.blinkt.openvpn.fragments.Settings_UserEditable; -import de.blinkt.openvpn.fragments.ShowConfigFragment; -import de.blinkt.openvpn.fragments.VPNProfileList; -import de.blinkt.openvpn.views.ScreenSlidePagerAdapter; -import de.blinkt.openvpn.views.TabBarView; - - -public class VPNPreferences extends BaseActivity { - - static final Class validFragments[] = new Class[] { - Settings_Authentication.class, Settings_Basic.class, Settings_IP.class, - Settings_Obscure.class, Settings_Routing.class, ShowConfigFragment.class, - Settings_Connections.class, Settings_Allowed_Apps.class - }; - - private String mProfileUUID; - private VpnProfile mProfile; - private ViewPager mPager; - private ScreenSlidePagerAdapter mPagerAdapter; - - public VPNPreferences() { - super(); - } - - - @TargetApi(Build.VERSION_CODES.KITKAT) - protected boolean isValidFragment(String fragmentName) { - for (Class c: validFragments) - if (c.getName().equals(fragmentName)) - return true; - return false; - - } - - @Override - protected void onStop() { - super.onStop(); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - outState.putString(getIntent().getStringExtra(getPackageName() + ".profileUUID"),mProfileUUID); - super.onSaveInstanceState(outState); - } - - @Override - protected void onResume() { - super.onResume(); - getProfile(); - // When a profile is deleted from a category fragment in hadset mod we need to finish - // this activity as well when returning - if (mProfile==null || mProfile.profileDeleted) { - setResult(VPNProfileList.RESULT_VPN_DELETED); - finish(); - } - if (mProfile.mTemporaryProfile) - { - Toast.makeText(this, "Temporary profiles cannot be edited", Toast.LENGTH_LONG); - finish(); - } - } - - private void getProfile() { - Intent intent = getIntent(); - - if(intent!=null) { - String profileUUID = intent.getStringExtra(getPackageName() + ".profileUUID"); - if(profileUUID==null) { - Bundle initialArguments = getIntent().getBundleExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS); - profileUUID = initialArguments.getString(getPackageName() + ".profileUUID"); - } - if(profileUUID!=null){ - - mProfileUUID = profileUUID; - mProfile = ProfileManager.get(this, mProfileUUID); - - } - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - mProfileUUID = getIntent().getStringExtra(getPackageName() + ".profileUUID"); - if(savedInstanceState!=null){ - String savedUUID = savedInstanceState.getString(getPackageName() + ".profileUUID"); - if(savedUUID!=null) - mProfileUUID=savedUUID; - } - - mProfile = ProfileManager.get(this,mProfileUUID); - if(mProfile!=null) { - setTitle(getString(R.string.edit_profile_title, mProfile.getName())); - } - super.onCreate(savedInstanceState); - - - setContentView(R.layout.main_activity); - - /* Toolbar and slider should have the same elevation */ - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - disableToolbarElevation(); - } - - // Instantiate a ViewPager and a PagerAdapter. - mPager = (ViewPager) findViewById(R.id.pager); - mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager(), this); - - - Bundle fragmentArguments = new Bundle(); - fragmentArguments.putString(getPackageName() + ".profileUUID",mProfileUUID); - mPagerAdapter.setFragmentArgs(fragmentArguments); - - if (mProfile.mUserEditable) { - mPagerAdapter.addTab(R.string.basic, Settings_Basic.class); - mPagerAdapter.addTab(R.string.server_list, Settings_Connections.class); - mPagerAdapter.addTab(R.string.ipdns, Settings_IP.class); - mPagerAdapter.addTab(R.string.routing, Settings_Routing.class); - mPagerAdapter.addTab(R.string.settings_auth, Settings_Authentication.class); - - mPagerAdapter.addTab(R.string.advanced, Settings_Obscure.class); - } else { - mPagerAdapter.addTab(R.string.basic, Settings_UserEditable.class); - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) - mPagerAdapter.addTab(R.string.vpn_allowed_apps, Settings_Allowed_Apps.class); - - mPagerAdapter.addTab(R.string.generated_config, ShowConfigFragment.class); - - - mPager.setAdapter(mPagerAdapter); - - TabBarView tabs = (TabBarView) findViewById(R.id.sliding_tabs); - tabs.setViewPager(mPager); - - } - - -/* - @Override - public void onBuildHeaders(List
target) { - loadHeadersFromResource(R.xml.vpn_headers, target); - Header headerToRemove=null; - for (Header header : target) { - if(header.fragmentArguments==null) - header.fragmentArguments = new Bundle(); - header.fragmentArguments.putString(getPackageName() + ".profileUUID",mProfileUUID); - if (header.id == R.id.allowed_apps_header && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) - headerToRemove = header; - } - if (headerToRemove != null) - target.remove(headerToRemove); - }*/ - - @Override - public void onBackPressed() { - setResult(RESULT_OK, getIntent()); - super.onBackPressed(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.remove_vpn) - askProfileRemoval(); - if (item.getItemId() == R.id.duplicate_vpn) { - Intent data = new Intent(); - data.putExtra(VpnProfile.EXTRA_PROFILEUUID, mProfileUUID); - setResult(VPNProfileList.RESULT_VPN_DUPLICATE, data); - finish(); - } - - return super.onOptionsItemSelected(item); - } - - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - - getMenuInflater().inflate(R.menu.vpnpreferences_menu, menu); - - return super.onCreateOptionsMenu(menu); - } - - private void askProfileRemoval() { - AlertDialog.Builder dialog = new AlertDialog.Builder(this); - dialog.setTitle("Confirm deletion"); - dialog.setMessage(getString(R.string.remove_vpn_query, mProfile.mName)); - - dialog.setPositiveButton(android.R.string.yes, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - removeProfile(mProfile); - } - - }); - dialog.setNegativeButton(android.R.string.no,null); - dialog.create().show(); - } - - protected void removeProfile(VpnProfile profile) { - ProfileManager.getInstance(this).removeProfile(this,profile); - setResult(VPNProfileList.RESULT_VPN_DELETED); - finish(); - - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private void disableToolbarElevation() { - ActionBar toolbar = getActionBar(); - toolbar.setElevation(0); - } - -} - diff --git a/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java index 181cca5f..6c5e3f10 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java +++ b/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java @@ -13,12 +13,6 @@ import android.content.Context; import android.graphics.Color; import android.os.Build; -/* -import org.acra.ACRA; -import org.acra.ReportingInteractionMode; -import org.acra.annotation.ReportsCrashes; -*/ - import android.os.StrictMode; import de.blinkt.openvpn.BuildConfig; import de.blinkt.openvpn.R; diff --git a/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java b/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java index 4e22189a..6be24995 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java +++ b/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java @@ -6,6 +6,7 @@ package de.blinkt.openvpn.core; import android.os.Build; +import de.blinkt.openvpn.BuildConfig; import java.security.InvalidKeyException; @@ -42,6 +43,9 @@ public class NativeUtils { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) System.loadLibrary("jbcrypto"); } + if (!BuildConfig.FLAVOR.equals("skeleton")) { + System.loadLibrary("osslspeedtest"); + } } public static boolean isRoboUnitTest() { diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/AboutFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/AboutFragment.java deleted file mode 100644 index 540f4a9a..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/AboutFragment.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.app.Fragment; -import android.app.PendingIntent; -import android.content.ComponentName; -import android.content.Intent; -import android.content.IntentSender; -import android.content.ServiceConnection; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.text.Html; -import android.text.SpannableString; -import android.text.Spanned; -import android.text.method.LinkMovementMethod; -import android.text.style.ClickableSpan; -import android.util.Log; -import android.util.Pair; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.android.vending.billing.IInAppBillingService; - -import de.blinkt.openvpn.core.NativeUtils; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.*; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Locale; -import java.util.Vector; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.core.VpnStatus; - -public class AboutFragment extends Fragment implements View.OnClickListener { - - public static final String INAPPITEM_TYPE_INAPP = "inapp"; - public static final String RESPONSE_CODE = "RESPONSE_CODE"; - private static final int DONATION_CODE = 12; - private static final int BILLING_RESPONSE_RESULT_OK = 0; - private static final String RESPONSE_BUY_INTENT = "BUY_INTENT"; - private static final String[] donationSkus = { "donation1eur", "donation2eur", "donation5eur", "donation10eur", - "donation1337eur","donation23eur","donation25eur",}; - IInAppBillingService mService; - Hashtable viewToProduct = new Hashtable<>(); - ServiceConnection mServiceConn = new ServiceConnection() { - @Override - public void onServiceDisconnected(ComponentName name) { - mService = null; - } - - @Override - public void onServiceConnected(ComponentName name, - IBinder service) { - mService = IInAppBillingService.Stub.asInterface(service); - initGooglePlayDonation(); - - } - }; - - private void initGooglePlayDonation() { - new Thread("queryGMSInApp") { - @Override - public void run() { - initGMSDonateOptions(); - } - }.start(); - } - - private TextView gmsTextView; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - /* - getActivity().bindService(new - Intent("com.android.vending.billing.InAppBillingService.BIND"), - mServiceConn, Context.BIND_AUTO_CREATE); - */ - } - - @Override - public void onDestroy() { - super.onDestroy(); - if (mService != null) { - getActivity().unbindService(mServiceConn); - } - - } - - private void initGMSDonateOptions() { - try { - int billingSupported = mService.isBillingSupported(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP); - if (billingSupported != BILLING_RESPONSE_RESULT_OK) { - Log.i("OpenVPN", "Play store billing not supported"); - return; - } - - ArrayList skuList = new ArrayList(); - Collections.addAll(skuList, donationSkus); - Bundle querySkus = new Bundle(); - querySkus.putStringArrayList("ITEM_ID_LIST", skuList); - - Bundle ownedItems = mService.getPurchases(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP, null); - - - if (ownedItems.getInt(RESPONSE_CODE) != BILLING_RESPONSE_RESULT_OK) - return; - - final ArrayList ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST"); - - Bundle skuDetails = mService.getSkuDetails(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP, querySkus); - - - if (skuDetails.getInt(RESPONSE_CODE) != BILLING_RESPONSE_RESULT_OK) - return; - - final ArrayList responseList = skuDetails.getStringArrayList("DETAILS_LIST"); - - if (getActivity() != null) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - createPlayBuyOptions(ownedSkus, responseList); - - } - }); - } - - } catch (RemoteException e) { - VpnStatus.logException(e); - } - } - - private static class SkuResponse { - String title; - String price; - - SkuResponse(String p, String t) - { - title=t; - price=p; - } - } - - - - private void createPlayBuyOptions(ArrayList ownedSkus, ArrayList responseList) { - try { - Vector> gdonation = new Vector>(); - - gdonation.add(new Pair(getString(R.string.donatePlayStore),null)); - HashMap responseMap = new HashMap(); - for (String thisResponse : responseList) { - JSONObject object = new JSONObject(thisResponse); - responseMap.put( - object.getString("productId"), - new SkuResponse( - object.getString("price"), - object.getString("title"))); - - } - for (String sku: donationSkus) - if (responseMap.containsKey(sku)) - gdonation.add(getSkuTitle(sku, - responseMap.get(sku).title, responseMap.get(sku).price, ownedSkus)); - - String gmsTextString=""; - for(int i=0;i1) - gmsTextString+= ", "; - gmsTextString+=gdonation.elementAt(i).first; - } - SpannableString gmsText = new SpannableString(gmsTextString); - - - int lStart = 0; - int lEnd=0; - for(Pair item:gdonation){ - lEnd = lStart + item.first.length(); - if (item.second!=null) { - final String mSku = item.second; - ClickableSpan cspan = new ClickableSpan() - { - @Override - public void onClick(View widget) { - triggerBuy(mSku); - } - }; - gmsText.setSpan(cspan,lStart,lEnd,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - lStart = lEnd+2; // Account for ", " between items - } - - if(gmsTextView !=null) { - gmsTextView.setText(gmsText); - gmsTextView.setMovementMethod(LinkMovementMethod.getInstance()); - gmsTextView.setVisibility(View.VISIBLE); - } - - } catch (JSONException e) { - VpnStatus.logException("Parsing Play Store IAP",e); - } - - } - - private Pair getSkuTitle(final String sku, String title, String price, ArrayList ownedSkus) { - String text; - if (ownedSkus.contains(sku)) - return new Pair(getString(R.string.thanks_for_donation, price),null); - - if (price.contains("€")|| price.contains("\u20ac")) { - text= title; - } else { - text = String.format(Locale.getDefault(), "%s (%s)", title, price); - } - //return text; - return new Pair(price, sku); - - } - - private void triggerBuy(String sku) { - try { - Bundle buyBundle - = mService.getBuyIntent(3, getActivity().getPackageName(), - sku, INAPPITEM_TYPE_INAPP, "Thanks for the donation! :)"); - - - if (buyBundle.getInt(RESPONSE_CODE) == BILLING_RESPONSE_RESULT_OK) { - PendingIntent buyIntent = buyBundle.getParcelable(RESPONSE_BUY_INTENT); - getActivity().startIntentSenderForResult(buyIntent.getIntentSender(), DONATION_CODE, new Intent(), - 0, 0, 0); - } - - } catch (RemoteException e) { - VpnStatus.logException(e); - } catch (IntentSender.SendIntentException e) { - VpnStatus.logException(e); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.about, container, false); - TextView ver = (TextView) v.findViewById(R.id.version); - - String version; - String name = "Openvpn"; - try { - PackageInfo packageinfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0); - version = packageinfo.versionName; - name = getString(R.string.app); - } catch (NameNotFoundException e) { - version = "error fetching version"; - } - - ver.setText(getString(R.string.version_info, name, version)); - - TextView verO2 = v.findViewById(R.id.version_ovpn2); - TextView verO3 = v.findViewById(R.id.version_ovpn3); - - verO2.setText(String.format(Locale.US, "OpenVPN version: %s", NativeUtils.getOpenVPN2GitVersion())); - verO3.setText(String.format(Locale.US, "OpenVPN3 core version: %s", NativeUtils.getOpenVPN3GitVersion())); - - gmsTextView = (TextView) v.findViewById(R.id.donategms); - /* recreating view without onCreate/onDestroy cycle */ - - // Disable GMS for now - if (mService!=null) - initGooglePlayDonation(); - - TextView translation = (TextView) v.findViewById(R.id.translation); - - // Don't print a text for myself - if (getString(R.string.translationby).contains("Arne Schwabe")) - translation.setText(""); - else - translation.setText(R.string.translationby); - - TextView wv = (TextView) v.findViewById(R.id.full_licenses); - wv.setText(Html.fromHtml(readHtmlFromAssets())); - return v; - } - - String readHtmlFromAssets() - { - InputStream mvpn; - - try { - mvpn = getActivity().getAssets().open("full_licenses.html"); - BufferedReader reader = new BufferedReader(new InputStreamReader(mvpn)); - StringBuilder sb = new StringBuilder(); - String line = null; - while ((line = reader.readLine()) != null) { - sb.append(line).append("\n"); - } - reader.close(); - return sb.toString(); - } catch (IOException errabi) { - return "full_licenses.html not found"; - } - } - - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - if (mService!=null) - initGooglePlayDonation(); - } - - - @Override - public void onClick(View v) { - - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/ConnectionsAdapter.java b/main/src/main/java/de/blinkt/openvpn/fragments/ConnectionsAdapter.java deleted file mode 100644 index 9c4c80de..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/ConnectionsAdapter.java +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.app.AlertDialog; -import android.content.Context; -import android.support.v7.widget.RecyclerView; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.*; - -import java.util.Arrays; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.Connection; - -public class ConnectionsAdapter extends RecyclerView.Adapter { - private static final int TYPE_NORMAL = 0; - private static final int TYPE_FOOTER = TYPE_NORMAL + 1; - private final Context mContext; - private final VpnProfile mProfile; - private final Settings_Connections mConnectionFragment; - private Connection[] mConnections; - - ConnectionsAdapter(Context c, Settings_Connections connections_fragments, VpnProfile vpnProfile) { - mContext = c; - mConnections = vpnProfile.mConnections; - mProfile = vpnProfile; - mConnectionFragment = connections_fragments; - } - - @Override - public ConnectionsAdapter.ConnectionsHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { - LayoutInflater li = LayoutInflater.from(mContext); - - View card; - if (viewType == TYPE_NORMAL) { - card = li.inflate(R.layout.server_card, viewGroup, false); - - } else { // TYPE_FOOTER - card = li.inflate(R.layout.server_footer, viewGroup, false); - } - return new ConnectionsHolder(card, this, viewType); - - } - - @Override - public void onBindViewHolder(final ConnectionsAdapter.ConnectionsHolder cH, int position) { - if (position == mConnections.length) { - // Footer - return; - } - final Connection connection = mConnections[position]; - - cH.mConnection = null; - - cH.mPortNumberView.setText(connection.mServerPort); - cH.mServerNameView.setText(connection.mServerName); - cH.mPortNumberView.setText(connection.mServerPort); - cH.mRemoteSwitch.setChecked(connection.mEnabled); - - - cH.mProxyNameView.setText(connection.mProxyName); - cH.mProxyPortNumberView.setText(connection.mProxyPort); - - cH.mConnectText.setText(String.valueOf(connection.getTimeout())); - - cH.mConnectSlider.setProgress(connection.getTimeout()); - - - cH.mProtoGroup.check(connection.mUseUdp ? R.id.udp_proto : R.id.tcp_proto); - - switch (connection.mProxyType) { - case NONE: - cH.mProxyGroup.check(R.id.proxy_none); - break; - case HTTP: - cH.mProxyGroup.check(R.id.proxy_http); - break; - case SOCKS5: - cH.mProxyGroup.check(R.id.proxy_http); - break; - case ORBOT: - cH.mProxyGroup.check(R.id.proxy_orbot); - break; - } - - cH.mProxyAuthCb.setChecked(connection.mUseProxyAuth); - cH.mProxyAuthUser.setText(connection.mProxyAuthUser); - cH.mProxyAuthPassword.setText(connection.mProxyAuthPassword); - - cH.mCustomOptionsLayout.setVisibility(connection.mUseCustomConfig ? View.VISIBLE : View.GONE); - cH.mCustomOptionText.setText(connection.mCustomConfiguration); - - cH.mCustomOptionCB.setChecked(connection.mUseCustomConfig); - cH.mConnection = connection; - - setVisibilityProxyServer(cH, connection); - - } - - private void setVisibilityProxyServer(ConnectionsHolder cH, Connection connection) { - int visible = (connection.mProxyType == Connection.ProxyType.HTTP || connection.mProxyType == Connection.ProxyType.SOCKS5) ? View.VISIBLE : View.GONE; - int authVisible = (connection.mProxyType == Connection.ProxyType.HTTP) ? View.VISIBLE : View.GONE; - - cH.mProxyNameView.setVisibility(visible); - cH.mProxyPortNumberView.setVisibility(visible); - cH.mProxyNameLabel.setVisibility(visible); - - cH.mProxyAuthLayout.setVisibility(authVisible); - - } - - private void removeRemote(int idx) { - Connection[] mConnections2 = Arrays.copyOf(mConnections, mConnections.length - 1); - for (int i = idx + 1; i < mConnections.length; i++) { - mConnections2[i - 1] = mConnections[i]; - } - mConnections = mConnections2; - - } - - @Override - public int getItemCount() { - return mConnections.length + 1; //for footer - } - - @Override - public int getItemViewType(int position) { - if (position == mConnections.length) - return TYPE_FOOTER; - else - return TYPE_NORMAL; - } - - void addRemote() { - mConnections = Arrays.copyOf(mConnections, mConnections.length + 1); - mConnections[mConnections.length - 1] = new Connection(); - notifyItemInserted(mConnections.length - 1); - displayWarningIfNoneEnabled(); - } - - void displayWarningIfNoneEnabled() { - int showWarning = View.VISIBLE; - for (Connection conn : mConnections) { - if (conn.mEnabled) - showWarning = View.GONE; - } - mConnectionFragment.setWarningVisible(showWarning); - } - - void saveProfile() { - mProfile.mConnections = mConnections; - } - - static abstract class OnTextChangedWatcher implements TextWatcher { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - - } - } - - class ConnectionsHolder extends RecyclerView.ViewHolder { - private final EditText mServerNameView; - private final EditText mPortNumberView; - private final Switch mRemoteSwitch; - private final RadioGroup mProtoGroup; - private final EditText mCustomOptionText; - private final CheckBox mCustomOptionCB; - private final View mCustomOptionsLayout; - private final ImageButton mDeleteButton; - private final EditText mConnectText; - private final SeekBar mConnectSlider; - private final ConnectionsAdapter mConnectionsAdapter; - private final RadioGroup mProxyGroup; - private final EditText mProxyNameView; - private final EditText mProxyPortNumberView; - private final View mProxyNameLabel; - private final View mProxyAuthLayout; - private final EditText mProxyAuthUser; - private final EditText mProxyAuthPassword; - private final CheckBox mProxyAuthCb; - - private Connection mConnection; // Set to null on update - - - ConnectionsHolder(View card, ConnectionsAdapter connectionsAdapter, int viewType) { - super(card); - mServerNameView = card.findViewById(R.id.servername); - mPortNumberView = card.findViewById(R.id.portnumber); - mRemoteSwitch = card.findViewById(R.id.remoteSwitch); - mCustomOptionCB = card.findViewById(R.id.use_customoptions); - mCustomOptionText = card.findViewById(R.id.customoptions); - mProtoGroup = card.findViewById(R.id.udptcpradiogroup); - mCustomOptionsLayout = card.findViewById(R.id.custom_options_layout); - mDeleteButton = card.findViewById(R.id.remove_connection); - mConnectSlider = card.findViewById(R.id.connect_silder); - mConnectText = card.findViewById(R.id.connect_timeout); - - mProxyGroup = card.findViewById(R.id.proxyradiogroup); - mProxyNameView = card.findViewById(R.id.proxyname); - mProxyPortNumberView = card.findViewById(R.id.proxyport); - mProxyNameLabel = card.findViewById(R.id.proxyserver_label); - - mProxyAuthLayout = card.findViewById(R.id.proxyauthlayout); - mProxyAuthCb = card.findViewById(R.id.enable_proxy_auth); - mProxyAuthUser = card.findViewById(R.id.proxyuser); - mProxyAuthPassword = card.findViewById(R.id.proxypassword); - - mConnectionsAdapter = connectionsAdapter; - - if (viewType == TYPE_NORMAL) - addListeners(); - } - - - void addListeners() { - mRemoteSwitch.setOnCheckedChangeListener((CompoundButton buttonView, boolean isChecked) -> { - if (mConnection != null) { - mConnection.mEnabled = isChecked; - mConnectionsAdapter.displayWarningIfNoneEnabled(); - } - }); - - mProtoGroup.setOnCheckedChangeListener((group, checkedId) -> { - if (mConnection != null) { - if (checkedId == R.id.udp_proto) - mConnection.mUseUdp = true; - else if (checkedId == R.id.tcp_proto) - mConnection.mUseUdp = false; - } - }); - - mProxyGroup.setOnCheckedChangeListener((group, checkedId) -> { - if (mConnection != null) { - switch (checkedId) { - case R.id.proxy_none: - mConnection.mProxyType = Connection.ProxyType.NONE; - break; - case R.id.proxy_http: - mConnection.mProxyType = Connection.ProxyType.HTTP; - break; - case R.id.proxy_socks: - mConnection.mProxyType = Connection.ProxyType.SOCKS5; - break; - case R.id.proxy_orbot: - mConnection.mProxyType = Connection.ProxyType.ORBOT; - break; - } - setVisibilityProxyServer(this, mConnection); - } - }); - - mProxyAuthCb.setOnCheckedChangeListener((group, isChecked) -> - { - if (mConnection != null) { - mConnection.mUseProxyAuth = isChecked; - setVisibilityProxyServer(this, mConnection); - } - }); - - mCustomOptionText.addTextChangedListener(new OnTextChangedWatcher() { - @Override - public void afterTextChanged(Editable s) { - if (mConnection != null) - mConnection.mCustomConfiguration = s.toString(); - } - }); - - mCustomOptionCB.setOnCheckedChangeListener((buttonView, isChecked) -> { - if (mConnection != null) { - mConnection.mUseCustomConfig = isChecked; - mCustomOptionsLayout.setVisibility(mConnection.mUseCustomConfig ? View.VISIBLE : View.GONE); - } - }); - - - mServerNameView.addTextChangedListener(new OnTextChangedWatcher() { - @Override - public void afterTextChanged(Editable s) { - if (mConnection != null) { - mConnection.mServerName = s.toString(); - } - } - - }); - - mPortNumberView.addTextChangedListener(new OnTextChangedWatcher() { - @Override - public void afterTextChanged(Editable s) { - if (mConnection != null) { - mConnection.mServerPort = s.toString(); - } - } - }); - - mProxyNameView.addTextChangedListener(new OnTextChangedWatcher() { - @Override - public void afterTextChanged(Editable s) { - if (mConnection != null) { - mConnection.mProxyName = s.toString(); - } - } - - }); - - mProxyPortNumberView.addTextChangedListener(new OnTextChangedWatcher() { - @Override - public void afterTextChanged(Editable s) { - if (mConnection != null) { - mConnection.mProxyPort = s.toString(); - } - } - }); - - mCustomOptionCB.setOnCheckedChangeListener((buttonView, isChecked) -> { - if (mConnection != null) { - mConnection.mUseProxyAuth = isChecked; - } - }); - - mProxyAuthPassword.addTextChangedListener(new OnTextChangedWatcher() { - @Override - public void afterTextChanged(Editable s) { - if (mConnection != null) { - mConnection.mProxyAuthPassword = s.toString(); - } - } - }); - - - mProxyAuthUser.addTextChangedListener(new OnTextChangedWatcher() { - @Override - public void afterTextChanged(Editable s) { - if (mConnection != null) { - mConnection.mProxyAuthUser = s.toString(); - } - } - }); - - - - mCustomOptionText.addTextChangedListener(new OnTextChangedWatcher() { - @Override - public void afterTextChanged(Editable s) { - if (mConnection != null) { - mConnection.mCustomConfiguration = s.toString(); - } - } - }); - - mConnectSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (fromUser && mConnection != null) { - mConnectText.setText(String.valueOf(progress)); - mConnection.mConnectTimeout = progress; - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - - } - }); - mConnectText.addTextChangedListener(new OnTextChangedWatcher() { - @Override - public void afterTextChanged(Editable s) { - if (mConnection != null) { - try { - int t = Integer.valueOf(String.valueOf(s)); - mConnectSlider.setProgress(t); - mConnection.mConnectTimeout = t; - } catch (Exception ignored) { - } - } - } - }); - - mDeleteButton.setOnClickListener( - v -> { - AlertDialog.Builder ab = new AlertDialog.Builder(mContext); - ab.setTitle(R.string.query_delete_remote); - ab.setPositiveButton(R.string.keep, null); - ab.setNegativeButton(R.string.delete, (dialog, which) -> { - removeRemote(getAdapterPosition()); - notifyItemRemoved(getAdapterPosition()); - }); - ab.create().show(); - } - ); - - - } - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java deleted file mode 100644 index 58937caf..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.app.Fragment; -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.StaggeredGridLayoutManager; -import android.util.DisplayMetrics; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import java.util.Vector; - -import de.blinkt.openvpn.R; - -public class FaqFragment extends Fragment { - static class FAQEntry { - - public FAQEntry(int startVersion, int endVersion, int title, int description) { - this.startVersion = startVersion; - this.endVersion = endVersion; - this.description = description; - this.title = title; - } - - final int startVersion; - final int endVersion; - final int description; - final int title; - - public boolean runningVersion() { - if (Build.VERSION.SDK_INT >= startVersion) { - if (Build.VERSION.SDK_INT <= endVersion) - return true; - - if (endVersion == -1) - return true; - - String release = Build.VERSION.RELEASE; - boolean isOlderThan443 = !release.startsWith("4.4.3") && !release.startsWith("4.4.4") && - !release.startsWith("4.4.5") && !release.startsWith("4.4.6"); - - boolean isOlderThan442 = isOlderThan443 && !release.startsWith("4.4.2"); - - - if(Build.VERSION.SDK_INT== Build.VERSION_CODES.KITKAT) { - if (endVersion == -441 && isOlderThan442) - return true; - - if (endVersion == -442 && isOlderThan443) - return true; - } else if (endVersion == -441 || endVersion == -442) { - return Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT; - } - - - } - return false; - } - - public String getVersionsString(Context c) { - if (startVersion == Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - if (endVersion == -1) - return null; - else - return c.getString(R.string.version_upto, getAndroidVersionString(c, endVersion)); - } - - if (endVersion == -1) - return c.getString(R.string.version_and_later, getAndroidVersionString(c, startVersion)); - - - String startver = getAndroidVersionString(c, startVersion); - - if (endVersion == startVersion) - return startver; - - return String.format("%s - %s", startver, getAndroidVersionString(c, endVersion)); - } - - - private String getAndroidVersionString(Context c, int versionCode) { - switch (versionCode) { - case Build.VERSION_CODES.ICE_CREAM_SANDWICH: - return "4.0 (Ice Cream Sandwich)"; - case -441: - return "4.4.1 (KitKat)"; - case -442: - return "4.4.2 (KitKat)"; - case Build.VERSION_CODES.JELLY_BEAN_MR2: - return "4.3 (Jelly Bean MR2)"; - case Build.VERSION_CODES.KITKAT: - return "4.4 (KitKat)"; - case Build.VERSION_CODES.LOLLIPOP: - return "5.0 (Lollipop)"; - default: - return "API " + versionCode; - } - } - - - } - - private static FAQEntry[] faqitemsVersionSpecific = { - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.faq_howto_title, R.string.faq_howto), - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.faq_killswitch_title, R.string.faq_killswitch), - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.faq_remote_api_title, R.string.faq_remote_api), - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.weakmd_title, R.string.weakmd), - new FAQEntry(Build.VERSION_CODES.LOLLIPOP, -1, R.string.samsung_broken_title, R.string.samsung_broken), - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.faq_duplicate_notification_title, R.string.faq_duplicate_notification), - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.faq_androids_clients_title, R.string.faq_android_clients), - - - new FAQEntry(Build.VERSION_CODES.LOLLIPOP, Build.VERSION_CODES.LOLLIPOP_MR1, R.string.ab_lollipop_reinstall_title, R.string.ab_lollipop_reinstall), - - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, Build.VERSION_CODES.JELLY_BEAN_MR2, R.string.vpn_tethering_title, R.string.faq_tethering), - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, Build.VERSION_CODES.JELLY_BEAN_MR2, R.string.broken_images, R.string.broken_images_faq), - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.battery_consumption_title, R.string.baterry_consumption), - - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, Build.VERSION_CODES.KITKAT, R.string.faq_system_dialogs_title, R.string.faq_system_dialogs), - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.tap_mode, R.string.faq_tap_mode), - - new FAQEntry(Build.VERSION_CODES.JELLY_BEAN_MR2, Build.VERSION_CODES.JELLY_BEAN_MR2, R.string.ab_secondary_users_title, R.string.ab_secondary_users), - new FAQEntry(Build.VERSION_CODES.JELLY_BEAN_MR2, -1, R.string.faq_vpndialog43_title, R.string.faq_vpndialog43), - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.tls_cipher_alert_title, R.string.tls_cipher_alert), - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.faq_security_title, R.string.faq_security), - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.faq_shortcut, R.string.faq_howto_shortcut), - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.tap_mode, R.string.tap_faq2), - - new FAQEntry(Build.VERSION_CODES.KITKAT, -1, R.string.vpn_tethering_title, R.string.ab_tethering_44), - new FAQEntry(Build.VERSION_CODES.KITKAT, -441, R.string.ab_kitkat_mss_title, R.string.ab_kitkat_mss), - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.copying_log_entries, R.string.faq_copying), - - new FAQEntry(Build.VERSION_CODES.KITKAT, -442, R.string.ab_persist_tun_title, R.string.ab_persist_tun), - new FAQEntry(Build.VERSION_CODES.KITKAT, -1, R.string.faq_routing_title, R.string.faq_routing), - new FAQEntry(Build.VERSION_CODES.KITKAT, Build.VERSION_CODES.KITKAT, R.string.ab_kitkat_reconnect_title, R.string.ab_kitkat_reconnect), - new FAQEntry(Build.VERSION_CODES.KITKAT, Build.VERSION_CODES.KITKAT, R.string.ab_vpn_reachability_44_title, R.string.ab_vpn_reachability_44), - - - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.ab_only_cidr_title, R.string.ab_only_cidr), - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.ab_proxy_title, R.string.ab_proxy), - - new FAQEntry(Build.VERSION_CODES.LOLLIPOP, -1, R.string.ab_not_route_to_vpn_title, R.string.ab_not_route_to_vpn), - new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.tap_mode, R.string.tap_faq3), - - // DNS weirdness in Samsung 5.0: https://plus.google.com/117315704597472009168/posts/g78bZLWmqgD - }; - - - private RecyclerView mRecyclerView; - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.faq, container, false); - - DisplayMetrics displaymetrics = new DisplayMetrics(); - getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); - int dpWidth = (int) (displaymetrics.widthPixels / getResources().getDisplayMetrics().density); - - //better way but does not work on 5.0 - //int dpWidth = (int) (container.getWidth()/getResources().getDisplayMetrics().density); - int columns = dpWidth / 360; - columns = Math.max(1, columns); - - - mRecyclerView = (RecyclerView) v.findViewById(R.id.faq_recycler_view); - - // use this setting to improve performance if you know that changes - // in content do not change the layout size of the RecyclerView - mRecyclerView.setHasFixedSize(true); - - - mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(columns, StaggeredGridLayoutManager.VERTICAL)); - - mRecyclerView.setAdapter(new FaqViewAdapter(getActivity(), getFAQEntries())); - - return v; - } - - private FAQEntry[] getFAQEntries() { - Vector faqItems = new Vector<>(); - - for (FAQEntry fe : faqitemsVersionSpecific) { - if (fe.runningVersion()) - faqItems.add(fe); - } - for (FAQEntry fe : faqitemsVersionSpecific) { - if (!fe.runningVersion()) - faqItems.add(fe); - } - - return faqItems.toArray(new FAQEntry[faqItems.size()]); - } - -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/FaqViewAdapter.java b/main/src/main/java/de/blinkt/openvpn/fragments/FaqViewAdapter.java deleted file mode 100644 index 0be9f4a2..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/FaqViewAdapter.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.content.Context; -import android.os.AsyncTask; -import android.support.v7.widget.CardView; -import android.support.v7.widget.RecyclerView; -import android.text.Html; -import android.text.Spanned; -import android.text.TextUtils; -import android.text.method.LinkMovementMethod; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import de.blinkt.openvpn.R; - -public class FaqViewAdapter extends RecyclerView.Adapter { - private final FaqFragment.FAQEntry[] mFaqItems; - private final Spanned[] mHtmlEntries; - private final Spanned[] mHtmlEntriesTitle; - private final Context mContext; - private boolean loaded =false; - - public FaqViewAdapter(Context context, FaqFragment.FAQEntry[] faqItems) { - mFaqItems = faqItems; - mContext = context; - - mHtmlEntries = new Spanned[faqItems.length]; - mHtmlEntriesTitle = new Spanned[faqItems.length]; - - new FetchStrings().execute(faqItems); - - } - - private class FetchStrings extends AsyncTask { - - @Override - protected void onPostExecute(Void aVoid) { - loaded=true; - notifyDataSetChanged(); - } - - @Override - protected Void doInBackground(FaqFragment.FAQEntry... params) { - fetchStrings(params); - return null; - } - } - - private void fetchStrings(FaqFragment.FAQEntry[] faqItems) { - for (int i =0; i < faqItems.length; i++) { - String versionText = mFaqItems[i].getVersionsString(mContext); - String title; - String textColor=""; - - if (mFaqItems[i].title==-1) - title =""; - else - title = mContext.getString(faqItems[i].title); - - - if (!mFaqItems[i].runningVersion()) - textColor= ""; - - if (versionText != null) { - - mHtmlEntriesTitle[i] = (Spanned) TextUtils.concat(Html.fromHtml(textColor + title), - Html.fromHtml(textColor + "
" + versionText + "")); - } else { - mHtmlEntriesTitle[i] = Html.fromHtml(title); - } - - String content = mContext.getString(faqItems[i].description); - mHtmlEntries[i] = Html.fromHtml(textColor + content); - - // Add hack R.string.faq_system_dialogs_title -> R.string.faq_system_dialog_xposed - if (faqItems[i].title == R.string.faq_system_dialogs_title) - { - Spanned xPosedtext = Html.fromHtml(textColor + mContext.getString(R.string.faq_system_dialog_xposed)); - mHtmlEntries[i] = (Spanned) TextUtils.concat(mHtmlEntries[i], xPosedtext); - } - } - } - - public static class FaqViewHolder extends RecyclerView.ViewHolder { - - private final CardView mView; - private final TextView mBody; - private final TextView mHead; - - public FaqViewHolder(View itemView) { - super(itemView); - - mView = (CardView) itemView; - mBody = (TextView)mView.findViewById(R.id.faq_body); - mHead = (TextView)mView.findViewById(R.id.faq_head); - mBody.setMovementMethod(LinkMovementMethod.getInstance()); - } - } - - @Override - public FaqViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { - View view = LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.faqcard, viewGroup, false); - return new FaqViewHolder(view); - } - - @Override - public void onBindViewHolder(FaqViewHolder faqViewHolder, int i) { - - faqViewHolder.mHead.setText(mHtmlEntriesTitle[i]); - faqViewHolder.mBody.setText(mHtmlEntries[i]); - - - } - - @Override - public int getItemCount() { - if(loaded) - return mFaqItems.length; - else - return 0; - } - - -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/FileSelectionFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/FileSelectionFragment.java deleted file mode 100644 index 9d12b83d..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/FileSelectionFragment.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.app.ListFragment; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.ListView; -import android.widget.SimpleAdapter; -import android.widget.TextView; -import android.widget.Toast; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.TreeMap; -import java.util.Vector; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.activities.FileSelect; - -public class FileSelectionFragment extends ListFragment { - - private static final String ITEM_KEY = "key"; - private static final String ITEM_IMAGE = "image"; - private static final String ROOT = "/"; - - - private List path = null; - private TextView myPath; - private ArrayList> mList; - - private Button selectButton; - - - private String parentPath; - private String currentPath = Environment.getExternalStorageDirectory().getAbsolutePath(); - - - private String[] formatFilter = null; - - private File selectedFile; - private HashMap lastPositions = new HashMap<>(); - private String mStartPath; - private CheckBox mInlineImport; - private Button mClearButton; - private boolean mHideImport = false; - - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { - onListItemClick(getListView(), view, position, id); - onFileSelectionClick(); - return true; - } - } - - ); - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.file_dialog_main, container, false); - - myPath = (TextView) v.findViewById(R.id.path); - - mInlineImport = (CheckBox) v.findViewById(R.id.doinline); - - if (mHideImport) { - mInlineImport.setVisibility(View.GONE); - mInlineImport.setChecked(false); - } - - - selectButton = (Button) v.findViewById(R.id.fdButtonSelect); - selectButton.setEnabled(false); - selectButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - onFileSelectionClick(); - } - }); - - mClearButton = (Button) v.findViewById(R.id.fdClear); - mClearButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - ((FileSelect) getActivity()).clearData(); - } - }); - if (!((FileSelect) getActivity()).showClear()) { - mClearButton.setVisibility(View.GONE); - mClearButton.setEnabled(false); - } - - return v; - } - - private void onFileSelectionClick() { - if (selectedFile != null) { - if (mInlineImport.isChecked()) - - ((FileSelect) getActivity()).importFile(selectedFile.getPath()); - else - ((FileSelect) getActivity()).setFile(selectedFile.getPath()); - } - } - - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - mStartPath = ((FileSelect) getActivity()).getSelectPath(); - getDir(mStartPath); - } - - public void refresh() { - getDir(Environment.getExternalStorageDirectory().getAbsolutePath()); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - - private void getDir(String dirPath) { - - boolean useAutoSelection = dirPath.length() < currentPath.length(); - - Integer position = lastPositions.get(parentPath); - - getDirImpl(dirPath); - - if (position != null && useAutoSelection) { - getListView().setSelection(position); - } - - } - - private void getDirImpl(final String dirPath) { - - currentPath = dirPath; - - final List item = new ArrayList(); - path = new ArrayList(); - mList = new ArrayList>(); - - File f = new File(currentPath); - File[] files = f.listFiles(); - if (files == null) { - currentPath = ROOT; - f = new File(currentPath); - files = f.listFiles(); - - if (files == null) - files = new File[]{}; - } - - myPath.setText(getText(R.string.location) + ": " + currentPath); - - if (!currentPath.equals(ROOT)) { - - item.add(ROOT); - addItem(ROOT, R.drawable.ic_root_folder_am); - path.add(ROOT); - - item.add("../"); - addItem("../", R.drawable.ic_root_folder_am); - path.add(f.getParent()); - parentPath = f.getParent(); - - } - - - TreeMap dirsMap = new TreeMap<>(); - TreeMap dirsPathMap = new TreeMap<>(); - TreeMap filesMap = new TreeMap<>(); - TreeMap filesPathMap = new TreeMap<>(); - - // add default locations - for (String dir: getExternalStorages()) { - // You got to love the P8 Lite to have null in this list .... - if (dir!=null) { - dirsMap.put(dir, dir); - dirsPathMap.put(dir, dir); - } - } - - for (File file : files) { - if (file.isDirectory()) { - String dirName = file.getName(); - dirsMap.put(dirName, dirName); - dirsPathMap.put(dirName, file.getPath()); - } else { - final String fileName = file.getName(); - final String fileNameLwr = fileName.toLowerCase(Locale.getDefault()); - - if (formatFilter != null) { - boolean contains = false; - for (String aFormatFilter : formatFilter) { - final String formatLwr = aFormatFilter.toLowerCase(Locale.getDefault()); - if (fileNameLwr.endsWith(formatLwr)) { - contains = true; - break; - } - } - if (contains) { - filesMap.put(fileName, fileName); - filesPathMap.put(fileName, file.getPath()); - } - } else { - filesMap.put(fileName, fileName); - filesPathMap.put(fileName, file.getPath()); - } - } - } - item.addAll(dirsMap.tailMap("").values()); - item.addAll(filesMap.tailMap("").values()); - path.addAll(dirsPathMap.tailMap("").values()); - path.addAll(filesPathMap.tailMap("").values()); - - SimpleAdapter fileList = new SimpleAdapter(getActivity(), mList, R.layout.file_dialog_row, new String[]{ - ITEM_KEY, ITEM_IMAGE}, new int[]{R.id.fdrowtext, R.id.fdrowimage}); - - for (String dir : dirsMap.tailMap("").values()) { - addItem(dir, R.drawable.ic_root_folder_am); - } - - for (String file : filesMap.tailMap("").values()) { - addItem(file, R.drawable.ic_doc_generic_am); - } - - fileList.notifyDataSetChanged(); - - setListAdapter(fileList); - - } - - private void addItem(String fileName, int imageId) { - HashMap item = new HashMap(); - item.put(ITEM_KEY, fileName); - item.put(ITEM_IMAGE, imageId); - mList.add(item); - } - - private Collection getExternalStorages() { - Vector dirs = new Vector<>(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - for (File d : getActivity().getExternalFilesDirs(null)) - dirs.add(getRootOfInnerSdCardFolder(d)); - } else { - dirs.add(Environment.getExternalStorageDirectory().getAbsolutePath()); - } - return dirs; - } - - private static String getRootOfInnerSdCardFolder(File file) { - if (file == null) - return null; - final long totalSpace = file.getTotalSpace(); - while (true) { - final File parentFile = file.getParentFile(); - if (parentFile == null || parentFile.getTotalSpace() != totalSpace - || file.equals(Environment.getExternalStorageDirectory())) - return file.getAbsolutePath(); - file = parentFile; - } - } - - - - @Override - public void onListItemClick(ListView l, View v, int position, long id) { - - File file = new File(path.get(position)); - - if (file.isDirectory()) { - selectButton.setEnabled(false); - - if (file.canRead()) { - lastPositions.put(currentPath, position); - getDir(path.get(position)); - } else { - Toast.makeText(getActivity(), - "[" + file.getName() + "] " + getActivity().getText(R.string.cant_read_folder), - Toast.LENGTH_SHORT).show(); - } - } else { - selectedFile = file; - v.setSelected(true); - selectButton.setEnabled(true); - } - } - - public void setNoInLine() { - mHideImport = true; - - } - -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java b/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java deleted file mode 100644 index 88c46e6e..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; -import java.io.File; -import java.util.Collection; - -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; -import android.app.Dialog; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Build; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceClickListener; -import android.preference.PreferenceCategory; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; - -import de.blinkt.openvpn.BuildConfig; -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.activities.OpenSSLSpeed; -import de.blinkt.openvpn.api.ExternalAppDatabase; -import de.blinkt.openvpn.core.ProfileManager; - - -public class GeneralSettings extends PreferenceFragment implements OnPreferenceClickListener, OnClickListener, Preference.OnPreferenceChangeListener { - - private ExternalAppDatabase mExtapp; - private ListPreference mAlwaysOnVPN; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.general_settings); - - - PreferenceCategory devHacks = (PreferenceCategory) findPreference("device_hacks"); - mAlwaysOnVPN = (ListPreference) findPreference("alwaysOnVpn"); - mAlwaysOnVPN.setOnPreferenceChangeListener(this); - - - Preference loadtun = findPreference("loadTunModule"); - if(!isTunModuleAvailable()) { - loadtun.setEnabled(false); - devHacks.removePreference(loadtun); - } - - CheckBoxPreference cm9hack = (CheckBoxPreference) findPreference("useCM9Fix"); - if (!cm9hack.isChecked() && (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1)) { - devHacks.removePreference(cm9hack); - } - - CheckBoxPreference useInternalFS = (CheckBoxPreference) findPreference("useInternalFileSelector"); - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) - { - devHacks.removePreference(useInternalFS); - } - - /* Android P does not allow access to the file storage anymore */ - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) - { - Preference useInternalFileSelector = findPreference("useInternalFileSelector"); - devHacks.removePreference(useInternalFileSelector); - } - - mExtapp = new ExternalAppDatabase(getActivity()); - Preference clearapi = findPreference("clearapi"); - clearapi.setOnPreferenceClickListener(this); - - findPreference("osslspeed").setOnPreferenceClickListener(this); - - if(devHacks.getPreferenceCount()==0) - getPreferenceScreen().removePreference(devHacks); - - if (!BuildConfig.openvpn3) { - PreferenceCategory appBehaviour = (PreferenceCategory) findPreference("app_behaviour"); - CheckBoxPreference ovpn3 = (CheckBoxPreference) findPreference("ovpn3"); - ovpn3.setEnabled(false); - ovpn3.setChecked(false); - } - - - setClearApiSummary(); - } - - @Override - public void onResume() { - super.onResume(); - - - - - VpnProfile vpn = ProfileManager.getAlwaysOnVPN(getActivity()); - StringBuffer sb = new StringBuffer(getString(R.string.defaultvpnsummary)); - sb.append('\n'); - if (vpn== null) - sb.append(getString(R.string.novpn_selected)); - else - sb.append(getString(R.string.vpnselected, vpn.getName())); - mAlwaysOnVPN.setSummary(sb.toString()); - - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (preference== mAlwaysOnVPN) { - VpnProfile vpn = ProfileManager.get(getActivity(), (String) newValue); - mAlwaysOnVPN.setSummary(vpn.getName()); - } - return true; - } - - private void setClearApiSummary() { - Preference clearapi = findPreference("clearapi"); - - if(mExtapp.getExtAppList().isEmpty()) { - clearapi.setEnabled(false); - clearapi.setSummary(R.string.no_external_app_allowed); - } else { - clearapi.setEnabled(true); - clearapi.setSummary(getString(R.string.allowed_apps, getExtAppList(", "))); - } - } - - private String getExtAppList(String delim) { - ApplicationInfo app; - PackageManager pm = getActivity().getPackageManager(); - - StringBuilder applist = new StringBuilder(); - for (String packagename : mExtapp.getExtAppList()) { - try { - app = pm.getApplicationInfo(packagename, 0); - if (applist.length() != 0) - applist.append(delim); - applist.append(app.loadLabel(pm)); - - } catch (NameNotFoundException e) { - // App not found. Remove it from the list - mExtapp.removeApp(packagename); - } - } - - return applist.toString(); - } - - private boolean isTunModuleAvailable() { - // Check if the tun module exists on the file system - return new File("/system/lib/modules/tun.ko").length() > 10; - } - - @Override - public boolean onPreferenceClick(Preference preference) { - if(preference.getKey().equals("clearapi")){ - Builder builder = new AlertDialog.Builder(getActivity()); - builder.setPositiveButton(R.string.clear, this); - builder.setNegativeButton(android.R.string.cancel, null); - builder.setMessage(getString(R.string.clearappsdialog,getExtAppList("\n"))); - builder.show(); - } else if (preference.getKey().equals("osslspeed")) { - startActivity(new Intent(getActivity(), OpenSSLSpeed.class)); - } - - return true; - } - - @Override - public void onClick(DialogInterface dialog, int which) { - if( which == Dialog.BUTTON_POSITIVE){ - mExtapp.clearAllApiApps(); - setClearApiSummary(); - } - } - - - -} \ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/GraphFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/GraphFragment.java deleted file mode 100644 index 10c09461..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/GraphFragment.java +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2012-2017 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.app.Fragment; -import android.content.Context; -import android.content.res.Resources; -import android.os.Bundle; -import android.os.Handler; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.ListView; -import android.widget.TextView; - -import com.github.mikephil.charting.charts.LineChart; -import com.github.mikephil.charting.components.AxisBase; -import com.github.mikephil.charting.components.XAxis; -import com.github.mikephil.charting.components.YAxis; -import com.github.mikephil.charting.data.Entry; -import com.github.mikephil.charting.data.LineData; -import com.github.mikephil.charting.data.LineDataSet; -import com.github.mikephil.charting.formatter.IAxisValueFormatter; -import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.core.OpenVPNManagement; -import de.blinkt.openvpn.core.TrafficHistory; -import de.blinkt.openvpn.core.VpnStatus; - -import static android.content.Context.MODE_PRIVATE; -import static de.blinkt.openvpn.core.OpenVPNService.humanReadableByteCount; -import static java.lang.Math.max; - -/** - * Created by arne on 19.05.17. - */ - -public class GraphFragment extends Fragment implements VpnStatus.ByteCountListener { - private static final String PREF_USE_LOG = "useLogGraph"; - private ListView mListView; - - private ChartDataAdapter mChartAdapter; - private int mColourIn; - private int mColourOut; - private int mColourPoint; - - private long firstTs; - private TextView mSpeedStatus; - private boolean mLogScale; - - private static final int TIME_PERIOD_SECDONS = 0; - private static final int TIME_PERIOD_MINUTES = 1; - private static final int TIME_PERIOD_HOURS = 2; - private Handler mHandler; - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.graph, container, false); - mListView = (ListView) v.findViewById(R.id.graph_listview); - mSpeedStatus = (TextView) v.findViewById(R.id.speedStatus); - CheckBox logScaleView = (CheckBox) v.findViewById(R.id.useLogScale); - mLogScale = getActivity().getPreferences(MODE_PRIVATE).getBoolean(PREF_USE_LOG, false); - logScaleView.setChecked(mLogScale); - - List charts = new LinkedList<>(); - charts.add(TIME_PERIOD_SECDONS); - charts.add(TIME_PERIOD_MINUTES); - charts.add(TIME_PERIOD_HOURS); - - mChartAdapter = new ChartDataAdapter(getActivity(), charts); - mListView.setAdapter(mChartAdapter); - - mColourIn = getActivity().getResources().getColor(R.color.dataIn); - mColourOut = getActivity().getResources().getColor(R.color.dataOut); - mColourPoint = getActivity().getResources().getColor(android.R.color.black); - - logScaleView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mLogScale = isChecked; - mChartAdapter.notifyDataSetChanged(); - getActivity().getPreferences(MODE_PRIVATE).edit().putBoolean(PREF_USE_LOG, isChecked).apply(); - } - }); - - mHandler = new Handler(); - - return v; - - - } - - private Runnable triggerRefresh = new Runnable() { - @Override - public void run() { - mChartAdapter.notifyDataSetChanged(); - mHandler.postDelayed(triggerRefresh, OpenVPNManagement.mBytecountInterval * 1500); - } - }; - - @Override - public void onResume() { - super.onResume(); - - VpnStatus.addByteCountListener(this); - mHandler.postDelayed(triggerRefresh, OpenVPNManagement.mBytecountInterval * 1500); - } - - @Override - public void onPause() { - super.onPause(); - - mHandler.removeCallbacks(triggerRefresh); - VpnStatus.removeByteCountListener(this); - } - - @Override - public void updateByteCount(long in, long out, long diffIn, long diffOut) { - if (firstTs == 0) - firstTs = System.currentTimeMillis() / 100; - - long now = (System.currentTimeMillis() / 100) - firstTs; - int interval = OpenVPNManagement.mBytecountInterval * 10; - Resources res = getActivity().getResources(); - - final String netstat = String.format(getString(R.string.statusline_bytecount), - humanReadableByteCount(in, false, res), - humanReadableByteCount(diffIn / OpenVPNManagement.mBytecountInterval, true, res), - humanReadableByteCount(out, false, res), - humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true, res)); - - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - mHandler.removeCallbacks(triggerRefresh); - mSpeedStatus.setText(netstat); - mChartAdapter.notifyDataSetChanged(); - mHandler.postDelayed(triggerRefresh, OpenVPNManagement.mBytecountInterval * 1500); - } - }); - - } - - private class ChartDataAdapter extends ArrayAdapter { - - private Context mContext; - - public ChartDataAdapter(Context context, List trafficData) { - super(context, 0, trafficData); - mContext = context; - } - - @NonNull - @Override - public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) { - ViewHolder holder = null; - - if (convertView == null) { - - holder = new ViewHolder(); - - convertView = LayoutInflater.from(mContext).inflate( - R.layout.graph_item, parent, false); - holder.chart = (LineChart) convertView.findViewById(R.id.chart); - holder.title = (TextView) convertView.findViewById(R.id.tvName); - convertView.setTag(holder); - - } else { - holder = (ViewHolder) convertView.getTag(); - } - - // apply styling - // holder.chart.setValueTypeface(mTf); - holder.chart.getDescription().setEnabled(false); - holder.chart.setDrawGridBackground(false); - - XAxis xAxis = holder.chart.getXAxis(); - xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); - xAxis.setDrawGridLines(false); - xAxis.setDrawAxisLine(true); - - switch (position) { - case TIME_PERIOD_HOURS: - holder.title.setText(R.string.avghour); - break; - case TIME_PERIOD_MINUTES: - holder.title.setText(R.string.avgmin); - break; - default: - holder.title.setText(R.string.last5minutes); - break; - } - - xAxis.setValueFormatter(new IAxisValueFormatter() { - - - @Override - public String getFormattedValue(float value, AxisBase axis) { - switch (position) { - case TIME_PERIOD_HOURS: - return String.format(Locale.getDefault(), "%.0f\u2009h ago", (axis.getAxisMaximum() - value) / 10 / 3600); - case TIME_PERIOD_MINUTES: - return String.format(Locale.getDefault(), "%.0f\u2009m ago", (axis.getAxisMaximum() - value) / 10 / 60); - default: - return String.format(Locale.getDefault(), "%.0f\u2009s ago", (axis.getAxisMaximum() - value) / 10); - } - - } - }); - xAxis.setLabelCount(5); - - YAxis yAxis = holder.chart.getAxisLeft(); - yAxis.setLabelCount(5, false); - - final Resources res = getActivity().getResources(); - yAxis.setValueFormatter(new IAxisValueFormatter() { - @Override - public String getFormattedValue(float value, AxisBase axis) { - if (mLogScale && value < 2.1f) - return "< 100\u2009bit/s"; - if (mLogScale) - value = (float) Math.pow(10, value) / 8; - - return humanReadableByteCount((long) value, true, res); - } - }); - - holder.chart.getAxisRight().setEnabled(false); - - LineData data = getDataSet(position); - float ymax = data.getYMax(); - - if (mLogScale) { - yAxis.setAxisMinimum(2f); - yAxis.setAxisMaximum((float) Math.ceil(ymax)); - yAxis.setLabelCount((int) (Math.ceil(ymax - 2f))); - } else { - yAxis.setAxisMinimum(0f); - yAxis.resetAxisMaximum(); - yAxis.setLabelCount(6); - } - - if (data.getDataSetByIndex(0).getEntryCount() < 3) - holder.chart.setData(null); - else - holder.chart.setData(data); - - holder.chart.setNoDataText(getString(R.string.notenoughdata)); - - holder.chart.invalidate(); - //holder.chart.animateX(750); - - return convertView; - } - - private LineData getDataSet(int timeperiod) { - - LinkedList dataIn = new LinkedList<>(); - LinkedList dataOut = new LinkedList<>(); - - long interval; - long totalInterval; - - LinkedList list; - switch (timeperiod) { - case TIME_PERIOD_HOURS: - list = VpnStatus.trafficHistory.getHours(); - interval = TrafficHistory.TIME_PERIOD_HOURS; - totalInterval = 0; - break; - case TIME_PERIOD_MINUTES: - list = VpnStatus.trafficHistory.getMinutes(); - interval = TrafficHistory.TIME_PERIOD_MINTUES; - totalInterval = TrafficHistory.TIME_PERIOD_HOURS * TrafficHistory.PERIODS_TO_KEEP; - ; - - break; - default: - list = VpnStatus.trafficHistory.getSeconds(); - interval = OpenVPNManagement.mBytecountInterval * 1000; - totalInterval = TrafficHistory.TIME_PERIOD_MINTUES * TrafficHistory.PERIODS_TO_KEEP; - break; - } - if (list.size() == 0) { - list = TrafficHistory.getDummyList(); - } - - - long lastts = 0; - float zeroValue; - if (mLogScale) - zeroValue = 2; - else - zeroValue = 0; - - long now = System.currentTimeMillis(); - - - long firstTimestamp = 0; - long lastBytecountOut = 0; - long lastBytecountIn = 0; - - for (TrafficHistory.TrafficDatapoint tdp : list) { - if (totalInterval != 0 && (now - tdp.timestamp) > totalInterval) - continue; - - if (firstTimestamp == 0) { - firstTimestamp = list.peek().timestamp; - lastBytecountIn = list.peek().in; - lastBytecountOut = list.peek().out; - } - - float t = (tdp.timestamp - firstTimestamp) / 100f; - - float in = (tdp.in - lastBytecountIn) / (float) (interval / 1000); - float out = (tdp.out - lastBytecountOut) / (float) (interval / 1000); - - lastBytecountIn = tdp.in; - lastBytecountOut = tdp.out; - - if (mLogScale) { - in = max(2f, (float) Math.log10(in * 8)); - out = max(2f, (float) Math.log10(out * 8)); - } - - if (lastts > 0 && (tdp.timestamp - lastts > 2 * interval)) { - dataIn.add(new Entry((lastts - firstTimestamp + interval) / 100f, zeroValue)); - dataOut.add(new Entry((lastts - firstTimestamp + interval) / 100f, zeroValue)); - - dataIn.add(new Entry(t - interval / 100f, zeroValue)); - dataOut.add(new Entry(t - interval / 100f, zeroValue)); - } - - lastts = tdp.timestamp; - - dataIn.add(new Entry(t, in)); - dataOut.add(new Entry(t, out)); - - } - if (lastts < now - interval) { - - if (now - lastts > 2 * interval * 1000) { - dataIn.add(new Entry((lastts - firstTimestamp + interval * 1000) / 100f, zeroValue)); - dataOut.add(new Entry((lastts - firstTimestamp + interval * 1000) / 100f, zeroValue)); - } - - dataIn.add(new Entry((now - firstTimestamp) / 100, zeroValue)); - dataOut.add(new Entry((now - firstTimestamp) / 100, zeroValue)); - } - - ArrayList dataSets = new ArrayList<>(); - - - LineDataSet indata = new LineDataSet(dataIn, getString(R.string.data_in)); - LineDataSet outdata = new LineDataSet(dataOut, getString(R.string.data_out)); - - setLineDataAttributes(indata, mColourIn); - setLineDataAttributes(outdata, mColourOut); - - dataSets.add(indata); - dataSets.add(outdata); - - return new LineData(dataSets); - } - - private void setLineDataAttributes(LineDataSet dataSet, int colour) { - dataSet.setLineWidth(2); - dataSet.setCircleRadius(1); - dataSet.setDrawCircles(true); - dataSet.setCircleColor(mColourPoint); - dataSet.setDrawFilled(true); - dataSet.setFillAlpha(42); - dataSet.setFillColor(colour); - dataSet.setColor(colour); - dataSet.setMode(LineDataSet.Mode.LINEAR); - - dataSet.setDrawValues(false); - } - } - - private static class ViewHolder { - LineChart chart; - TextView title; - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/InlineFileTab.java b/main/src/main/java/de/blinkt/openvpn/fragments/InlineFileTab.java deleted file mode 100644 index 41206a54..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/InlineFileTab.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.app.Fragment; -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.EditText; -import de.blinkt.openvpn.activities.FileSelect; -import de.blinkt.openvpn.R; - -public class InlineFileTab extends Fragment -{ - - private static final int MENU_SAVE = 0; - private EditText mInlineData; - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - mInlineData.setText(((FileSelect)getActivity()).getInlineData()); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) - { - - View v = inflater.inflate(R.layout.file_dialog_inline, container, false); - mInlineData =(EditText) v.findViewById(R.id.inlineFileData); - return v; - } - - public void setData(String data) { - if(mInlineData!=null) - mInlineData.setText(data); - - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - menu.add(0, MENU_SAVE, 0, R.string.menu_use_inline_data) - .setIcon(android.R.drawable.ic_menu_save) - .setAlphabeticShortcut('u') - .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if(item.getItemId()==MENU_SAVE){ - ((FileSelect)getActivity()).saveInlineData(null, mInlineData.getText().toString()); - return true; - } - return super.onOptionsItemSelected(item); - } - -} \ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/KeyChainSettingsFragment.kt b/main/src/main/java/de/blinkt/openvpn/fragments/KeyChainSettingsFragment.kt deleted file mode 100644 index 323b3a4d..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/KeyChainSettingsFragment.kt +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2012-2018 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments - -import android.annotation.TargetApi -import android.app.Activity -import android.app.AlertDialog -import android.content.ActivityNotFoundException -import android.content.Intent -import android.os.Build -import android.os.Bundle -import android.os.Handler -import android.os.Message -import android.security.KeyChain -import android.security.KeyChainException -import android.security.keystore.KeyInfo -import android.text.TextUtils -import android.view.View -import android.widget.AdapterView -import android.widget.Spinner -import android.widget.TextView -import android.widget.Toast -import de.blinkt.openvpn.R -import de.blinkt.openvpn.VpnProfile -import de.blinkt.openvpn.api.ExternalCertificateProvider -import de.blinkt.openvpn.core.ExtAuthHelper -import de.blinkt.openvpn.core.X509Utils -import java.security.KeyFactory -import java.security.PrivateKey - -import java.security.cert.X509Certificate - -internal abstract class KeyChainSettingsFragment : Settings_Fragment(), View.OnClickListener, Handler.Callback { - - - private lateinit var mAliasCertificate: TextView - private lateinit var mAliasName: TextView - private var mHandler: Handler? = null - private lateinit var mExtAliasName: TextView - private lateinit var mExtAuthSpinner: Spinner - - private val isInHardwareKeystore: Boolean - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) - @Throws(KeyChainException::class, InterruptedException::class) - get() { - val key : PrivateKey = KeyChain.getPrivateKey(activity.applicationContext, mProfile.mAlias) ?: return false - - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) - { - val keyFactory = KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore") - val keyInfo = keyFactory.getKeySpec(key, KeyInfo::class.java) - return keyInfo.isInsideSecureHardware() - - } else { - val algorithm = key.algorithm - return KeyChain.isBoundKeyAlgorithm(algorithm) - } - } - - - private fun setKeyStoreAlias() { - if (mProfile.mAlias == null) { - mAliasName.setText(R.string.client_no_certificate) - mAliasCertificate.text = "" - } else { - mAliasCertificate.text = "Loading certificate from Keystore..." - mAliasName.text = mProfile.mAlias - setCertificate(false) - } - } - - private fun setExtAlias() { - if (mProfile.mAlias == null) { - mExtAliasName.setText(R.string.extauth_not_configured) - mAliasCertificate.text = "" - } else { - mAliasCertificate.text = "Querying certificate from external provider..." - mExtAliasName.text = "" - setCertificate(true) - } - } - - private fun fetchExtCertificateMetaData() { - object : Thread() { - override fun run() { - try { - val b = ExtAuthHelper.getCertificateMetaData(activity, mProfile.mExternalAuthenticator, mProfile.mAlias) - mProfile.mAlias = b.getString(ExtAuthHelper.EXTRA_ALIAS) - activity.runOnUiThread { setAlias() } - } catch (e: KeyChainException) { - e.printStackTrace() - } - - } - }.start() - } - - - protected fun setCertificate(external: Boolean) { - object : Thread() { - override fun run() { - var certstr = "" - var metadata: Bundle? = null - try { - val cert: X509Certificate? - - if (external) { - if (!TextUtils.isEmpty(mProfile.mExternalAuthenticator) && !TextUtils.isEmpty(mProfile.mAlias)) { - cert = ExtAuthHelper.getCertificateChain(activity, mProfile.mExternalAuthenticator, mProfile.mAlias)!![0] - metadata = ExtAuthHelper.getCertificateMetaData(activity, mProfile.mExternalAuthenticator, mProfile.mAlias) - } else { - cert = null - certstr = getString(R.string.extauth_not_configured) - } - } else { - cert = KeyChain.getCertificateChain(activity.applicationContext, mProfile.mAlias)!![0] - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - run { - if (isInHardwareKeystore) - certstr += getString(R.string.hwkeychain) - } - } - } - if (cert != null) { - certstr += X509Utils.getCertificateValidityString(cert, resources) - certstr += X509Utils.getCertificateFriendlyName(cert) - } - - - } catch (e: Exception) { - certstr = "Could not get certificate from Keystore: " + e.localizedMessage!! - } - - val certStringCopy = certstr - val finalMetadata = metadata - activity.runOnUiThread { - mAliasCertificate.text = certStringCopy - if (finalMetadata != null) - mExtAliasName.text = finalMetadata.getString(ExtAuthHelper.EXTRA_DESCRIPTION) - - } - - } - }.start() - } - - protected fun initKeychainViews(v: View) { - v.findViewById(R.id.select_keystore_button).setOnClickListener(this) - v.findViewById(R.id.configure_extauth_button)?.setOnClickListener(this) - v.findViewById(R.id.install_keystore_button).setOnClickListener(this) - mAliasCertificate = v.findViewById(R.id.alias_certificate) - mExtAuthSpinner = v.findViewById(R.id.extauth_spinner) - mExtAuthSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) { - val selectedProvider = parent.getItemAtPosition(position) as ExtAuthHelper.ExternalAuthProvider - if (selectedProvider.packageName != mProfile.mExternalAuthenticator) { - mProfile.mAlias = "" - } - } - - override fun onNothingSelected(parent: AdapterView<*>) { - - } - } - mExtAliasName = v.findViewById(R.id.extauth_detail) - mAliasName = v.findViewById(R.id.aliasname) - if (mHandler == null) { - mHandler = Handler(this) - } - ExtAuthHelper.setExternalAuthProviderSpinnerList(mExtAuthSpinner, mProfile.mExternalAuthenticator) - - v.findViewById(R.id.install_keystore_button).setOnClickListener { - startActivity(KeyChain.createInstallIntent()) }; - } - - override fun onClick(v: View) { - if (v === v.findViewById(R.id.select_keystore_button)) { - showCertDialog() - } else if (v === v.findViewById(R.id.configure_extauth_button)) { - startExternalAuthConfig() - } - } - - private fun startExternalAuthConfig() { - val eAuth = mExtAuthSpinner.selectedItem as ExtAuthHelper.ExternalAuthProvider - mProfile.mExternalAuthenticator = eAuth.packageName - if (!eAuth.configurable) { - fetchExtCertificateMetaData() - return - } - val extauth = Intent(ExtAuthHelper.ACTION_CERT_CONFIGURATION) - extauth.setPackage(eAuth.packageName) - extauth.putExtra(ExtAuthHelper.EXTRA_ALIAS, mProfile.mAlias) - startActivityForResult(extauth, UPDATEE_EXT_ALIAS) - } - - override fun savePreferences() { - - } - - override fun onStart() { - super.onStart() - loadPreferences() - } - - fun showCertDialog() { - try { - KeyChain.choosePrivateKeyAlias(activity, - { alias -> - // Credential alias selected. Remember the alias selection for future use. - mProfile.mAlias = alias - mHandler!!.sendEmptyMessage(UPDATE_ALIAS) - }, - arrayOf("RSA", "EC"), null, // issuer, null for any - mProfile.mServerName, // host name of server requesting the cert, null if unavailable - -1, // port of server requesting the cert, -1 if unavailable - mProfile.mAlias)// List of acceptable key types. null for any - // alias to preselect, null if unavailable - } catch (anf: ActivityNotFoundException) { - val ab = AlertDialog.Builder(activity) - ab.setTitle(R.string.broken_image_cert_title) - ab.setMessage(R.string.broken_image_cert) - ab.setPositiveButton(android.R.string.ok, null) - ab.show() - } - - } - - protected open fun loadPreferences() { - setAlias() - - } - - private fun setAlias() { - if (mProfile.mAuthenticationType == VpnProfile.TYPE_EXTERNAL_APP) - setExtAlias() - else - setKeyStoreAlias() - } - - override fun handleMessage(msg: Message): Boolean { - setAlias() - return true - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { - super.onActivityResult(requestCode, resultCode, data) - - if (requestCode == UPDATEE_EXT_ALIAS && resultCode == Activity.RESULT_OK) { - mProfile.mAlias = data.getStringExtra(ExtAuthHelper.EXTRA_ALIAS) - mExtAliasName.text = data.getStringExtra(ExtAuthHelper.EXTRA_DESCRIPTION) - } - } - - companion object { - private val UPDATE_ALIAS = 20 - private val UPDATEE_EXT_ALIAS = 210 - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java deleted file mode 100644 index e64ce2cd..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ /dev/null @@ -1,694 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.ListFragment; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.res.Resources; -import android.database.DataSetObserver; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.Handler; -import android.os.Handler.Callback; -import android.os.Message; -import android.preference.PreferenceManager; -import android.support.annotation.Nullable; -import android.text.SpannableString; -import android.text.format.DateFormat; -import android.text.style.ImageSpan; -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.AdapterView; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.LinearLayout; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.RadioGroup; -import android.widget.SeekBar; -import android.widget.TextView; -import android.widget.Toast; - -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Date; -import java.util.Locale; -import java.util.Vector; - -import de.blinkt.openvpn.LaunchVPN; -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.activities.DisconnectVPN; -import de.blinkt.openvpn.activities.MainActivity; -import de.blinkt.openvpn.activities.VPNPreferences; -import de.blinkt.openvpn.core.ConnectionStatus; -import de.blinkt.openvpn.core.OpenVPNManagement; -import de.blinkt.openvpn.core.OpenVPNService; -import de.blinkt.openvpn.core.Preferences; -import de.blinkt.openvpn.core.ProfileManager; -import de.blinkt.openvpn.core.VpnStatus; -import de.blinkt.openvpn.core.LogItem; -import de.blinkt.openvpn.core.VpnStatus.LogListener; -import de.blinkt.openvpn.core.VpnStatus.StateListener; - -import static de.blinkt.openvpn.core.OpenVPNService.humanReadableByteCount; - -public class LogFragment extends ListFragment implements StateListener, SeekBar.OnSeekBarChangeListener, RadioGroup.OnCheckedChangeListener, VpnStatus.ByteCountListener { - private static final String LOGTIMEFORMAT = "logtimeformat"; - private static final int START_VPN_CONFIG = 0; - private static final String VERBOSITYLEVEL = "verbositylevel"; - - - - private SeekBar mLogLevelSlider; - private LinearLayout mOptionsLayout; - private RadioGroup mTimeRadioGroup; - private TextView mUpStatus; - private TextView mDownStatus; - private TextView mConnectStatus; - private boolean mShowOptionsLayout; - private CheckBox mClearLogCheckBox; - - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - ladapter.setLogLevel(progress + 1); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - - @Override - public void onCheckedChanged(RadioGroup group, int checkedId) { - switch (checkedId) { - case R.id.radioISO: - ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_ISO); - break; - case R.id.radioNone: - ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_NONE); - break; - case R.id.radioShort: - ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_SHORT); - break; - - } - } - - @Override - public void updateByteCount(long in, long out, long diffIn, long diffOut) { - //%2$s/s %1$s - ↑%4$s/s %3$s - Resources res = getActivity().getResources(); - final String down = String.format("%2$s %1$s", humanReadableByteCount(in, false, res), humanReadableByteCount(diffIn / OpenVPNManagement.mBytecountInterval, true, res)); - final String up = String.format("%2$s %1$s", humanReadableByteCount(out, false, res), humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true, res)); - - if (mUpStatus != null && mDownStatus != null) { - if (getActivity() != null) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - mUpStatus.setText(up); - mDownStatus.setText(down); - } - }); - } - } - - } - - - class LogWindowListAdapter implements ListAdapter, LogListener, Callback { - - private static final int MESSAGE_NEWLOG = 0; - - private static final int MESSAGE_CLEARLOG = 1; - - private static final int MESSAGE_NEWTS = 2; - private static final int MESSAGE_NEWLOGLEVEL = 3; - - public static final int TIME_FORMAT_NONE = 0; - public static final int TIME_FORMAT_SHORT = 1; - public static final int TIME_FORMAT_ISO = 2; - private static final int MAX_STORED_LOG_ENTRIES = 1000; - - private Vector allEntries = new Vector<>(); - - private Vector currentLevelEntries = new Vector(); - - private Handler mHandler; - - private Vector observers = new Vector(); - - private int mTimeFormat = 0; - private int mLogLevel = 3; - - - public LogWindowListAdapter() { - initLogBuffer(); - if (mHandler == null) { - mHandler = new Handler(this); - } - - VpnStatus.addLogListener(this); - } - - - private void initLogBuffer() { - allEntries.clear(); - Collections.addAll(allEntries, VpnStatus.getlogbuffer()); - initCurrentMessages(); - } - - String getLogStr() { - String str = ""; - for (LogItem entry : allEntries) { - str += getTime(entry, TIME_FORMAT_ISO) + entry.getString(getActivity()) + '\n'; - } - return str; - } - - - private void shareLog() { - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_TEXT, getLogStr()); - shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.ics_openvpn_log_file)); - shareIntent.setType("text/plain"); - startActivity(Intent.createChooser(shareIntent, "Send Logfile")); - } - - @Override - public void registerDataSetObserver(DataSetObserver observer) { - observers.add(observer); - - } - - @Override - public void unregisterDataSetObserver(DataSetObserver observer) { - observers.remove(observer); - } - - @Override - public int getCount() { - return currentLevelEntries.size(); - } - - @Override - public Object getItem(int position) { - return currentLevelEntries.get(position); - } - - @Override - public long getItemId(int position) { - return ((Object) currentLevelEntries.get(position)).hashCode(); - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - TextView v; - if (convertView == null) - v = new TextView(getActivity()); - else - v = (TextView) convertView; - - LogItem le = currentLevelEntries.get(position); - String msg = le.getString(getActivity()); - String time = getTime(le, mTimeFormat); - msg = time + msg; - - int spanStart = time.length(); - - SpannableString t = new SpannableString(msg); - - //t.setSpan(getSpanImage(le,(int)v.getTextSize()),spanStart,spanStart+1, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - v.setText(t); - return v; - } - - private String getTime(LogItem le, int time) { - if (time != TIME_FORMAT_NONE) { - Date d = new Date(le.getLogtime()); - java.text.DateFormat timeformat; - if (time == TIME_FORMAT_ISO) - timeformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); - else - timeformat = DateFormat.getTimeFormat(getActivity()); - - return timeformat.format(d) + " "; - - } else { - return ""; - } - - } - - private ImageSpan getSpanImage(LogItem li, int imageSize) { - int imageRes = android.R.drawable.ic_menu_call; - - switch (li.getLogLevel()) { - case ERROR: - imageRes = android.R.drawable.ic_notification_clear_all; - break; - case INFO: - imageRes = android.R.drawable.ic_menu_compass; - break; - case VERBOSE: - imageRes = android.R.drawable.ic_menu_info_details; - break; - case WARNING: - imageRes = android.R.drawable.ic_menu_camera; - break; - } - - Drawable d = getResources().getDrawable(imageRes); - - - //d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); - d.setBounds(0, 0, imageSize, imageSize); - ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BOTTOM); - - return span; - } - - @Override - public int getItemViewType(int position) { - return 0; - } - - @Override - public int getViewTypeCount() { - return 1; - } - - @Override - public boolean isEmpty() { - return currentLevelEntries.isEmpty(); - - } - - @Override - public boolean areAllItemsEnabled() { - return true; - } - - @Override - public boolean isEnabled(int position) { - return true; - } - - @Override - public void newLog(LogItem logMessage) { - Message msg = Message.obtain(); - assert (msg != null); - msg.what = MESSAGE_NEWLOG; - Bundle bundle = new Bundle(); - bundle.putParcelable("logmessage", logMessage); - msg.setData(bundle); - mHandler.sendMessage(msg); - } - - @Override - public boolean handleMessage(Message msg) { - // We have been called - if (msg.what == MESSAGE_NEWLOG) { - - LogItem logMessage = msg.getData().getParcelable("logmessage"); - if (addLogMessage(logMessage)) - for (DataSetObserver observer : observers) { - observer.onChanged(); - } - } else if (msg.what == MESSAGE_CLEARLOG) { - for (DataSetObserver observer : observers) { - observer.onInvalidated(); - } - initLogBuffer(); - } else if (msg.what == MESSAGE_NEWTS) { - for (DataSetObserver observer : observers) { - observer.onInvalidated(); - } - } else if (msg.what == MESSAGE_NEWLOGLEVEL) { - initCurrentMessages(); - - for (DataSetObserver observer : observers) { - observer.onChanged(); - } - - } - - return true; - } - - private void initCurrentMessages() { - currentLevelEntries.clear(); - for (LogItem li : allEntries) { - if (li.getVerbosityLevel() <= mLogLevel || - mLogLevel == VpnProfile.MAXLOGLEVEL) - currentLevelEntries.add(li); - } - } - - /** - * @param logmessage - * @return True if the current entries have changed - */ - private boolean addLogMessage(LogItem logmessage) { - allEntries.add(logmessage); - - if (allEntries.size() > MAX_STORED_LOG_ENTRIES) { - Vector oldAllEntries = allEntries; - allEntries = new Vector(allEntries.size()); - for (int i = 50; i < oldAllEntries.size(); i++) { - allEntries.add(oldAllEntries.elementAt(i)); - } - initCurrentMessages(); - return true; - } else { - if (logmessage.getVerbosityLevel() <= mLogLevel) { - currentLevelEntries.add(logmessage); - return true; - } else { - return false; - } - } - } - - void clearLog() { - // Actually is probably called from GUI Thread as result of the user - // pressing a button. But better safe than sorry - VpnStatus.clearLog(); - VpnStatus.logInfo(R.string.logCleared); - mHandler.sendEmptyMessage(MESSAGE_CLEARLOG); - } - - - public void setTimeFormat(int newTimeFormat) { - mTimeFormat = newTimeFormat; - mHandler.sendEmptyMessage(MESSAGE_NEWTS); - } - - public void setLogLevel(int logLevel) { - mLogLevel = logLevel; - mHandler.sendEmptyMessage(MESSAGE_NEWLOGLEVEL); - } - - } - - - private LogWindowListAdapter ladapter; - private TextView mSpeedView; - - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.clearlog) { - ladapter.clearLog(); - return true; - } else if (item.getItemId() == R.id.cancel) { - Intent intent = new Intent(getActivity(), DisconnectVPN.class); - startActivity(intent); - return true; - } else if (item.getItemId() == R.id.send) { - ladapter.shareLog(); - } else if (item.getItemId() == R.id.edit_vpn) { - VpnProfile lastConnectedprofile = ProfileManager.get(getActivity(), VpnStatus.getLastConnectedVPNProfile()); - - if (lastConnectedprofile != null) { - Intent vprefintent = new Intent(getActivity(), VPNPreferences.class) - .putExtra(VpnProfile.EXTRA_PROFILEUUID, lastConnectedprofile.getUUIDString()); - startActivityForResult(vprefintent, START_VPN_CONFIG); - } else { - Toast.makeText(getActivity(), R.string.log_no_last_vpn, Toast.LENGTH_LONG).show(); - } - } else if (item.getItemId() == R.id.toggle_time) { - showHideOptionsPanel(); - } else if (item.getItemId() == android.R.id.home) { - // This is called when the Home (Up) button is pressed - // in the Action Bar. - Intent parentActivityIntent = new Intent(getActivity(), MainActivity.class); - parentActivityIntent.addFlags( - Intent.FLAG_ACTIVITY_CLEAR_TOP | - Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(parentActivityIntent); - getActivity().finish(); - return true; - - } - return super.onOptionsItemSelected(item); - - } - - private void showHideOptionsPanel() { - boolean optionsVisible = (mOptionsLayout.getVisibility() != View.GONE); - - ObjectAnimator anim; - if (optionsVisible) { - anim = ObjectAnimator.ofFloat(mOptionsLayout, "alpha", 1.0f, 0f); - anim.addListener(collapseListener); - - } else { - mOptionsLayout.setVisibility(View.VISIBLE); - anim = ObjectAnimator.ofFloat(mOptionsLayout, "alpha", 0f, 1.0f); - //anim = new TranslateAnimation(0.0f, 0.0f, mOptionsLayout.getHeight(), 0.0f); - - } - - //anim.setInterpolator(new AccelerateInterpolator(1.0f)); - //anim.setDuration(300); - //mOptionsLayout.startAnimation(anim); - anim.start(); - - } - - AnimatorListenerAdapter collapseListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animator) { - mOptionsLayout.setVisibility(View.GONE); - } - - }; - - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - inflater.inflate(R.menu.logmenu, menu); - if (getResources().getBoolean(R.bool.logSildersAlwaysVisible)) - menu.removeItem(R.id.toggle_time); - } - - - @Override - public void onResume() { - super.onResume(); - Intent intent = new Intent(getActivity(), OpenVPNService.class); - intent.setAction(OpenVPNService.START_SERVICE); - } - - @Override - public void onStart() { - super.onStart(); - VpnStatus.addStateListener(this); - VpnStatus.addByteCountListener(this); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == START_VPN_CONFIG && resultCode == Activity.RESULT_OK) { - String configuredVPN = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); - - final VpnProfile profile = ProfileManager.get(getActivity(), configuredVPN); - ProfileManager.getInstance(getActivity()).saveProfile(getActivity(), profile); - // Name could be modified, reset List adapter - - AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity()); - dialog.setTitle(R.string.configuration_changed); - dialog.setMessage(R.string.restart_vpn_after_change); - - - dialog.setPositiveButton(R.string.restart, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Intent intent = new Intent(getActivity(), LaunchVPN.class); - intent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUIDString()); - intent.setAction(Intent.ACTION_MAIN); - startActivity(intent); - } - - - }); - dialog.setNegativeButton(R.string.ignore, null); - dialog.create().show(); - } - super.onActivityResult(requestCode, resultCode, data); - } - - - @Override - public void onStop() { - super.onStop(); - VpnStatus.removeStateListener(this); - VpnStatus.removeByteCountListener(this); - - getActivity().getPreferences(0).edit().putInt(LOGTIMEFORMAT, ladapter.mTimeFormat) - .putInt(VERBOSITYLEVEL, ladapter.mLogLevel).apply(); - - } - - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - ListView lv = getListView(); - - lv.setOnItemLongClickListener(new OnItemLongClickListener() { - - @Override - public boolean onItemLongClick(AdapterView parent, View view, - int position, long id) { - ClipboardManager clipboard = (ClipboardManager) - getActivity().getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("Log Entry", ((TextView) view).getText()); - clipboard.setPrimaryClip(clip); - Toast.makeText(getActivity(), R.string.copied_entry, Toast.LENGTH_SHORT).show(); - return true; - } - }); - } - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.log_fragment, container, false); - - setHasOptionsMenu(true); - - ladapter = new LogWindowListAdapter(); - ladapter.mTimeFormat = getActivity().getPreferences(0).getInt(LOGTIMEFORMAT, 1); - int logLevel = getActivity().getPreferences(0).getInt(VERBOSITYLEVEL, 1); - ladapter.setLogLevel(logLevel); - - setListAdapter(ladapter); - - mTimeRadioGroup = (RadioGroup) v.findViewById(R.id.timeFormatRadioGroup); - mTimeRadioGroup.setOnCheckedChangeListener(this); - - if (ladapter.mTimeFormat == LogWindowListAdapter.TIME_FORMAT_ISO) { - mTimeRadioGroup.check(R.id.radioISO); - } else if (ladapter.mTimeFormat == LogWindowListAdapter.TIME_FORMAT_NONE) { - mTimeRadioGroup.check(R.id.radioNone); - } else if (ladapter.mTimeFormat == LogWindowListAdapter.TIME_FORMAT_SHORT) { - mTimeRadioGroup.check(R.id.radioShort); - } - - mClearLogCheckBox = (CheckBox) v.findViewById(R.id.clearlogconnect); - mClearLogCheckBox.setChecked(PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean(LaunchVPN.CLEARLOG, true)); - mClearLogCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - Preferences.getDefaultSharedPreferences(getActivity()).edit().putBoolean(LaunchVPN.CLEARLOG, isChecked).apply(); - } - }); - - mSpeedView = (TextView) v.findViewById(R.id.speed); - - mOptionsLayout = (LinearLayout) v.findViewById(R.id.logOptionsLayout); - mLogLevelSlider = (SeekBar) v.findViewById(R.id.LogLevelSlider); - mLogLevelSlider.setMax(VpnProfile.MAXLOGLEVEL - 1); - mLogLevelSlider.setProgress(logLevel - 1); - - mLogLevelSlider.setOnSeekBarChangeListener(this); - - if (getResources().getBoolean(R.bool.logSildersAlwaysVisible)) - mOptionsLayout.setVisibility(View.VISIBLE); - - mUpStatus = (TextView) v.findViewById(R.id.speedUp); - mDownStatus = (TextView) v.findViewById(R.id.speedDown); - mConnectStatus = (TextView) v.findViewById(R.id.speedStatus); - if (mShowOptionsLayout) - mOptionsLayout.setVisibility(View.VISIBLE); - return v; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - // Scroll to the end of the list end - //getListView().setSelection(getListView().getAdapter().getCount()-1); - } - - @Override - public void onAttach(Context activity) { - super.onAttach(activity); - if (getResources().getBoolean(R.bool.logSildersAlwaysVisible)) { - mShowOptionsLayout = true; - if (mOptionsLayout != null) - mOptionsLayout.setVisibility(View.VISIBLE); - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - //getActionBar().setDisplayHomeAsUpEnabled(true); - - } - - - @Override - public void updateState(final String status, final String logMessage, final int resId, final ConnectionStatus level) { - if (isAdded()) { - final String cleanLogMessage = VpnStatus.getLastCleanLogMessage(getActivity()); - - getActivity().runOnUiThread(new Runnable() { - - @Override - public void run() { - if (isAdded()) { - if (mSpeedView != null) { - mSpeedView.setText(cleanLogMessage); - } - if (mConnectStatus != null) - mConnectStatus.setText(cleanLogMessage); - } - } - }); - } - } - - @Override - public void setConnectedVPN(String uuid) { - } - - - @Override - public void onDestroy() { - VpnStatus.removeLogListener(ladapter); - super.onDestroy(); - } - -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java deleted file mode 100644 index ee51c776..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.os.Bundle; -import android.preference.PreferenceFragment; -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.ProfileManager; - -public abstract class OpenVpnPreferencesFragment extends PreferenceFragment { - - protected VpnProfile mProfile; - - protected abstract void loadSettings(); - protected abstract void saveSettings(); - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - String profileUUID = getArguments().getString(getActivity().getPackageName() + ".profileUUID"); - mProfile = ProfileManager.get(getActivity(),profileUUID); - getActivity().setTitle(getString(R.string.edit_profile_title, mProfile.getName())); - - } - - @Override - public void onPause() { - super.onPause(); - saveSettings(); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - if(savedInstanceState!=null) { - String profileUUID=savedInstanceState.getString(VpnProfile.EXTRA_PROFILEUUID); - mProfile = ProfileManager.get(getActivity(),profileUUID); - loadSettings(); - } - } - - @Override - public void onSaveInstanceState (Bundle outState) { - super.onSaveInstanceState(outState); - saveSettings(); - outState.putString(VpnProfile.EXTRA_PROFILEUUID, mProfile.getUUIDString()); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/SendDumpFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/SendDumpFragment.java deleted file mode 100644 index e138197a..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/SendDumpFragment.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import java.io.File; -import java.util.ArrayList; -import java.util.Date; - -import android.app.Fragment; -import android.content.Context; -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.util.Pair; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.TextView; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.core.VpnStatus; - -public class SendDumpFragment extends Fragment { - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - - final View v = inflater.inflate(R.layout.fragment_senddump, container, false); - v.findViewById(R.id.senddump).setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - emailMiniDumps(); - } - }); - - new Thread(new Runnable() { - @Override - public void run() { - final Pair ldump = getLastestDump(getActivity()); - if (ldump==null) - return; - // Do in background since it does I/O - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - TextView dumpDateText = (TextView) v.findViewById(R.id.dumpdate); - String datestr = (new Date(ldump.second)).toString(); - long timediff = System.currentTimeMillis() - ldump.second; - long minutes = timediff / 1000 / 60 % 60; - long hours = timediff / 1000 / 60 / 60; - dumpDateText.setText(getString(R.string.lastdumpdate, hours, minutes, datestr)); - - } - }); - } - }).start(); - return v; - } - - public void emailMiniDumps() - { - //need to "send multiple" to get more than one attachment - final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE); - emailIntent.setType("*/*"); - emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, - new String[]{"Arne Schwabe "}); - - String version; - String name="ics-openvpn"; - try { - PackageInfo packageinfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0); - version = packageinfo.versionName; - name = packageinfo.applicationInfo.name; - } catch (NameNotFoundException e) { - version = "error fetching version"; - } - - - emailIntent.putExtra(Intent.EXTRA_SUBJECT, String.format("%s(%s) %s Minidump",name, getActivity().getPackageName(), version)); - - emailIntent.putExtra(Intent.EXTRA_TEXT, "Please describe the issue you have experienced"); - - ArrayList uris = new ArrayList<>(); - - Pair ldump = getLastestDump(getActivity()); - if(ldump==null) { - VpnStatus.logError("No Minidump found!"); - } - - uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/" + ldump.first.getName())); - uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/" + ldump.first.getName() + ".log")); - - emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); - startActivity(emailIntent); - } - - static public Pair getLastestDump(Context c) { - long newestDumpTime=0; - File newestDumpFile=null; - - if (c.getCacheDir() ==null) - return null; - - for(File f:c.getCacheDir().listFiles()) { - if(!f.getName().endsWith(".dmp")) - continue; - - if (newestDumpTime < f.lastModified()) { - newestDumpTime = f.lastModified(); - newestDumpFile=f; - } - } - // Ignore old dumps - if(System.currentTimeMillis() - 48 * 60 * 1000 > newestDumpTime ) - return null; - - return Pair.create(newestDumpFile, newestDumpTime); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Allowed_Apps.kt b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Allowed_Apps.kt deleted file mode 100644 index dd2aa3b7..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Allowed_Apps.kt +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments - -import android.Manifest -import android.app.Activity -import android.app.Fragment -import android.content.Context -import android.content.pm.ApplicationInfo -import android.content.pm.PackageManager -import android.os.Bundle -import android.text.TextUtils -import android.util.Log -import android.view.LayoutInflater -import android.view.Menu -import android.view.MenuInflater -import android.view.View -import android.view.ViewGroup -import android.widget.AdapterView -import android.widget.BaseAdapter -import android.widget.CompoundButton -import android.widget.Filter -import android.widget.Filterable -import android.widget.ImageView -import android.widget.ListView -import android.widget.SearchView -import android.widget.Switch -import android.widget.TextView - -import java.util.Collections -import java.util.Locale -import java.util.Vector - -import de.blinkt.openvpn.R -import de.blinkt.openvpn.VpnProfile -import de.blinkt.openvpn.core.ProfileManager - -/** - * Created by arne on 16.11.14. - */ -class Settings_Allowed_Apps : Fragment(), AdapterView.OnItemClickListener, CompoundButton.OnCheckedChangeListener, View.OnClickListener { - private lateinit var mListView: ListView - private lateinit var mProfile: VpnProfile - private lateinit var mDefaultAllowTextView: TextView - private lateinit var mListAdapter: PackageAdapter - private lateinit var mSettingsView: View - - - override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) { - val avh = view.tag as AppViewHolder - avh.checkBox.toggle() - } - - override fun onClick(v: View) { - - } - - override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) { - val packageName = buttonView.tag as String - if (isChecked) { - mProfile.mAllowedAppsVpn.add(packageName) - } else { - mProfile.mAllowedAppsVpn.remove(packageName) - } - } - - override fun onResume() { - super.onResume() - changeDisallowText(mProfile.mAllowedAppsVpnAreDisallowed) - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - val profileUuid = arguments.getString(activity.packageName + ".profileUUID") - mProfile = ProfileManager.get(activity, profileUuid) - activity.title = getString(R.string.edit_profile_title, mProfile.name) - setHasOptionsMenu(true) - } - - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.allowed_apps, menu) - - val searchView = menu.findItem(R.id.app_search_widget).actionView as SearchView - searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { - override fun onQueryTextSubmit(query: String): Boolean { - mListView.setFilterText(query) - mListView.isTextFilterEnabled = true - return true - } - - override fun onQueryTextChange(newText: String): Boolean { - mListView.setFilterText(newText) - mListView.isTextFilterEnabled = !TextUtils.isEmpty(newText) - - return true - } - }) - searchView.setOnCloseListener { - mListView.clearTextFilter() - mListAdapter.filter.filter("") - false - } - - super.onCreateOptionsMenu(menu, inflater) - } - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - val v = inflater.inflate(R.layout.allowed_vpn_apps, container, false) - - mSettingsView = inflater.inflate(R.layout.allowed_application_settings, container, false) - mDefaultAllowTextView = mSettingsView.findViewById(R.id.default_allow_text) as TextView - - val vpnOnDefaultSwitch = mSettingsView.findViewById(R.id.default_allow) as Switch - - vpnOnDefaultSwitch.setOnCheckedChangeListener { buttonView, isChecked -> - changeDisallowText(isChecked) - mProfile.mAllowedAppsVpnAreDisallowed = isChecked - } - - vpnOnDefaultSwitch.isChecked = mProfile.mAllowedAppsVpnAreDisallowed - - val vpnAllowBypassSwitch = mSettingsView.findViewById(R.id.allow_bypass) as Switch - - vpnAllowBypassSwitch.setOnCheckedChangeListener { buttonView, isChecked -> mProfile.mAllowAppVpnBypass = isChecked } - - vpnAllowBypassSwitch.isChecked = mProfile.mAllowAppVpnBypass - - mListView = v.findViewById(android.R.id.list) as ListView - - mListAdapter = PackageAdapter(activity, mProfile) - mListView.adapter = mListAdapter - mListView.onItemClickListener = this - - mListView.emptyView = v.findViewById(R.id.loading_container) - - Thread(Runnable { mListAdapter.populateList(activity) }).start() - - return v - } - - private fun changeDisallowText(selectedAreDisallowed: Boolean) { - if (selectedAreDisallowed) - mDefaultAllowTextView.setText(R.string.vpn_disallow_radio) - else - mDefaultAllowTextView.setText(R.string.vpn_allow_radio) - } - - internal class AppViewHolder { - var mInfo: ApplicationInfo? = null - var rootView: View? = null - lateinit var appName: TextView - lateinit var appIcon: ImageView - //public TextView appSize; - //public TextView disabled; - lateinit var checkBox: CompoundButton - - companion object { - - fun createOrRecycle(inflater: LayoutInflater, oldview: View?, parent: ViewGroup): AppViewHolder { - var convertView = oldview - if (convertView == null) { - convertView = inflater.inflate(R.layout.allowed_application_layout, parent, false) - - // Creates a ViewHolder and store references to the two children views - // we want to bind data to. - val holder = AppViewHolder() - holder.rootView = convertView - holder.appName = convertView.findViewById(R.id.app_name) as TextView - holder.appIcon = convertView.findViewById(R.id.app_icon) as ImageView - //holder.appSize = (TextView) convertView.findViewById(R.id.app_size); - //holder.disabled = (TextView) convertView.findViewById(R.id.app_disabled); - holder.checkBox = convertView.findViewById(R.id.app_selected) as CompoundButton - convertView.tag = holder - - - return holder - } else { - // Get the ViewHolder back to get fast access to the TextView - // and the ImageView. - return convertView.tag as AppViewHolder - } - } - } - - } - - internal inner class PackageAdapter(c: Context, vp: VpnProfile) : BaseAdapter(), Filterable { - private val mInflater: LayoutInflater = LayoutInflater.from(c) - private val mPm: PackageManager = c.packageManager - private var mPackages: Vector = Vector() - private val mFilter = ItemFilter() - private var mFilteredData: Vector = mPackages - private val mProfile = vp - - - fun populateList(c: Activity) { - val installedPackages = mPm.getInstalledApplications(PackageManager.GET_META_DATA) - - // Remove apps not using Internet - - var androidSystemUid = 0 - val apps = Vector() - - try { - val system = mPm.getApplicationInfo("android", PackageManager.GET_META_DATA) - androidSystemUid = system.uid - apps.add(system) - } catch (e: PackageManager.NameNotFoundException) { - } - - - for (app in installedPackages) { - - if (mPm.checkPermission(Manifest.permission.INTERNET, app.packageName) == PackageManager.PERMISSION_GRANTED && app.uid != androidSystemUid) { - - apps.add(app) - } - } - - Collections.sort(apps, ApplicationInfo.DisplayNameComparator(mPm)) - mPackages = apps - mFilteredData = apps - c.runOnUiThread { notifyDataSetChanged() } - } - - override fun getCount(): Int { - return mFilteredData.size + 1 - } - - override fun getItem(position: Int): Any { - return mFilteredData[position - 1] - } - - override fun getItemId(position: Int): Long { - if (position == 0) - return "settings".hashCode().toLong() - return mFilteredData[position - 1].packageName.hashCode().toLong() - } - - override fun getView(position: Int, convertView: View?, parent: ViewGroup): View? { - if (position == 0) { - return mSettingsView - } else - return getViewApp(position - 1, convertView, parent) - - } - - fun getViewApp(position: Int, convertView: View?, parent: ViewGroup): View? { - val viewHolder = AppViewHolder.createOrRecycle(mInflater, convertView, parent) - viewHolder.mInfo = mFilteredData[position] - val mInfo = mFilteredData[position] - - - var appName = mInfo.loadLabel(mPm) - - if (TextUtils.isEmpty(appName)) - appName = mInfo.packageName - viewHolder.appName.text = appName - viewHolder.appIcon.setImageDrawable(mInfo.loadIcon(mPm)) - viewHolder.checkBox.tag = mInfo.packageName - viewHolder.checkBox.setOnCheckedChangeListener(this@Settings_Allowed_Apps) - - - viewHolder.checkBox.isChecked = mProfile.mAllowedAppsVpn.contains(mInfo.packageName) - return viewHolder.rootView - } - - override fun getFilter(): Filter { - return mFilter - } - - override fun getViewTypeCount(): Int { - return 2; - } - - override fun getItemViewType(position: Int): Int { - return if (position == 0) 0 else 1 - } - - private inner class ItemFilter : Filter() { - override fun performFiltering(constraint: CharSequence): Filter.FilterResults { - - val filterString = constraint.toString().toLowerCase(Locale.getDefault()) - - val results = Filter.FilterResults() - - - val count = mPackages.size - val nlist = Vector(count) - - for (i in 0 until count) { - val pInfo = mPackages[i] - var appName = pInfo.loadLabel(mPm) - - if (TextUtils.isEmpty(appName)) - appName = pInfo.packageName - - if (appName is String) { - if (appName.toLowerCase(Locale.getDefault()).contains(filterString)) - nlist.add(pInfo) - } else { - if (appName.toString().toLowerCase(Locale.getDefault()).contains(filterString)) - nlist.add(pInfo) - } - } - results.values = nlist - results.count = nlist.size - - return results - } - - override fun publishResults(constraint: CharSequence, results: Filter.FilterResults) { - mFilteredData = results.values as Vector - notifyDataSetChanged() - } - - } - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Authentication.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Authentication.java deleted file mode 100644 index 1fc7337c..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Authentication.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.app.Activity; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.EditTextPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceChangeListener; -import android.preference.Preference.OnPreferenceClickListener; -import android.preference.SwitchPreference; -import android.text.TextUtils; -import android.util.Pair; -import de.blinkt.openvpn.activities.FileSelect; -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.core.VpnStatus; -import de.blinkt.openvpn.views.RemoteCNPreference; -import de.blinkt.openvpn.VpnProfile; - -import java.io.IOException; - - -public class Settings_Authentication extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener, OnPreferenceClickListener { - private static final int SELECT_TLS_FILE_LEGACY_DIALOG = 23223232; - private static final int SELECT_TLS_FILE_KITKAT = SELECT_TLS_FILE_LEGACY_DIALOG +1; - private CheckBoxPreference mExpectTLSCert; - private CheckBoxPreference mCheckRemoteCN; - private RemoteCNPreference mRemoteCN; - private ListPreference mTLSAuthDirection; - private Preference mTLSAuthFile; - private SwitchPreference mUseTLSAuth; - private EditTextPreference mCipher; - private String mTlsAuthFileData; - private EditTextPreference mAuth; - private EditTextPreference mRemoteX509Name; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.vpn_authentification); - - mExpectTLSCert = (CheckBoxPreference) findPreference("remoteServerTLS"); - mCheckRemoteCN = (CheckBoxPreference) findPreference("checkRemoteCN"); - mRemoteCN = (RemoteCNPreference) findPreference("remotecn"); - mRemoteCN.setOnPreferenceChangeListener(this); - - mRemoteX509Name = (EditTextPreference) findPreference("remotex509name"); - mRemoteX509Name.setOnPreferenceChangeListener(this); - - mUseTLSAuth = (SwitchPreference) findPreference("useTLSAuth" ); - mTLSAuthFile = findPreference("tlsAuthFile"); - mTLSAuthDirection = (ListPreference) findPreference("tls_direction"); - - - mTLSAuthFile.setOnPreferenceClickListener(this); - - mCipher =(EditTextPreference) findPreference("cipher"); - mCipher.setOnPreferenceChangeListener(this); - - mAuth =(EditTextPreference) findPreference("auth"); - mAuth.setOnPreferenceChangeListener(this); - - loadSettings(); - - } - - @Override - protected void loadSettings() { - - mExpectTLSCert.setChecked(mProfile.mExpectTLSCert); - mCheckRemoteCN.setChecked(mProfile.mCheckRemoteCN); - mRemoteCN.setDN(mProfile.mRemoteCN); - mRemoteCN.setAuthType(mProfile.mX509AuthType); - onPreferenceChange(mRemoteCN, - new Pair(mProfile.mX509AuthType, mProfile.mRemoteCN)); - - mRemoteX509Name.setText(mProfile.mx509UsernameField); - onPreferenceChange(mRemoteX509Name, mProfile.mx509UsernameField); - - mUseTLSAuth.setChecked(mProfile.mUseTLSAuth); - mTlsAuthFileData= mProfile.mTLSAuthFilename; - setTlsAuthSummary(mTlsAuthFileData); - mTLSAuthDirection.setValue(mProfile.mTLSAuthDirection); - mCipher.setText(mProfile.mCipher); - onPreferenceChange(mCipher, mProfile.mCipher); - mAuth.setText(mProfile.mAuth); - onPreferenceChange(mAuth, mProfile.mAuth); - - if (mProfile.mAuthenticationType == VpnProfile.TYPE_STATICKEYS) { - mExpectTLSCert.setEnabled(false); - mCheckRemoteCN.setEnabled(false); - mUseTLSAuth.setChecked(true); - } else { - mExpectTLSCert.setEnabled(true); - mCheckRemoteCN.setEnabled(true); - - } - } - - @Override - protected void saveSettings() { - mProfile.mExpectTLSCert=mExpectTLSCert.isChecked(); - mProfile.mCheckRemoteCN=mCheckRemoteCN.isChecked(); - mProfile.mRemoteCN=mRemoteCN.getCNText(); - mProfile.mX509AuthType=mRemoteCN.getAuthtype(); - - mProfile.mUseTLSAuth = mUseTLSAuth.isChecked(); - mProfile.mTLSAuthFilename = mTlsAuthFileData; - mProfile.mx509UsernameField = mRemoteX509Name.getText(); - - if(mTLSAuthDirection.getValue()==null) - mProfile.mTLSAuthDirection=null; - else - mProfile.mTLSAuthDirection = mTLSAuthDirection.getValue(); - - if(mCipher.getText()==null) - mProfile.mCipher=null; - else - mProfile.mCipher = mCipher.getText(); - - if(mAuth.getText()==null) - mProfile.mAuth = null; - else - mProfile.mAuth = mAuth.getText(); - - } - - - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if(preference==mRemoteCN) { - @SuppressWarnings("unchecked") - int authtype = ((Pair) newValue).first; - @SuppressWarnings("unchecked") - String dn = ((Pair) newValue).second; - - if ("".equals(dn)) { - if (mProfile.mConnections.length > 0) { - preference.setSummary(getX509String(VpnProfile.X509_VERIFY_TLSREMOTE_RDN, mProfile.mConnections[0].mServerName)); - } else { - preference.setSummary(R.string.no_remote_defined); - } - } else { - preference.setSummary(getX509String(authtype, dn)); - } - - } else if (preference == mCipher || preference == mAuth) { - preference.setSummary((CharSequence) newValue); - } else if (preference == mRemoteX509Name) { - preference.setSummary(TextUtils.isEmpty((CharSequence) newValue) ? "CN (default)" : (CharSequence)newValue); - } - return true; - } - private CharSequence getX509String(int authtype, String dn) { - String ret =""; - switch (authtype) { - case VpnProfile.X509_VERIFY_TLSREMOTE: - case VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING: - ret+="tls-remote "; - break; - - case VpnProfile.X509_VERIFY_TLSREMOTE_DN: - ret="dn: "; - break; - - case VpnProfile.X509_VERIFY_TLSREMOTE_RDN: - ret="rdn: "; - break; - - case VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX: - ret="rdn prefix: "; - break; - } - return ret + dn; - } - - void startFileDialog() { - Intent startFC = null; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && ! Utils.alwaysUseOldFileChooser(getActivity())) { - startFC = Utils.getFilePickerIntent(getActivity(), Utils.FileType.TLS_AUTH_FILE); - startActivityForResult(startFC, SELECT_TLS_FILE_KITKAT); - } - - if (startFC == null) { - startFC = new Intent(getActivity(), FileSelect.class); - startFC.putExtra(FileSelect.START_DATA, mTlsAuthFileData); - startFC.putExtra(FileSelect.WINDOW_TITLE, R.string.tls_auth_file); - startActivityForResult(startFC, SELECT_TLS_FILE_LEGACY_DIALOG); - } - } - - @Override - public boolean onPreferenceClick(Preference preference) { - startFileDialog(); - return true; - - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if(requestCode == SELECT_TLS_FILE_LEGACY_DIALOG && resultCode == Activity.RESULT_OK){ - String result = data.getStringExtra(FileSelect.RESULT_DATA); - mTlsAuthFileData=result; - setTlsAuthSummary(result); - } else if (requestCode == SELECT_TLS_FILE_KITKAT && resultCode == Activity.RESULT_OK) { - try { - mTlsAuthFileData= Utils.getFilePickerResult(Utils.FileType.TLS_AUTH_FILE,data,getActivity()); - setTlsAuthSummary(mTlsAuthFileData); - } catch (IOException e) { - VpnStatus.logException(e); - } catch (SecurityException se) { - VpnStatus.logException(se); - } - } - } - - private void setTlsAuthSummary(String result) { - if(result==null) - result = getString(R.string.no_certificate); - if(result.startsWith(VpnProfile.INLINE_TAG)) - mTLSAuthFile.setSummary(R.string.inline_file_data); - else if (result.startsWith(VpnProfile.DISPLAYNAME_TAG)) - mTLSAuthFile.setSummary(getString(R.string.imported_from_file, VpnProfile.getDisplayName(result))); - else - mTLSAuthFile.setSummary(result); - } -} \ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java deleted file mode 100644 index 81da76fe..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.util.SparseArray; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.*; -import android.widget.AdapterView.OnItemSelectedListener; -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.R.id; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.ProfileManager; -import de.blinkt.openvpn.views.FileSelectLayout; - -public class Settings_Basic extends KeyChainSettingsFragment implements OnItemSelectedListener, FileSelectLayout.FileSelectCallback { - private static final int CHOOSE_FILE_OFFSET = 1000; - - private FileSelectLayout mClientCert; - private FileSelectLayout mCaCert; - private FileSelectLayout mClientKey; - private CheckBox mUseLzo; - private Spinner mType; - private FileSelectLayout mpkcs12; - private FileSelectLayout mCrlFile; - private TextView mPKCS12Password; - private EditText mUserName; - private EditText mPassword; - private View mView; - private EditText mProfileName; - private EditText mKeyPassword; - - private SparseArray fileselects = new SparseArray<>(); - private Spinner mAuthRetry; - - - private void addFileSelectLayout(FileSelectLayout fsl, Utils.FileType type) { - int i = fileselects.size() + CHOOSE_FILE_OFFSET; - fileselects.put(i, fsl); - fsl.setCaller(this, i, type); - } - - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - - mView = inflater.inflate(R.layout.basic_settings, container, false); - - mProfileName = mView.findViewById(id.profilename); - mClientCert = mView.findViewById(id.certselect); - mClientKey = mView.findViewById(id.keyselect); - mCaCert = mView.findViewById(id.caselect); - mpkcs12 = mView.findViewById(id.pkcs12select); - mCrlFile = mView.findViewById(id.crlfile); - mUseLzo = mView.findViewById(id.lzo); - mType = mView.findViewById(id.type); - mPKCS12Password = mView.findViewById(id.pkcs12password); - - mUserName = mView.findViewById(id.auth_username); - mPassword = mView.findViewById(id.auth_password); - mKeyPassword = mView.findViewById(id.key_password); - mAuthRetry = mView.findViewById(id.auth_retry); - - addFileSelectLayout(mCaCert, Utils.FileType.CA_CERTIFICATE); - addFileSelectLayout(mClientCert, Utils.FileType.CLIENT_CERTIFICATE); - addFileSelectLayout(mClientKey, Utils.FileType.KEYFILE); - addFileSelectLayout(mpkcs12, Utils.FileType.PKCS12); - addFileSelectLayout(mCrlFile, Utils.FileType.CRL_FILE); - mCaCert.setShowClear(); - mCrlFile.setShowClear(); - - mType.setOnItemSelectedListener(this); - mAuthRetry.setOnItemSelectedListener(this); - - initKeychainViews(mView); - - return mView; - } - - - @Override - public void onActivityResult(int request, int result, Intent data) { - super.onActivityResult(request, result, data); - if (result == Activity.RESULT_OK && request >= CHOOSE_FILE_OFFSET) { - FileSelectLayout fsl = fileselects.get(request); - fsl.parseResponse(data, getActivity()); - - savePreferences(); - - // Private key files may result in showing/hiding the private key password dialog - if (fsl == mClientKey) { - changeType(mType.getSelectedItemPosition()); - } - } - - } - - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - if (parent == mType) { - changeType(position); - } - } - - - private void changeType(int type) { - // hide everything - mView.findViewById(R.id.pkcs12).setVisibility(View.GONE); - mView.findViewById(R.id.certs).setVisibility(View.GONE); - mView.findViewById(R.id.statickeys).setVisibility(View.GONE); - mView.findViewById(R.id.keystore).setVisibility(View.GONE); - mView.findViewById(R.id.cacert).setVisibility(View.GONE); - ((FileSelectLayout) mView.findViewById(R.id.caselect)).setClearable(false); - mView.findViewById(R.id.userpassword).setVisibility(View.GONE); - mView.findViewById(R.id.key_password_layout).setVisibility(View.GONE); - mView.findViewById(R.id.external_auth).setVisibility(View.GONE); - - // Fall through are by design - switch (type) { - case VpnProfile.TYPE_USERPASS_CERTIFICATES: - mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE); - case VpnProfile.TYPE_CERTIFICATES: - mView.findViewById(R.id.certs).setVisibility(View.VISIBLE); - mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE); - if (mProfile.requireTLSKeyPassword()) - mView.findViewById(R.id.key_password_layout).setVisibility(View.VISIBLE); - break; - - case VpnProfile.TYPE_USERPASS_PKCS12: - mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE); - case VpnProfile.TYPE_PKCS12: - mView.findViewById(R.id.pkcs12).setVisibility(View.VISIBLE); - mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE); - ((FileSelectLayout) mView.findViewById(R.id.caselect)).setClearable(true); - break; - - case VpnProfile.TYPE_STATICKEYS: - mView.findViewById(R.id.statickeys).setVisibility(View.VISIBLE); - break; - - case VpnProfile.TYPE_USERPASS_KEYSTORE: - mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE); - case VpnProfile.TYPE_KEYSTORE: - mView.findViewById(R.id.keystore).setVisibility(View.VISIBLE); - mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE); - ((FileSelectLayout) mView.findViewById(R.id.caselect)).setClearable(true); - break; - - case VpnProfile.TYPE_USERPASS: - mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE); - mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE); - break; - case VpnProfile.TYPE_EXTERNAL_APP: - mView.findViewById(R.id.external_auth).setVisibility(View.VISIBLE); - break; - } - - - } - - protected void loadPreferences() { - super.loadPreferences(); - mProfileName.setText(mProfile.mName); - mClientCert.setData(mProfile.mClientCertFilename, getActivity()); - mClientKey.setData(mProfile.mClientKeyFilename, getActivity()); - mCaCert.setData(mProfile.mCaFilename, getActivity()); - mCrlFile.setData(mProfile.mCrlFilename, getActivity()); - - mUseLzo.setChecked(mProfile.mUseLzo); - mType.setSelection(mProfile.mAuthenticationType); - mpkcs12.setData(mProfile.mPKCS12Filename, getActivity()); - mPKCS12Password.setText(mProfile.mPKCS12Password); - mUserName.setText(mProfile.mUsername); - mPassword.setText(mProfile.mPassword); - mKeyPassword.setText(mProfile.mKeyPassword); - mAuthRetry.setSelection(mProfile.mAuthRetry); - } - - protected void savePreferences() { - super.savePreferences(); - mProfile.mName = mProfileName.getText().toString(); - mProfile.mCaFilename = mCaCert.getData(); - mProfile.mClientCertFilename = mClientCert.getData(); - mProfile.mClientKeyFilename = mClientKey.getData(); - mProfile.mCrlFilename = mCrlFile.getData(); - - mProfile.mUseLzo = mUseLzo.isChecked(); - mProfile.mAuthenticationType = mType.getSelectedItemPosition(); - mProfile.mPKCS12Filename = mpkcs12.getData(); - mProfile.mPKCS12Password = mPKCS12Password.getText().toString(); - - mProfile.mPassword = mPassword.getText().toString(); - mProfile.mUsername = mUserName.getText().toString(); - mProfile.mKeyPassword = mKeyPassword.getText().toString(); - mProfile.mAuthRetry = mAuthRetry.getSelectedItemPosition(); - - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - savePreferences(); - if (mProfile != null) { - outState.putString(getActivity().getPackageName() + "profileUUID", mProfile.getUUID().toString()); - } - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - - -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Connections.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Connections.java deleted file mode 100644 index e41e6cb9..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Connections.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.os.Build; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -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.Checkable; -import android.widget.ImageButton; -import android.widget.TextView; - -import de.blinkt.openvpn.R; - -public class Settings_Connections extends Settings_Fragment implements View.OnClickListener { - private ConnectionsAdapter mConnectionsAdapter; - private TextView mWarning; - private Checkable mUseRandomRemote; - private RecyclerView mRecyclerView; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) - inflater.inflate(R.menu.connections, menu); - super.onCreateOptionsMenu(menu, inflater); - } - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.connections, container, false); - - mWarning = (TextView) v.findViewById(R.id.noserver_active_warning); - mRecyclerView = (RecyclerView) v.findViewById(R.id.connection_recycler_view); - - int dpwidth = (int) (container.getWidth()/getResources().getDisplayMetrics().density); - int columns = dpwidth/290; - columns = Math.max(1, columns); - - mConnectionsAdapter = new ConnectionsAdapter(getActivity(), this, mProfile); - - //mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(columns, StaggeredGridLayoutManager.VERTICAL)); - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL,false)); - mRecyclerView.setAdapter(mConnectionsAdapter); - - ImageButton fab_button = (ImageButton) v.findViewById(R.id.add_new_remote); - if(fab_button!=null) - fab_button.setOnClickListener(this); - - mUseRandomRemote = (Checkable) v.findViewById(R.id.remote_random); - mUseRandomRemote.setChecked(mProfile.mRemoteRandom); - - - mConnectionsAdapter.displayWarningIfNoneEnabled(); - - return v; - } - - @Override - public void onClick(View v) { - if (v.getId() == R.id.add_new_remote) { - mConnectionsAdapter.addRemote(); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId()==R.id.add_new_remote) - mConnectionsAdapter.addRemote(); - return super.onOptionsItemSelected(item); - } - - @Override - protected void savePreferences() { - mConnectionsAdapter.saveProfile(); - mProfile.mRemoteRandom = mUseRandomRemote.isChecked(); - } - - public void setWarningVisible(int showWarning) { - mWarning.setVisibility(showWarning); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Fragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Fragment.java deleted file mode 100644 index 738bd0e9..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Fragment.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2012-2015 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.app.Fragment; -import android.os.Bundle; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.ProfileManager; - -public abstract class Settings_Fragment extends Fragment { - - protected VpnProfile mProfile; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - String profileUuid = getArguments().getString(getActivity().getPackageName() + ".profileUUID"); - mProfile= ProfileManager.get(getActivity(), profileUuid); - getActivity().setTitle(getString(R.string.edit_profile_title, mProfile.getName())); - } - - - @Override - public void onPause() { - super.onPause(); - savePreferences(); - } - - protected abstract void savePreferences(); -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_IP.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_IP.java deleted file mode 100644 index fec849ca..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_IP.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.EditTextPreference; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceChangeListener; -import android.preference.PreferenceManager; -import android.preference.SwitchPreference; -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; - -public class Settings_IP extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { - private EditTextPreference mIPv4; - private EditTextPreference mIPv6; - private SwitchPreference mUsePull; - private CheckBoxPreference mOverrideDNS; - private EditTextPreference mSearchdomain; - private EditTextPreference mDNS1; - private EditTextPreference mDNS2; - private CheckBoxPreference mNobind; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - - // Make sure default values are applied. In a real app, you would - // want this in a shared function that is used to retrieve the - // SharedPreferences wherever they are needed. - PreferenceManager.setDefaultValues(getActivity(), - R.xml.vpn_ipsettings, false); - - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.vpn_ipsettings); - mIPv4 = (EditTextPreference) findPreference("ipv4_address"); - mIPv6 = (EditTextPreference) findPreference("ipv6_address"); - mUsePull = (SwitchPreference) findPreference("usePull"); - mOverrideDNS = (CheckBoxPreference) findPreference("overrideDNS"); - mSearchdomain =(EditTextPreference) findPreference("searchdomain"); - mDNS1 = (EditTextPreference) findPreference("dns1"); - mDNS2 = (EditTextPreference) findPreference("dns2"); - mNobind = (CheckBoxPreference) findPreference("nobind"); - - mIPv4.setOnPreferenceChangeListener(this); - mIPv6.setOnPreferenceChangeListener(this); - mDNS1.setOnPreferenceChangeListener(this); - mDNS2.setOnPreferenceChangeListener(this); - mUsePull.setOnPreferenceChangeListener(this); - mOverrideDNS.setOnPreferenceChangeListener(this); - mSearchdomain.setOnPreferenceChangeListener(this); - - loadSettings(); - } - - @Override - protected void loadSettings() { - - mUsePull.setChecked(mProfile.mUsePull); - mIPv4.setText(mProfile.mIPv4Address); - mIPv6.setText(mProfile.mIPv6Address); - mDNS1.setText(mProfile.mDNS1); - mDNS2.setText(mProfile.mDNS2); - mOverrideDNS.setChecked(mProfile.mOverrideDNS); - mSearchdomain.setText(mProfile.mSearchDomain); - mNobind.setChecked(mProfile.mNobind); - if (mProfile.mAuthenticationType == VpnProfile.TYPE_STATICKEYS) - mUsePull.setChecked(false); - - mUsePull.setEnabled(mProfile.mAuthenticationType != VpnProfile.TYPE_STATICKEYS); - - // Sets Summary - onPreferenceChange(mIPv4, mIPv4.getText()); - onPreferenceChange(mIPv6, mIPv6.getText()); - onPreferenceChange(mDNS1, mDNS1.getText()); - onPreferenceChange(mDNS2, mDNS2.getText()); - onPreferenceChange(mSearchdomain, mSearchdomain.getText()); - - setDNSState(); - } - - - @Override - protected void saveSettings() { - mProfile.mUsePull = mUsePull.isChecked(); - mProfile.mIPv4Address = mIPv4.getText(); - mProfile.mIPv6Address = mIPv6.getText(); - mProfile.mDNS1 = mDNS1.getText(); - mProfile.mDNS2 = mDNS2.getText(); - mProfile.mOverrideDNS = mOverrideDNS.isChecked(); - mProfile.mSearchDomain = mSearchdomain.getText(); - mProfile.mNobind = mNobind.isChecked(); - - } - - @Override - public boolean onPreferenceChange(Preference preference, - Object newValue) { - if(preference==mIPv4 || preference == mIPv6 - || preference==mDNS1 || preference == mDNS2 - || preference == mSearchdomain - ) - - preference.setSummary((String)newValue); - - if(preference== mUsePull || preference == mOverrideDNS) - if(preference==mOverrideDNS) { - // Set so the function gets the right value - mOverrideDNS.setChecked((Boolean) newValue); - } - setDNSState(); - - saveSettings(); - return true; - } - - private void setDNSState() { - boolean enabled; - mOverrideDNS.setEnabled(mUsePull.isChecked()); - if(!mUsePull.isChecked()) - enabled =true; - else - enabled = mOverrideDNS.isChecked(); - - mDNS1.setEnabled(enabled); - mDNS2.setEnabled(enabled); - mSearchdomain.setEnabled(enabled); - - - } - - - } \ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java deleted file mode 100644 index 5c70564e..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.EditTextPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceChangeListener; -import android.widget.Toast; - -import java.util.Locale; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; - -public class Settings_Obscure extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { - private CheckBoxPreference mUseRandomHostName; - private CheckBoxPreference mUseFloat; - private CheckBoxPreference mUseCustomConfig; - private EditTextPreference mCustomConfig; - private EditTextPreference mMssFixValue; - private CheckBoxPreference mMssFixCheckBox; - private CheckBoxPreference mPeerInfo; - - private CheckBoxPreference mPersistent; - private ListPreference mConnectRetrymax; - private EditTextPreference mConnectRetry; - private EditTextPreference mConnectRetryMaxTime; - private EditTextPreference mTunMtu; - - public void onCreateBehaviour(Bundle savedInstanceState) { - - mPersistent = (CheckBoxPreference) findPreference("usePersistTun"); - mConnectRetrymax = (ListPreference) findPreference("connectretrymax"); - mConnectRetry = (EditTextPreference) findPreference("connectretry"); - mConnectRetryMaxTime = (EditTextPreference) findPreference("connectretrymaxtime"); - - mPeerInfo = (CheckBoxPreference) findPreference("peerInfo"); - - mConnectRetrymax.setOnPreferenceChangeListener(this); - mConnectRetrymax.setSummary("%s"); - - mConnectRetry.setOnPreferenceChangeListener(this); - mConnectRetryMaxTime.setOnPreferenceChangeListener(this); - - - - } - - protected void loadSettingsBehaviour() { - mPersistent.setChecked(mProfile.mPersistTun); - mPeerInfo.setChecked(mProfile.mPushPeerInfo); - - mConnectRetrymax.setValue(mProfile.mConnectRetryMax); - onPreferenceChange(mConnectRetrymax, mProfile.mConnectRetryMax); - - mConnectRetry.setText(mProfile.mConnectRetry); - onPreferenceChange(mConnectRetry, mProfile.mConnectRetry); - - mConnectRetryMaxTime.setText(mProfile.mConnectRetryMaxTime); - onPreferenceChange(mConnectRetryMaxTime, mProfile.mConnectRetryMaxTime); - - } - - - protected void saveSettingsBehaviour() { - mProfile.mConnectRetryMax = mConnectRetrymax.getValue(); - mProfile.mPersistTun = mPersistent.isChecked(); - mProfile.mConnectRetry = mConnectRetry.getText(); - mProfile.mPushPeerInfo = mPeerInfo.isChecked(); - mProfile.mConnectRetryMaxTime = mConnectRetryMaxTime.getText(); - } - - - public boolean onPreferenceChangeBehaviour(Preference preference, Object newValue) { - if (preference == mConnectRetrymax) { - if(newValue==null) { - newValue="5"; - } - mConnectRetrymax.setDefaultValue(newValue); - - for(int i=0;i< mConnectRetrymax.getEntryValues().length;i++){ - if(mConnectRetrymax.getEntryValues().equals(newValue)) - mConnectRetrymax.setSummary(mConnectRetrymax.getEntries()[i]); - } - - } else if (preference == mConnectRetry) { - if(newValue==null || newValue=="") - newValue="2"; - mConnectRetry.setSummary(String.format("%s s", newValue)); - } else if (preference == mConnectRetryMaxTime) { - if(newValue==null || newValue=="") - newValue="300"; - mConnectRetryMaxTime.setSummary(String.format("%s s", newValue)); - } - - - return true; - } - - - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.vpn_obscure); - - mUseRandomHostName = (CheckBoxPreference) findPreference("useRandomHostname"); - mUseFloat = (CheckBoxPreference) findPreference("useFloat"); - mUseCustomConfig = (CheckBoxPreference) findPreference("enableCustomOptions"); - mCustomConfig = (EditTextPreference) findPreference("customOptions"); - mMssFixCheckBox = (CheckBoxPreference) findPreference("mssFix"); - mMssFixValue = (EditTextPreference) findPreference("mssFixValue"); - mMssFixValue.setOnPreferenceChangeListener(this); - mTunMtu = (EditTextPreference) findPreference("tunmtu"); - mTunMtu.setOnPreferenceChangeListener(this);; - - onCreateBehaviour(savedInstanceState); - loadSettings(); - - } - - protected void loadSettings() { - mUseRandomHostName.setChecked(mProfile.mUseRandomHostname); - mUseFloat.setChecked(mProfile.mUseFloat); - mUseCustomConfig.setChecked(mProfile.mUseCustomConfig); - mCustomConfig.setText(mProfile.mCustomConfigOptions); - - if (mProfile.mMssFix == 0) { - mMssFixValue.setText(String.valueOf(VpnProfile.DEFAULT_MSSFIX_SIZE)); - mMssFixCheckBox.setChecked(false); - setMssSummary(VpnProfile.DEFAULT_MSSFIX_SIZE); - } else { - mMssFixValue.setText(String.valueOf(mProfile.mMssFix)); - mMssFixCheckBox.setChecked(true); - setMssSummary(mProfile.mMssFix); - } - - - int tunmtu = mProfile.mTunMtu; - if (mProfile.mTunMtu < 48) - tunmtu = 1500; - - mTunMtu.setText(String.valueOf(tunmtu)); - setMtuSummary(tunmtu); - - - loadSettingsBehaviour(); - - } - - private void setMssSummary(int value) { - mMssFixValue.setSummary(String.format(Locale.getDefault(),"Configured MSS value: %d", value)); - } - - private void setMtuSummary(int value) { - if (value == 1500) - mTunMtu.setSummary(String.format(Locale.getDefault(),"Using default (1500) MTU", value)); - else - mTunMtu.setSummary(String.format(Locale.getDefault(),"Configured MTU value: %d", value)); - } - - protected void saveSettings() { - mProfile.mUseRandomHostname = mUseRandomHostName.isChecked(); - mProfile.mUseFloat = mUseFloat.isChecked(); - mProfile.mUseCustomConfig = mUseCustomConfig.isChecked(); - mProfile.mCustomConfigOptions = mCustomConfig.getText(); - if (mMssFixCheckBox.isChecked()) - mProfile.mMssFix=Integer.parseInt(mMssFixValue.getText()); - else - mProfile.mMssFix=0; - - mProfile.mTunMtu = Integer.parseInt(mTunMtu.getText()); - saveSettingsBehaviour(); - } - - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (preference.getKey().equals("mssFixValue")) - try { - int v = Integer.parseInt((String) newValue); - if (v < 0 || v > 9000) - throw new NumberFormatException("mssfix value"); - setMssSummary(v); - - } catch(NumberFormatException e) { - Toast.makeText(getActivity(), R.string.mssfix_invalid_value, Toast.LENGTH_LONG).show(); - return false; - } - else if (preference.getKey().equals("tunmtu")) - try { - int v = Integer.parseInt((String) newValue); - if (v < 48 || v > 9000) - throw new NumberFormatException("mtu value"); - setMtuSummary(v); - - } catch(NumberFormatException e) { - Toast.makeText(getActivity(), R.string.mtu_invalid_value, Toast.LENGTH_LONG).show(); - return false; - } - return onPreferenceChangeBehaviour(preference, newValue); - - } - -} \ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Routing.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Routing.java deleted file mode 100644 index 53f88bbf..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Routing.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; -import android.os.Build; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.EditTextPreference; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceChangeListener; -import de.blinkt.openvpn.R; - - -public class Settings_Routing extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { - private EditTextPreference mCustomRoutes; - private CheckBoxPreference mUseDefaultRoute; - private EditTextPreference mCustomRoutesv6; - private CheckBoxPreference mUseDefaultRoutev6; - private CheckBoxPreference mRouteNoPull; - private CheckBoxPreference mLocalVPNAccess; - private EditTextPreference mExcludedRoutes; - private EditTextPreference mExcludedRoutesv6; - private CheckBoxPreference mBlockUnusedAF; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.vpn_routing); - mCustomRoutes = (EditTextPreference) findPreference("customRoutes"); - mUseDefaultRoute = (CheckBoxPreference) findPreference("useDefaultRoute"); - mCustomRoutesv6 = (EditTextPreference) findPreference("customRoutesv6"); - mUseDefaultRoutev6 = (CheckBoxPreference) findPreference("useDefaultRoutev6"); - mExcludedRoutes = (EditTextPreference) findPreference("excludedRoutes"); - mExcludedRoutesv6 = (EditTextPreference) findPreference("excludedRoutesv6"); - - mRouteNoPull = (CheckBoxPreference) findPreference("routenopull"); - mLocalVPNAccess = (CheckBoxPreference) findPreference("unblockLocal"); - - mBlockUnusedAF = (CheckBoxPreference) findPreference("blockUnusedAF"); - - mCustomRoutes.setOnPreferenceChangeListener(this); - mCustomRoutesv6.setOnPreferenceChangeListener(this); - mExcludedRoutes.setOnPreferenceChangeListener(this); - mExcludedRoutesv6.setOnPreferenceChangeListener(this); - mBlockUnusedAF.setOnPreferenceChangeListener(this); - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) - getPreferenceScreen().removePreference(mBlockUnusedAF); - - loadSettings(); - } - - @Override - protected void loadSettings() { - - mUseDefaultRoute.setChecked(mProfile.mUseDefaultRoute); - mUseDefaultRoutev6.setChecked(mProfile.mUseDefaultRoutev6); - - mCustomRoutes.setText(mProfile.mCustomRoutes); - mCustomRoutesv6.setText(mProfile.mCustomRoutesv6); - - mExcludedRoutes.setText(mProfile.mExcludedRoutes); - mExcludedRoutesv6.setText(mProfile.mExcludedRoutesv6); - - mRouteNoPull.setChecked(mProfile.mRoutenopull); - mLocalVPNAccess.setChecked(mProfile.mAllowLocalLAN); - - mBlockUnusedAF.setChecked(mProfile.mBlockUnusedAddressFamilies); - - // Sets Summary - onPreferenceChange(mCustomRoutes, mCustomRoutes.getText()); - onPreferenceChange(mCustomRoutesv6, mCustomRoutesv6.getText()); - onPreferenceChange(mExcludedRoutes, mExcludedRoutes.getText()); - onPreferenceChange(mExcludedRoutesv6, mExcludedRoutesv6.getText()); - - mRouteNoPull.setEnabled(mProfile.mUsePull); - } - - - @Override - protected void saveSettings() { - mProfile.mUseDefaultRoute = mUseDefaultRoute.isChecked(); - mProfile.mUseDefaultRoutev6 = mUseDefaultRoutev6.isChecked(); - mProfile.mCustomRoutes = mCustomRoutes.getText(); - mProfile.mCustomRoutesv6 = mCustomRoutesv6.getText(); - mProfile.mRoutenopull = mRouteNoPull.isChecked(); - mProfile.mAllowLocalLAN =mLocalVPNAccess.isChecked(); - mProfile.mExcludedRoutes = mExcludedRoutes.getText(); - mProfile.mExcludedRoutesv6 = mExcludedRoutesv6.getText(); - mProfile.mBlockUnusedAddressFamilies = mBlockUnusedAF.isChecked(); - } - - @Override - public boolean onPreferenceChange(Preference preference, - Object newValue) { - if( preference == mCustomRoutes || preference == mCustomRoutesv6 - || preference == mExcludedRoutes || preference == mExcludedRoutesv6) - preference.setSummary((String)newValue); - - saveSettings(); - return true; - } - - -} \ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_UserEditable.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_UserEditable.java deleted file mode 100644 index 98ebb55b..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_UserEditable.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2012-2015 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.api.AppRestrictions; - -public class Settings_UserEditable extends KeyChainSettingsFragment implements View.OnClickListener { - - private View mView; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - mView = inflater.inflate(R.layout.settings_usereditable, container, false); - TextView messageView = (TextView) mView.findViewById(R.id.messageUserEdit); - messageView.setText(getString(R.string.message_no_user_edit, getPackageString(mProfile.mProfileCreator))); - initKeychainViews(this.mView); - return mView; - } - - - private String getPackageString(String packageName) { - - if (AppRestrictions.PROFILE_CREATOR.equals(packageName)) - return "Android Enterprise Management"; - - final PackageManager pm = getActivity().getPackageManager(); - ApplicationInfo ai; - try { - ai = pm.getApplicationInfo(packageName, 0); - } catch (final PackageManager.NameNotFoundException e) { - ai = null; - } - final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)"); - return String.format("%s (%s)", applicationName, packageName); - } - - @Override - protected void savePreferences() { - - } - - @Override - public void onResume() { - super.onResume(); - mView.findViewById(R.id.keystore).setVisibility(View.GONE); - if (mProfile.mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE || - mProfile.mAuthenticationType == VpnProfile.TYPE_KEYSTORE) - mView.findViewById(R.id.keystore).setVisibility(View.VISIBLE); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/ShowConfigFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/ShowConfigFragment.java deleted file mode 100644 index e578aeeb..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/ShowConfigFragment.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.app.Fragment; -import android.content.Intent; -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.ViewGroup; -import android.widget.ImageButton; -import android.widget.TextView; -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.ProfileManager; - - -public class ShowConfigFragment extends Fragment { - private String configtext; - private TextView mConfigView; - private ImageButton mfabButton; - - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) - { - View v=inflater.inflate(R.layout.viewconfig, container,false); - mConfigView = (TextView) v.findViewById(R.id.configview); - - - mfabButton = (ImageButton) v.findViewById(R.id.share_config); - if (mfabButton!=null) { - mfabButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - shareConfig(); - } - }); - mfabButton.setVisibility(View.INVISIBLE); - } - return v; - } - - private void startGenConfig(final VpnProfile vp, final TextView cv) { - - new Thread() { - public void run() { - /* Add a few newlines to make the textview scrollable past the FAB */ - try { - - configtext = vp.getConfigFile(getActivity(), VpnProfile.doUseOpenVPN3(getActivity())) + "\n\n\n"; - } catch (Exception e) { - e.printStackTrace(); - configtext = "Error generating config file: " + e.getLocalizedMessage(); - } - getActivity().runOnUiThread(() -> { - cv.setText(configtext); - if (mfabButton!=null) - mfabButton.setVisibility(View.VISIBLE); - }); - - - } - }.start(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) - inflater.inflate(R.menu.configmenu, menu); - } - - private void shareConfig() { - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_TEXT, configtext); - shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.export_config_title)); - shareIntent.setType("text/plain"); - startActivity(Intent.createChooser(shareIntent, getString(R.string.export_config_chooser_title))); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final int itemId = item.getItemId(); - if (itemId == R.id.sendConfig) { - shareConfig(); - return true; - } else { - return super.onOptionsItemSelected(item); - } - } - - @Override - public void onResume() { - super.onResume(); - - populateConfigText(); - } - - private void populateConfigText() { - String profileUUID = getArguments().getString(getActivity().getPackageName() + ".profileUUID"); - final VpnProfile vp = ProfileManager.get(getActivity(),profileUUID); - int check=vp.checkProfile(getActivity()); - - if(check != R.string.no_error_found) { - mConfigView.setText(check); - configtext = getString(check); - } - else { - // Run in own Thread since Keystore does not like to be queried from the main thread - - mConfigView.setText("Generating config..."); - startGenConfig(vp, mConfigView); - } - } - - @Override - public void setUserVisibleHint(boolean visible) - { - super.setUserVisibleHint(visible); - if (visible && isResumed()) - populateConfigText(); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Utils.java b/main/src/main/java/de/blinkt/openvpn/fragments/Utils.java deleted file mode 100644 index abdc45f5..00000000 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Utils.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.database.Cursor; -import android.net.Uri; -import android.os.Build; -import android.provider.OpenableColumns; -import android.util.Base64; -import android.webkit.MimeTypeMap; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.TreeSet; -import java.util.Vector; - -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.Preferences; - -public class Utils { - - - @TargetApi(Build.VERSION_CODES.KITKAT) - public static Intent getFilePickerIntent(Context c, FileType fileType) { - Intent i = new Intent(Intent.ACTION_GET_CONTENT); - i.addCategory(Intent.CATEGORY_OPENABLE); - TreeSet supportedMimeTypes = new TreeSet(); - Vector extensions = new Vector(); - - switch (fileType) { - case PKCS12: - i.setType("application/x-pkcs12"); - supportedMimeTypes.add("application/x-pkcs12"); - extensions.add("p12"); - extensions.add("pfx"); - break; - case CLIENT_CERTIFICATE: - case CA_CERTIFICATE: - i.setType("application/x-pem-file"); - supportedMimeTypes.add("application/x-x509-ca-cert"); - supportedMimeTypes.add("application/x-x509-user-cert"); - supportedMimeTypes.add("application/x-pem-file"); - supportedMimeTypes.add("application/pkix-cert"); - supportedMimeTypes.add("text/plain"); - - extensions.add("pem"); - extensions.add("crt"); - extensions.add("cer"); - break; - case KEYFILE: - i.setType("application/x-pem-file"); - supportedMimeTypes.add("application/x-pem-file"); - supportedMimeTypes.add("application/pkcs8"); - - // Google drive .... - supportedMimeTypes.add("application/x-iwork-keynote-sffkey"); - extensions.add("key"); - break; - - case TLS_AUTH_FILE: - i.setType("text/plain"); - - // Backup .... - supportedMimeTypes.add("application/pkcs8"); - // Google Drive is kind of crazy ..... - supportedMimeTypes.add("application/x-iwork-keynote-sffkey"); - - extensions.add("txt"); - extensions.add("key"); - break; - - case OVPN_CONFIG: - i.setType("application/x-openvpn-profile"); - supportedMimeTypes.add("application/x-openvpn-profile"); - supportedMimeTypes.add("application/openvpn-profile"); - supportedMimeTypes.add("application/ovpn"); - supportedMimeTypes.add("text/plain"); - extensions.add("ovpn"); - extensions.add("conf"); - break; - - case CRL_FILE: - supportedMimeTypes.add("application/x-pkcs7-crl"); - supportedMimeTypes.add("application/pkix-crl"); - extensions.add("crl"); - break; - - case USERPW_FILE: - i.setType("text/plain"); - supportedMimeTypes.add("text/plain"); - break; - } - - MimeTypeMap mtm = MimeTypeMap.getSingleton(); - - for (String ext : extensions) { - String mimeType = mtm.getMimeTypeFromExtension(ext); - if (mimeType != null) - supportedMimeTypes.add(mimeType); - } - - // Always add this as fallback - supportedMimeTypes.add("application/octet-stream"); - - i.putExtra(Intent.EXTRA_MIME_TYPES, supportedMimeTypes.toArray(new String[supportedMimeTypes.size()])); - - // People don't know that this is actually a system setting. Override it ... - // DocumentsContract.EXTRA_SHOW_ADVANCED is hidden - i.putExtra("android.content.extra.SHOW_ADVANCED", true); - - /* Samsung has decided to do something strange, on stock Android GET_CONTENT opens the document UI */ - /* fist try with documentsui */ - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) - i.setPackage("com.android.documentsui"); - - - - - //noinspection ConstantConditions - if (!isIntentAvailable(c,i)) { - i.setAction(Intent.ACTION_OPEN_DOCUMENT); - i.setPackage(null); - - // Check for really broken devices ... :( - if (!isIntentAvailable(c,i)) { - return null; - } - } - - - /* - final PackageManager packageManager = c.getPackageManager(); - ResolveInfo list = packageManager.resolveActivity(i, 0); - - Toast.makeText(c, "Starting package: "+ list.activityInfo.packageName - + "with ACTION " + i.getAction(), Toast.LENGTH_LONG).show(); - - */ - return i; - } - - public static boolean alwaysUseOldFileChooser(Context c) - { - /* Android P does not allow access to the file storage anymore */ - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) - return false; - - SharedPreferences prefs = Preferences.getDefaultSharedPreferences(c); - return prefs.getBoolean("useInternalFileSelector", false); - } - - public static boolean isIntentAvailable(Context context, Intent i) { - final PackageManager packageManager = context.getPackageManager(); - List list = - packageManager.queryIntentActivities(i, - PackageManager.MATCH_DEFAULT_ONLY); - - // Ignore the Android TV framework app in the list - int size = list.size(); - for (ResolveInfo ri: list) - { - // Ignore stub apps - if ("com.google.android.tv.frameworkpackagestubs".equals(ri.activityInfo.packageName)) - { - size--; - } - } - - return size > 0; - } - - - public enum FileType { - PKCS12(0), - CLIENT_CERTIFICATE(1), - CA_CERTIFICATE(2), - OVPN_CONFIG(3), - KEYFILE(4), - TLS_AUTH_FILE(5), - USERPW_FILE(6), - CRL_FILE(7); - - private int value; - - FileType(int i) { - value = i; - } - - public static FileType getFileTypeByValue(int value) { - switch (value) { - case 0: - return PKCS12; - case 1: - return CLIENT_CERTIFICATE; - case 2: - return CA_CERTIFICATE; - case 3: - return OVPN_CONFIG; - case 4: - return KEYFILE; - case 5: - return TLS_AUTH_FILE; - case 6: - return USERPW_FILE; - case 7: - return CRL_FILE; - default: - return null; - } - } - - public int getValue() { - return value; - } - } - - static private byte[] readBytesFromStream(InputStream input) throws IOException { - - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - int nRead; - byte[] data = new byte[16384]; - - ; - - long totalread = 0; - while ((nRead = input.read(data, 0, data.length)) != -1 && totalread { - - public VPNArrayAdapter(Context context, int resource, - int textViewResourceId) { - super(context, resource, textViewResourceId); - } - - @Override - public View getView(final int position, View convertView, ViewGroup parent) { - View v = super.getView(position, convertView, parent); - - final VpnProfile profile = (VpnProfile) getListAdapter().getItem(position); - - View titleview = v.findViewById(R.id.vpn_list_item_left); - titleview.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - startOrStopVPN(profile); - } - }); - - View settingsview = v.findViewById(R.id.quickedit_settings); - settingsview.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - editVPN(profile); - - } - }); - - TextView subtitle = (TextView) v.findViewById(R.id.vpn_item_subtitle); - if (profile.getUUIDString().equals(VpnStatus.getLastConnectedVPNProfile())) { - subtitle.setText(mLastStatusMessage); - subtitle.setVisibility(View.VISIBLE); - } else { - subtitle.setText(""); - subtitle.setVisibility(View.GONE); - } - - - return v; - } - } - - private void startOrStopVPN(VpnProfile profile) { - if (VpnStatus.isVPNActive() && profile.getUUIDString().equals(VpnStatus.getLastConnectedVPNProfile())) { - Intent disconnectVPN = new Intent(getActivity(), DisconnectVPN.class); - startActivity(disconnectVPN); - } else { - startVPN(profile); - } - } - - - private ArrayAdapter mArrayadapter; - - protected VpnProfile mEditProfile = null; - - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - - // Shortcut version is increased to refresh all shortcuts - final static int SHORTCUT_VERSION = 1; - - @RequiresApi(api = Build.VERSION_CODES.N_MR1) - void updateDynamicShortcuts() { - PersistableBundle versionExtras = new PersistableBundle(); - versionExtras.putInt("version", SHORTCUT_VERSION); - - ShortcutManager shortcutManager = getContext().getSystemService(ShortcutManager.class); - if (shortcutManager.isRateLimitingActive()) - return; - - List shortcuts = shortcutManager.getDynamicShortcuts(); - int maxvpn = shortcutManager.getMaxShortcutCountPerActivity() - 1; - - - ShortcutInfo disconnectShortcut = new ShortcutInfo.Builder(getContext(), "disconnectVPN") - .setShortLabel("Disconnect") - .setLongLabel("Disconnect VPN") - .setIntent(new Intent(getContext(), DisconnectVPN.class).setAction(DISCONNECT_VPN)) - .setIcon(Icon.createWithResource(getContext(), R.drawable.ic_shortcut_cancel)) - .setExtras(versionExtras) - .build(); - - LinkedList newShortcuts = new LinkedList<>(); - LinkedList updateShortcuts = new LinkedList<>(); - - LinkedList removeShortcuts = new LinkedList<>(); - LinkedList disableShortcuts = new LinkedList<>(); - - boolean addDisconnect = true; - - - TreeSet sortedProfilesLRU = new TreeSet(new VpnProfileLRUComparator()); - ProfileManager profileManager = ProfileManager.getInstance(getContext()); - sortedProfilesLRU.addAll(profileManager.getProfiles()); - - LinkedList LRUProfiles = new LinkedList<>(); - maxvpn = Math.min(maxvpn, sortedProfilesLRU.size()); - - for (int i = 0; i < maxvpn; i++) { - LRUProfiles.add(sortedProfilesLRU.pollFirst()); - } - - for (ShortcutInfo shortcut : shortcuts) { - if (shortcut.getId().equals("disconnectVPN")) { - addDisconnect = false; - if (shortcut.getExtras() == null - || shortcut.getExtras().getInt("version") != SHORTCUT_VERSION) - updateShortcuts.add(disconnectShortcut); - - } else { - VpnProfile p = ProfileManager.get(getContext(), shortcut.getId()); - if (p == null || p.profileDeleted) { - if (shortcut.isEnabled()) { - disableShortcuts.add(shortcut.getId()); - removeShortcuts.add(shortcut.getId()); - } - if (!shortcut.isPinned()) - removeShortcuts.add(shortcut.getId()); - } else { - - if (LRUProfiles.contains(p)) - LRUProfiles.remove(p); - else - removeShortcuts.add(p.getUUIDString()); - - if (!p.getName().equals(shortcut.getShortLabel()) - || shortcut.getExtras() == null - || shortcut.getExtras().getInt("version") != SHORTCUT_VERSION) - updateShortcuts.add(createShortcut(p)); - - - } - - } - - } - if (addDisconnect) - newShortcuts.add(disconnectShortcut); - for (VpnProfile p : LRUProfiles) - newShortcuts.add(createShortcut(p)); - - if (updateShortcuts.size() > 0) - shortcutManager.updateShortcuts(updateShortcuts); - if (removeShortcuts.size() > 0) - shortcutManager.removeDynamicShortcuts(removeShortcuts); - if (newShortcuts.size() > 0) - shortcutManager.addDynamicShortcuts(newShortcuts); - if (disableShortcuts.size() > 0) - shortcutManager.disableShortcuts(disableShortcuts, "VpnProfile does not exist anymore."); - } - - @RequiresApi(Build.VERSION_CODES.N_MR1) - ShortcutInfo createShortcut(VpnProfile profile) { - Intent shortcutIntent = new Intent(Intent.ACTION_MAIN); - shortcutIntent.setClass(getActivity(), LaunchVPN.class); - shortcutIntent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUID().toString()); - shortcutIntent.setAction(Intent.ACTION_MAIN); - shortcutIntent.putExtra("EXTRA_HIDELOG", true); - - PersistableBundle versionExtras = new PersistableBundle(); - versionExtras.putInt("version", SHORTCUT_VERSION); - - return new ShortcutInfo.Builder(getContext(), profile.getUUIDString()) - .setShortLabel(profile.getName()) - .setLongLabel(getString(R.string.qs_connect, profile.getName())) - .setIcon(Icon.createWithResource(getContext(), R.drawable.ic_shortcut_vpn_key)) - .setIntent(shortcutIntent) - .setExtras(versionExtras) - .build(); - } - - class MiniImageGetter implements ImageGetter { - - - @Override - public Drawable getDrawable(String source) { - Drawable d = null; - if ("ic_menu_add".equals(source)) - d = getActivity().getResources().getDrawable(R.drawable.ic_menu_add_grey); - else if ("ic_menu_archive".equals(source)) - d = getActivity().getResources().getDrawable(R.drawable.ic_menu_import_grey); - - - if (d != null) { - d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); - return d; - } else { - return null; - } - } - } - - - @Override - public void onResume() { - super.onResume(); - setListAdapter(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { - updateDynamicShortcuts(); - } - VpnStatus.addStateListener(this); - } - - @Override - public void onPause() { - super.onPause(); - VpnStatus.removeStateListener(this); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.vpn_profile_list, container, false); - - TextView newvpntext = (TextView) v.findViewById(R.id.add_new_vpn_hint); - TextView importvpntext = (TextView) v.findViewById(R.id.import_vpn_hint); - - newvpntext.setText(Html.fromHtml(getString(R.string.add_new_vpn_hint), new MiniImageGetter(), null)); - importvpntext.setText(Html.fromHtml(getString(R.string.vpn_import_hint), new MiniImageGetter(), null)); - - ImageButton fab_add = (ImageButton) v.findViewById(R.id.fab_add); - ImageButton fab_import = (ImageButton) v.findViewById(R.id.fab_import); - if (fab_add != null) - fab_add.setOnClickListener(this); - - if (fab_import != null) - fab_import.setOnClickListener(this); - - return v; - - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - setListAdapter(); - } - - static class VpnProfileNameComparator implements Comparator { - - @Override - public int compare(VpnProfile lhs, VpnProfile rhs) { - if (lhs == rhs) - // Catches also both null - return 0; - - if (lhs == null) - return -1; - if (rhs == null) - return 1; - - if (lhs.mName == null) - return -1; - if (rhs.mName == null) - return 1; - - return lhs.mName.compareTo(rhs.mName); - } - - } - - static class VpnProfileLRUComparator implements Comparator { - - VpnProfileNameComparator nameComparator = new VpnProfileNameComparator(); - - @Override - public int compare(VpnProfile lhs, VpnProfile rhs) { - if (lhs == rhs) - // Catches also both null - return 0; - - if (lhs == null) - return -1; - if (rhs == null) - return 1; - - // Copied from Long.compare - if (lhs.mLastUsed > rhs.mLastUsed) - return -1; - if (lhs.mLastUsed < rhs.mLastUsed) - return 1; - else - return nameComparator.compare(lhs, rhs); - } - } - - - private void setListAdapter() { - if (mArrayadapter == null) { - mArrayadapter = new VPNArrayAdapter(getActivity(), R.layout.vpn_list_item, R.id.vpn_item_title); - - } - populateVpnList(); - } - - private void populateVpnList() { - boolean sortByLRU = Preferences.getDefaultSharedPreferences(getActivity()).getBoolean(PREF_SORT_BY_LRU, false); - Collection allvpn = getPM().getProfiles(); - TreeSet sortedset; - if (sortByLRU) - sortedset = new TreeSet<>(new VpnProfileLRUComparator()); - else - sortedset = new TreeSet<>(new VpnProfileNameComparator()); - - sortedset.addAll(allvpn); - mArrayadapter.clear(); - mArrayadapter.addAll(sortedset); - - setListAdapter(mArrayadapter); - mArrayadapter.notifyDataSetChanged(); - } - - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - menu.add(0, MENU_ADD_PROFILE, 0, R.string.menu_add_profile) - .setIcon(R.drawable.ic_menu_add) - .setAlphabeticShortcut('a') - .setTitleCondensed(getActivity().getString(R.string.add)) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - - menu.add(0, MENU_IMPORT_PROFILE, 0, R.string.menu_import) - .setIcon(R.drawable.ic_menu_import) - .setAlphabeticShortcut('i') - .setTitleCondensed(getActivity().getString(R.string.menu_import_short)) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - - menu.add(0, MENU_CHANGE_SORTING, 0, R.string.change_sorting) - .setIcon(R.drawable.ic_sort) - .setAlphabeticShortcut('s') - .setTitleCondensed(getString(R.string.sort)) - .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM); - - } - - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final int itemId = item.getItemId(); - if (itemId == MENU_ADD_PROFILE) { - onAddOrDuplicateProfile(null); - return true; - } else if (itemId == MENU_IMPORT_PROFILE) { - return startImportConfigFilePicker(); - } else if (itemId == MENU_CHANGE_SORTING) { - return changeSorting(); - } else { - return super.onOptionsItemSelected(item); - } - } - - private boolean changeSorting() { - SharedPreferences prefs = Preferences.getDefaultSharedPreferences(getActivity()); - boolean oldValue = prefs.getBoolean(PREF_SORT_BY_LRU, false); - SharedPreferences.Editor prefsedit = prefs.edit(); - if (oldValue) { - Toast.makeText(getActivity(), R.string.sorted_az, Toast.LENGTH_SHORT).show(); - prefsedit.putBoolean(PREF_SORT_BY_LRU, false); - } else { - prefsedit.putBoolean(PREF_SORT_BY_LRU, true); - Toast.makeText(getActivity(), R.string.sorted_lru, Toast.LENGTH_SHORT).show(); - } - prefsedit.apply(); - populateVpnList(); - return true; - } - - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.fab_import: - startImportConfigFilePicker(); - break; - case R.id.fab_add: - onAddOrDuplicateProfile(null); - break; - } - } - - private boolean startImportConfigFilePicker() { - boolean startOldFileDialog = true; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && !Utils.alwaysUseOldFileChooser(getActivity() )) - startOldFileDialog = !startFilePicker(); - - if (startOldFileDialog) - startImportConfig(); - - return true; - } - - @TargetApi(Build.VERSION_CODES.KITKAT) - private boolean startFilePicker() { - - Intent i = Utils.getFilePickerIntent(getActivity(), Utils.FileType.OVPN_CONFIG); - if (i != null) { - startActivityForResult(i, FILE_PICKER_RESULT_KITKAT); - return true; - } else - return false; - } - - private void startImportConfig() { - Intent intent = new Intent(getActivity(), FileSelect.class); - intent.putExtra(FileSelect.NO_INLINE_SELECTION, true); - intent.putExtra(FileSelect.WINDOW_TITLE, R.string.import_configuration_file); - startActivityForResult(intent, SELECT_PROFILE); - } - - - private void onAddOrDuplicateProfile(final VpnProfile mCopyProfile) { - Context context = getActivity(); - if (context != null) { - final EditText entry = new EditText(context); - entry.setSingleLine(); - - AlertDialog.Builder dialog = new AlertDialog.Builder(context); - if (mCopyProfile == null) - dialog.setTitle(R.string.menu_add_profile); - else { - dialog.setTitle(context.getString(R.string.duplicate_profile_title, mCopyProfile.mName)); - entry.setText(getString(R.string.copy_of_profile, mCopyProfile.mName)); - } - - dialog.setMessage(R.string.add_profile_name_prompt); - dialog.setView(entry); - - dialog.setNeutralButton(R.string.menu_import_short, - (dialog1, which) -> startImportConfigFilePicker()); - dialog.setPositiveButton(android.R.string.ok, - (dialog12, which) -> { - String name = entry.getText().toString(); - if (getPM().getProfileByName(name) == null) { - VpnProfile profile; - if (mCopyProfile != null) { - profile = mCopyProfile.copy(name); - // Remove restrictions on copy profile - profile.mProfileCreator = null; - profile.mUserEditable = true; - } else - profile = new VpnProfile(name); - - addProfile(profile); - editVPN(profile); - } else { - Toast.makeText(getActivity(), R.string.duplicate_profile_name, Toast.LENGTH_LONG).show(); - } - }); - dialog.setNegativeButton(android.R.string.cancel, null); - dialog.create().show(); - } - - } - - private void addProfile(VpnProfile profile) { - getPM().addProfile(profile); - getPM().saveProfileList(getActivity()); - getPM().saveProfile(getActivity(), profile); - mArrayadapter.add(profile); - } - - private ProfileManager getPM() { - return ProfileManager.getInstance(getActivity()); - } - - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - if (resultCode == RESULT_VPN_DELETED) { - if (mArrayadapter != null && mEditProfile != null) - mArrayadapter.remove(mEditProfile); - } else if (resultCode == RESULT_VPN_DUPLICATE && data != null) { - String profileUUID = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); - VpnProfile profile = ProfileManager.get(getActivity(), profileUUID); - if (profile != null) - onAddOrDuplicateProfile(profile); - } - - - if (resultCode != Activity.RESULT_OK) - return; - - - if (requestCode == START_VPN_CONFIG) { - String configuredVPN = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); - - VpnProfile profile = ProfileManager.get(getActivity(), configuredVPN); - getPM().saveProfile(getActivity(), profile); - // Name could be modified, reset List adapter - setListAdapter(); - - } else if (requestCode == SELECT_PROFILE) { - String fileData = data.getStringExtra(FileSelect.RESULT_DATA); - Uri uri = new Uri.Builder().path(fileData).scheme("file").build(); - - startConfigImport(uri); - } else if (requestCode == IMPORT_PROFILE) { - String profileUUID = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); - mArrayadapter.add(ProfileManager.get(getActivity(), profileUUID)); - } else if (requestCode == FILE_PICKER_RESULT_KITKAT) { - if (data != null) { - Uri uri = data.getData(); - startConfigImport(uri); - } - } - - } - - private void startConfigImport(Uri uri) { - Intent startImport = new Intent(getActivity(), ConfigConverter.class); - startImport.setAction(ConfigConverter.IMPORT_PROFILE); - startImport.setData(uri); - startActivityForResult(startImport, IMPORT_PROFILE); - } - - - private void editVPN(VpnProfile profile) { - mEditProfile = profile; - Intent vprefintent = new Intent(getActivity(), VPNPreferences.class) - .putExtra(getActivity().getPackageName() + ".profileUUID", profile.getUUID().toString()); - - startActivityForResult(vprefintent, START_VPN_CONFIG); - } - - private void startVPN(VpnProfile profile) { - - getPM().saveProfile(getActivity(), profile); - - Intent intent = new Intent(getActivity(), LaunchVPN.class); - intent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUID().toString()); - intent.setAction(Intent.ACTION_MAIN); - startActivity(intent); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/views/DefaultVPNListPreference.java b/main/src/main/java/de/blinkt/openvpn/views/DefaultVPNListPreference.java deleted file mode 100644 index e8328f5c..00000000 --- a/main/src/main/java/de/blinkt/openvpn/views/DefaultVPNListPreference.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2012-2018 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.views; - -import android.content.Context; -import android.preference.ListPreference; -import android.util.AttributeSet; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.ProfileManager; - -import java.util.Collection; - -public class DefaultVPNListPreference extends ListPreference { - public DefaultVPNListPreference(Context context, AttributeSet attrs) { - super(context, attrs); - setVPNs(context); - } - - private void setVPNs(Context c) { - ProfileManager pm = ProfileManager.getInstance(c); - Collection profiles = pm.getProfiles(); - CharSequence[] entries = new CharSequence[profiles.size()]; - CharSequence[] entryValues = new CharSequence[profiles.size()];; - - int i=0; - for (VpnProfile p: profiles) - { - entries[i]=p.getName(); - entryValues[i]=p.getUUIDString(); - i++; - } - - setEntries(entries); - setEntryValues(entryValues); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/views/FileSelectLayout.java b/main/src/main/java/de/blinkt/openvpn/views/FileSelectLayout.java deleted file mode 100644 index bc3bd5cd..00000000 --- a/main/src/main/java/de/blinkt/openvpn/views/FileSelectLayout.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.views; - -import android.content.Context; -import android.content.Intent; -import android.content.res.TypedArray; -import android.util.AttributeSet; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.TextView; - -import java.io.IOException; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.activities.FileSelect; -import de.blinkt.openvpn.core.VpnStatus; -import de.blinkt.openvpn.core.X509Utils; -import de.blinkt.openvpn.fragments.Utils; - -import static android.os.Build.VERSION; -import static android.os.Build.VERSION_CODES; - - -public class FileSelectLayout extends LinearLayout implements OnClickListener { - - - public void parseResponse(Intent data, Context c) { - - try { - String newData = Utils.getFilePickerResult(fileType, data, c); - if (newData!=null) - setData(newData, c); - - if (newData == null) { - String fileData = data.getStringExtra(FileSelect.RESULT_DATA); - setData(fileData, c); - } - - } catch (IOException | SecurityException e) { - VpnStatus.logException(e); - } - } - - public interface FileSelectCallback { - - String getString(int res); - - void startActivityForResult(Intent startFC, int mTaskId); - } - - private boolean mIsCertificate; - private TextView mDataView; - private String mData; - private FileSelectCallback mFragment; - private int mTaskId; - private Button mSelectButton; - private Utils.FileType fileType; - private String mTitle; - private boolean mShowClear; - private TextView mDataDetails; - private Button mShowClearButton; - - - public FileSelectLayout(Context context, AttributeSet attrset) { - super(context, attrset); - - TypedArray ta = context.obtainStyledAttributes(attrset, R.styleable.FileSelectLayout); - - setupViews(ta.getString(R.styleable.FileSelectLayout_fileTitle), ta.getBoolean(R.styleable.FileSelectLayout_certificate, true) - ); - - ta.recycle(); - } - - public FileSelectLayout (Context context, String title, boolean isCertificate, boolean showClear) - { - super(context); - - setupViews(title, isCertificate); - mShowClear = showClear; - - } - - private void setupViews(String title, boolean isCertificate) { - inflate(getContext(), R.layout.file_select, this); - - mTitle = title; - mIsCertificate = isCertificate; - - TextView tView = (TextView) findViewById(R.id.file_title); - tView.setText(mTitle); - - mDataView = (TextView) findViewById(R.id.file_selected_item); - mDataDetails = (TextView) findViewById(R.id.file_selected_description); - mSelectButton = (Button) findViewById(R.id.file_select_button); - mSelectButton.setOnClickListener(this); - - mShowClearButton = (Button) findViewById(R.id.file_clear_button); - mShowClearButton.setOnClickListener(this); - } - - public void setClearable(boolean clearable) - { - mShowClear = clearable; - if (mShowClearButton != null && mData !=null) - mShowClearButton.setVisibility(mShowClear? VISIBLE : GONE); - - } - - - public void setCaller(FileSelectCallback fragment, int i, Utils.FileType ft) { - mTaskId = i; - mFragment = fragment; - fileType = ft; - } - - public void getCertificateFileDialog() { - Intent startFC = new Intent(getContext(), FileSelect.class); - startFC.putExtra(FileSelect.START_DATA, mData); - startFC.putExtra(FileSelect.WINDOW_TITLE, mTitle); - if (fileType == Utils.FileType.PKCS12) - startFC.putExtra(FileSelect.DO_BASE64_ENCODE, true); - if (mShowClear) - startFC.putExtra(FileSelect.SHOW_CLEAR_BUTTON, true); - - mFragment.startActivityForResult(startFC, mTaskId); - } - - - public String getData() { - return mData; - } - - public void setData(String data, Context c) { - mData = data; - if (data == null) { - mDataView.setText(c.getString(R.string.no_data)); - mDataDetails.setText(""); - mShowClearButton.setVisibility(GONE); - } else { - if (mData.startsWith(VpnProfile.DISPLAYNAME_TAG)) { - mDataView.setText(c.getString(R.string.imported_from_file, VpnProfile.getDisplayName(mData))); - } else if (mData.startsWith(VpnProfile.INLINE_TAG)) - mDataView.setText(R.string.inline_file_data); - else - mDataView.setText(data); - if (mIsCertificate) { - mDataDetails.setText(X509Utils.getCertificateFriendlyName(c, data)); - } - - // Show clear button if it should be shown - mShowClearButton.setVisibility(mShowClear? VISIBLE : GONE); - } - - } - - @Override - public void onClick(View v) { - if (v == mSelectButton) { - Intent startFilePicker=null; - if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { - startFilePicker = Utils.getFilePickerIntent(getContext(), fileType); - } - - if (startFilePicker == null || Utils.alwaysUseOldFileChooser(v.getContext())) { - getCertificateFileDialog(); - } else { - mFragment.startActivityForResult(startFilePicker, mTaskId); - } - } else if (v == mShowClearButton) { - setData(null, getContext()); - } - } - - - - - public void setShowClear() { - mShowClear = true; - } - -} diff --git a/main/src/main/java/de/blinkt/openvpn/views/MultiLineRadioGroup.java b/main/src/main/java/de/blinkt/openvpn/views/MultiLineRadioGroup.java deleted file mode 100644 index 8296a644..00000000 --- a/main/src/main/java/de/blinkt/openvpn/views/MultiLineRadioGroup.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2012-2018 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.views; - -import android.content.Context; -import android.graphics.Rect; -import android.util.AttributeSet; -import android.view.View; -import android.widget.RadioGroup; - -import java.util.HashMap; -import java.util.Map; - -public class MultiLineRadioGroup extends RadioGroup { - private Map viewRectMap; - - public MultiLineRadioGroup(Context context) { - this(context, null); - } - - public MultiLineRadioGroup(Context context, AttributeSet attrs) { - super(context, attrs); - - viewRectMap = new HashMap(); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ - int widthMeasurement = MeasureSpec.getSize(widthMeasureSpec); - int heightMeasurement = MeasureSpec.getSize(heightMeasureSpec); - switch (getOrientation()){ - case HORIZONTAL: - heightMeasurement = findHorizontalHeight(widthMeasureSpec, heightMeasureSpec); - break; - case VERTICAL: - widthMeasurement = findVerticalWidth(widthMeasureSpec, heightMeasureSpec); - break; - } - setMeasuredDimension(widthMeasurement, heightMeasurement); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - int count = getChildCount(); - for(int x=0; x < count; ++x) { - View button = getChildAt(x); - Rect dims = viewRectMap.get(button); - button.layout(dims.left, dims.top, dims.right, dims.bottom); - } - } - - private int findHorizontalHeight(int widthMeasureSpec, int heightMeasureSpec){ - int parentHeight = MeasureSpec.getSize(heightMeasureSpec); - int maxRight = MeasureSpec.getSize(widthMeasureSpec) - getPaddingRight(); - - // create MeasureSpecs to accommodate max space that RadioButtons can occupy - int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(maxRight - getPaddingLeft(), - MeasureSpec.getMode(widthMeasureSpec)); - int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec( - parentHeight - (getPaddingTop() + getPaddingBottom()), - MeasureSpec.getMode(heightMeasureSpec)); - - int nextLeft = getPaddingLeft(); - int nextTop = getPaddingTop(); - int maxRowHeight = 0; - viewRectMap.clear(); - // measure and find placement for each RadioButton (results to be used in onLayout() stage) - int count = getChildCount(); - for(int x=0; x < count; ++x){ - View button = getChildAt(x); - measureChild(button, newWidthMeasureSpec, newHeightMeasureSpec); - - maxRowHeight = Math.max(maxRowHeight, button.getMeasuredHeight()); - - // determine RadioButton placement - int nextRight = nextLeft + button.getMeasuredWidth(); - if(nextRight > maxRight){ // if current button will exceed border on this row ... - // ... move to next row - nextLeft = getPaddingLeft(); - nextTop += maxRowHeight; - - // adjust for next row values - nextRight = nextLeft + button.getMeasuredWidth(); - maxRowHeight = button.getMeasuredHeight(); - } - - int nextBottom = nextTop + button.getMeasuredHeight(); - viewRectMap.put(button, new Rect(nextLeft, nextTop, nextRight, nextBottom)); - - // update nextLeft - nextLeft = nextRight; - } - - // height of RadioGroup is a natural by-product of placing all the children - int idealHeight = nextTop + maxRowHeight + getPaddingBottom(); - switch(MeasureSpec.getMode(heightMeasureSpec)){ - case MeasureSpec.UNSPECIFIED: - return idealHeight; - case MeasureSpec.AT_MOST: - return Math.min(idealHeight, parentHeight); - case MeasureSpec.EXACTLY: - default: - return parentHeight; - } - } - - private int findVerticalWidth(int widthMeasureSpec, int heightMeasureSpec){ - int parentWidth = MeasureSpec.getSize(widthMeasureSpec); - int maxBottom = MeasureSpec.getSize(heightMeasureSpec) - getPaddingBottom(); - - // create MeasureSpecs to accommodate max space that RadioButtons can occupy - int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec( - parentWidth - (getPaddingLeft() + getPaddingRight()), - MeasureSpec.getMode(widthMeasureSpec)); - int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(maxBottom - getPaddingTop(), - MeasureSpec.getMode(heightMeasureSpec)); - - int nextTop = getPaddingTop(); - int nextLeft = getPaddingLeft(); - int maxColWidth = 0; - viewRectMap.clear(); - // measure and find placement for each RadioButton (results to be used in onLayout() stage) - int count = getChildCount(); - for(int x=0; x < count; ++x){ - View button = getChildAt(x); - measureChild(button, newWidthMeasureSpec, newHeightMeasureSpec); - - maxColWidth = Math.max(maxColWidth, button.getMeasuredWidth()); - - // determine RadioButton placement - int nextBottom = nextTop + button.getMeasuredHeight(); - if(nextBottom > maxBottom){ // if current button will exceed border for this column ... - // ... move to next column - nextTop = getPaddingTop(); - nextLeft += maxColWidth; - - // adjust for next row values - nextBottom = nextTop + button.getMeasuredHeight(); - maxColWidth = button.getMeasuredWidth(); - } - - int nextRight = nextLeft + button.getMeasuredWidth(); - viewRectMap.put(button, new Rect(nextLeft, nextTop, nextRight, nextBottom)); - - // update nextTop - nextTop = nextBottom; - } - - // width of RadioGroup is a natural by-product of placing all the children - int idealWidth = nextLeft + maxColWidth + getPaddingRight(); - switch(MeasureSpec.getMode(widthMeasureSpec)){ - case MeasureSpec.UNSPECIFIED: - return idealWidth; - case MeasureSpec.AT_MOST: - return Math.min(idealWidth, parentWidth); - case MeasureSpec.EXACTLY: - default: - return parentWidth; - } - } -} \ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/views/PagerSlidingTabStrip.java b/main/src/main/java/de/blinkt/openvpn/views/PagerSlidingTabStrip.java deleted file mode 100644 index ab8598c6..00000000 --- a/main/src/main/java/de/blinkt/openvpn/views/PagerSlidingTabStrip.java +++ /dev/null @@ -1,732 +0,0 @@ -/* - * Copyright (C) 2013 Andreas Stuetz - * - * 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 de.blinkt.openvpn.views; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.res.ColorStateList; -import android.content.res.TypedArray; -import android.database.DataSetObserver; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.Typeface; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.support.v4.view.ViewCompat; -import android.support.v4n.view.ViewPager; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.Pair; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; -import android.widget.HorizontalScrollView; -import android.widget.LinearLayout; -import android.widget.TextView; - - -import java.util.Locale; - -import de.blinkt.openvpn.R; - -public class PagerSlidingTabStrip extends HorizontalScrollView implements TabBarView { - - private static final float OPAQUE = 1.0f; - private static final float HALF_TRANSP = 0.5f; - - public interface CustomTabProvider { - public View getCustomTabView(ViewGroup parent, int position); - } - - // @formatter:off - private static final int[] ATTRS = new int[]{ - android.R.attr.textSize, - android.R.attr.textColor, - android.R.attr.paddingLeft, - android.R.attr.paddingRight, - }; - // @formatter:on - - private final PagerAdapterObserver adapterObserver = new PagerAdapterObserver(); - - //These indexes must be related with the ATTR array above - private static final int TEXT_SIZE_INDEX = 0; - private static final int TEXT_COLOR_INDEX = 1; - private static final int PADDING_LEFT_INDEX = 2; - private static final int PADDING_RIGHT_INDEX = 3; - - private LinearLayout.LayoutParams defaultTabLayoutParams; - private LinearLayout.LayoutParams expandedTabLayoutParams; - - private final PageListener pageListener = new PageListener(); - public ViewPager.OnPageChangeListener delegatePageListener; - - private LinearLayout tabsContainer; - private ViewPager pager; - - private int tabCount; - - private int currentPosition = 0; - private float currentPositionOffset = 0f; - - private Paint rectPaint; - private Paint dividerPaint; - - private int indicatorColor; - private int indicatorHeight = 2; - - private int underlineHeight = 0; - private int underlineColor; - - private int dividerWidth = 0; - private int dividerPadding = 0; - private int dividerColor; - - private int tabPadding = 12; - private int tabTextSize = 14; - private ColorStateList tabTextColor = null; - private float tabTextAlpha = HALF_TRANSP; - private float tabTextSelectedAlpha = OPAQUE; - - private int paddingLeft = 0; - private int paddingRight = 0; - - private boolean shouldExpand = false; - private boolean textAllCaps = true; - private boolean isPaddingMiddle = false; - - private Typeface tabTypeface = null; - private int tabTypefaceStyle = Typeface.BOLD; - private int tabTypefaceSelectedStyle = Typeface.BOLD; - - private int scrollOffset; - private int lastScrollX = 0; - - private int tabBackgroundResId = R.drawable.slidingtab_background; - - private Locale locale; - - public PagerSlidingTabStrip(Context context) { - this(context, null); - } - - public PagerSlidingTabStrip(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setFillViewport(true); - setWillNotDraw(false); - tabsContainer = new LinearLayout(context); - tabsContainer.setOrientation(LinearLayout.HORIZONTAL); - tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - addView(tabsContainer); - - //Default color will be 'textColorPrimary' - int colorPrimary = context.getResources().getColor(android.R.color.primary_text_dark); - setTextColor(colorPrimary); - underlineColor = colorPrimary; - dividerColor = colorPrimary; - indicatorColor = colorPrimary; - - - DisplayMetrics dm = getResources().getDisplayMetrics(); - scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm); - indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm); - underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm); - dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm); - tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm); - dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm); - tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm); - - // get system attrs (android:textSize and android:textColor) - TypedArray a = context.obtainStyledAttributes(attrs, ATTRS); - tabTextSize = a.getDimensionPixelSize(TEXT_SIZE_INDEX, tabTextSize); - ColorStateList colorStateList = a.getColorStateList(TEXT_COLOR_INDEX); - if (colorStateList != null) { - tabTextColor = colorStateList; - } - paddingLeft = a.getDimensionPixelSize(PADDING_LEFT_INDEX, paddingLeft); - paddingRight = a.getDimensionPixelSize(PADDING_RIGHT_INDEX, paddingRight); - a.recycle(); - - //In case we have the padding they must be equal so we take the biggest - if (paddingRight < paddingLeft) { - paddingRight = paddingLeft; - } - - if (paddingLeft < paddingRight) { - paddingLeft = paddingRight; - } - - // get custom attrs - a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip); - indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor); - underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor); - dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor); - dividerWidth = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerWidth, dividerWidth); - indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight); - underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight); - dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding); - tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding); - tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId); - shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand); - scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset); - textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps); - isPaddingMiddle = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsPaddingMiddle, isPaddingMiddle); - tabTypefaceStyle = a.getInt(R.styleable.PagerSlidingTabStrip_pstsTextStyle, Typeface.BOLD); - tabTypefaceSelectedStyle = a.getInt(R.styleable.PagerSlidingTabStrip_pstsTextSelectedStyle, Typeface.BOLD); - tabTextAlpha = a.getFloat(R.styleable.PagerSlidingTabStrip_pstsTextAlpha, HALF_TRANSP); - tabTextSelectedAlpha = a.getFloat(R.styleable.PagerSlidingTabStrip_pstsTextSelectedAlpha, OPAQUE); - a.recycle(); - - rectPaint = new Paint(); - rectPaint.setAntiAlias(true); - rectPaint.setStyle(Style.FILL); - - - dividerPaint = new Paint(); - dividerPaint.setAntiAlias(true); - dividerPaint.setStrokeWidth(dividerWidth); - - defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f); - - if (locale == null) { - locale = getResources().getConfiguration().locale; - } - } - - public void setViewPager(ViewPager pager) { - this.pager = pager; - if (pager.getAdapter() == null) { - throw new IllegalStateException("ViewPager does not have adapter instance."); - } - - pager.setOnPageChangeListener(pageListener); - pager.getAdapter().registerDataSetObserver(adapterObserver); - adapterObserver.setAttached(true); - notifyDataSetChanged(); - } - - public void notifyDataSetChanged() { - tabsContainer.removeAllViews(); - tabCount = pager.getAdapter().getCount(); - View tabView; - for (int i = 0; i < tabCount; i++) { - - if (pager.getAdapter() instanceof CustomTabProvider) { - tabView = ((CustomTabProvider) pager.getAdapter()).getCustomTabView(this, i); - } else { - tabView = LayoutInflater.from(getContext()).inflate(R.layout.padersliding_tab, this, false); - } - - CharSequence title = pager.getAdapter().getPageTitle(i); - - addTab(i, title, tabView); - } - - updateTabStyles(); - getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { - - @SuppressWarnings("deprecation") - @SuppressLint("NewApi") - @Override - public void onGlobalLayout() { - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { - getViewTreeObserver().removeGlobalOnLayoutListener(this); - } else { - getViewTreeObserver().removeOnGlobalLayoutListener(this); - } - - currentPosition = pager.getCurrentItem(); - currentPositionOffset = 0f; - scrollToChild(currentPosition, 0); - updateSelection(currentPosition); - } - }); - } - - private void addTab(final int position, CharSequence title, View tabView) { - TextView textView = (TextView) tabView.findViewById(R.id.tab_title); - if (textView != null) { - if (title != null) textView.setText(title); - float alpha = pager.getCurrentItem() == position ? tabTextSelectedAlpha : tabTextAlpha; - ViewCompat.setAlpha(textView, alpha); - } - - tabView.setFocusable(true); - tabView.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (pager.getCurrentItem() != position) { - View tab = tabsContainer.getChildAt(pager.getCurrentItem()); - notSelected(tab); - pager.setCurrentItem(position); - } - } - }); - - tabView.setPadding(tabPadding, tabView.getPaddingTop(), tabPadding, tabView.getPaddingBottom()); - tabsContainer.addView(tabView, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams); - } - - private void updateTabStyles() { - for (int i = 0; i < tabCount; i++) { - View v = tabsContainer.getChildAt(i); - v.setBackgroundResource(tabBackgroundResId); - TextView tab_title = (TextView) v.findViewById(R.id.tab_title); - - if (tab_title != null) { - tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize); - tab_title.setTypeface(tabTypeface, pager.getCurrentItem() == i ? tabTypefaceSelectedStyle : tabTypefaceStyle); - if (tabTextColor != null) { - tab_title.setTextColor(tabTextColor); - } - // setAllCaps() is only available from API 14, so the upper case is made manually if we are on a - // pre-ICS-build - if (textAllCaps) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - tab_title.setAllCaps(true); - } else { - tab_title.setText(tab_title.getText().toString().toUpperCase(locale)); - } - } - } - } - - } - - private void scrollToChild(int position, int offset) { - if (tabCount == 0) { - return; - } - - int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset; - if (position > 0 || offset > 0) { - - //Half screen offset. - //- Either tabs start at the middle of the view scrolling straight away - //- Or tabs start at the begging (no padding) scrolling when indicator gets - // to the middle of the view width - newScrollX -= scrollOffset; - Pair lines = getIndicatorCoordinates(); - newScrollX += ((lines.second - lines.first) / 2); - } - - if (newScrollX != lastScrollX) { - lastScrollX = newScrollX; - scrollTo(newScrollX, 0); - } - } - - private Pair getIndicatorCoordinates() { - // default: line below current tab - View currentTab = tabsContainer.getChildAt(currentPosition); - float lineLeft = currentTab.getLeft(); - float lineRight = currentTab.getRight(); - - // if there is an offset, start interpolating left and right coordinates between current and next tab - if (currentPositionOffset > 0f && currentPosition < tabCount - 1) { - - View nextTab = tabsContainer.getChildAt(currentPosition + 1); - final float nextTabLeft = nextTab.getLeft(); - final float nextTabRight = nextTab.getRight(); - - lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft); - lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight); - } - return new Pair(lineLeft, lineRight); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - if (isInEditMode() || tabCount == 0) { - return; - } - - final int height = getHeight(); - // draw indicator line - rectPaint.setColor(indicatorColor); - Pair lines = getIndicatorCoordinates(); - canvas.drawRect(lines.first + paddingLeft, height - indicatorHeight, lines.second + paddingRight, height, rectPaint); - // draw underline - rectPaint.setColor(underlineColor); - canvas.drawRect(paddingLeft, height - underlineHeight, tabsContainer.getWidth() + paddingRight, height, rectPaint); - // draw divider - if (dividerWidth != 0) { - dividerPaint.setStrokeWidth(dividerWidth); - dividerPaint.setColor(dividerColor); - for (int i = 0; i < tabCount - 1; i++) { - View tab = tabsContainer.getChildAt(i); - canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint); - } - } - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - if (isPaddingMiddle) { - //Make sure tabContainer is bigger than the HorizontalScrollView to be able to scroll - tabsContainer.setMinimumWidth(getWidth()); - int halfFirstTab = 0; - if (tabsContainer.getChildCount() > 0) { - halfFirstTab = (tabsContainer.getChildAt(0).getWidth() / 2); - } - //The user choose the tabs to start in the middle of the view width (padding) - paddingLeft = paddingRight = getWidth() / 2 - halfFirstTab; - //Clipping padding to false to see the tabs while we pass them swiping - setClipToPadding(false); - } - - if (scrollOffset == 0) scrollOffset = getWidth() / 2 - paddingLeft; - setPadding(paddingLeft, getPaddingTop(), paddingRight, getPaddingBottom()); - super.onLayout(changed, l, t, r, b); - } - - public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) { - this.delegatePageListener = listener; - } - - private class PageListener implements ViewPager.OnPageChangeListener { - - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - currentPosition = position; - currentPositionOffset = positionOffset; - int offset = tabCount > 0 ? (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()) : 0; - scrollToChild(position, offset); - invalidate(); - if (delegatePageListener != null) { - delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels); - } - } - - @Override - public void onPageScrollStateChanged(int state) { - if (state == ViewPager.SCROLL_STATE_IDLE) { - scrollToChild(pager.getCurrentItem(), 0); - } - //Full alpha for current item - View currentTab = tabsContainer.getChildAt(pager.getCurrentItem()); - selected(currentTab); - //Half transparent for prev item - if (pager.getCurrentItem() - 1 >= 0) { - View prevTab = tabsContainer.getChildAt(pager.getCurrentItem() - 1); - notSelected(prevTab); - } - //Half transparent for next item - if (pager.getCurrentItem() + 1 <= pager.getAdapter().getCount() - 1) { - View nextTab = tabsContainer.getChildAt(pager.getCurrentItem() + 1); - notSelected(nextTab); - } - - if (delegatePageListener != null) { - delegatePageListener.onPageScrollStateChanged(state); - } - } - - @Override - public void onPageSelected(int position) { - updateSelection(position); - if (delegatePageListener != null) { - delegatePageListener.onPageSelected(position); - } - } - - } - - private void updateSelection(int position) { - for (int i = 0; i < tabCount; ++i) { - View tv = tabsContainer.getChildAt(i); - tv.setSelected(i == position); - } - } - - private void notSelected(View tab) { - TextView title = (TextView) tab.findViewById(R.id.tab_title); - if (title != null) { - title.setTypeface(tabTypeface, tabTypefaceStyle); - ViewCompat.setAlpha(title, tabTextAlpha); - } - } - - private void selected(View tab) { - TextView title = (TextView) tab.findViewById(R.id.tab_title); - if (title != null) { - title.setTypeface(tabTypeface, tabTypefaceSelectedStyle); - ViewCompat.setAlpha(title, tabTextSelectedAlpha); - } - } - - private class PagerAdapterObserver extends DataSetObserver { - - private boolean attached = false; - - @Override - public void onChanged() { - notifyDataSetChanged(); - } - - public void setAttached(boolean attached) { - this.attached = attached; - } - - public boolean isAttached() { - return attached; - } - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - if (pager != null) { - if (!adapterObserver.isAttached()) { - pager.getAdapter().registerDataSetObserver(adapterObserver); - adapterObserver.setAttached(true); - } - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (pager != null) { - if (adapterObserver.isAttached()) { - pager.getAdapter().unregisterDataSetObserver(adapterObserver); - adapterObserver.setAttached(false); - } - } - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - SavedState savedState = (SavedState) state; - super.onRestoreInstanceState(savedState.getSuperState()); - currentPosition = savedState.currentPosition; - if (currentPosition != 0 && tabsContainer.getChildCount() > 0) { - notSelected(tabsContainer.getChildAt(0)); - selected(tabsContainer.getChildAt(currentPosition)); - } - requestLayout(); - } - - @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState savedState = new SavedState(superState); - savedState.currentPosition = currentPosition; - return savedState; - } - - static class SavedState extends BaseSavedState { - int currentPosition; - - public SavedState(Parcelable superState) { - super(superState); - } - - private SavedState(Parcel in) { - super(in); - currentPosition = in.readInt(); - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeInt(currentPosition); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - @Override - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - @Override - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - public int getIndicatorColor() { - return this.indicatorColor; - } - - public int getIndicatorHeight() { - return indicatorHeight; - } - - public int getUnderlineColor() { - return underlineColor; - } - - public int getDividerColor() { - return dividerColor; - } - - public int getDividerWidth() { - return dividerWidth; - } - - public int getUnderlineHeight() { - return underlineHeight; - } - - public int getDividerPadding() { - return dividerPadding; - } - - public int getScrollOffset() { - return scrollOffset; - } - - public boolean getShouldExpand() { - return shouldExpand; - } - - public int getTextSize() { - return tabTextSize; - } - - public boolean isTextAllCaps() { - return textAllCaps; - } - - public ColorStateList getTextColor() { - return tabTextColor; - } - - public int getTabBackground() { - return tabBackgroundResId; - } - - public int getTabPaddingLeftRight() { - return tabPadding; - } - - public void setIndicatorColor(int indicatorColor) { - this.indicatorColor = indicatorColor; - invalidate(); - } - - public void setIndicatorColorResource(int resId) { - this.indicatorColor = getResources().getColor(resId); - invalidate(); - } - - public void setIndicatorHeight(int indicatorLineHeightPx) { - this.indicatorHeight = indicatorLineHeightPx; - invalidate(); - } - - public void setUnderlineColor(int underlineColor) { - this.underlineColor = underlineColor; - invalidate(); - } - - public void setUnderlineColorResource(int resId) { - this.underlineColor = getResources().getColor(resId); - invalidate(); - } - - public void setDividerColor(int dividerColor) { - this.dividerColor = dividerColor; - invalidate(); - } - - public void setDividerColorResource(int resId) { - this.dividerColor = getResources().getColor(resId); - invalidate(); - } - - public void setDividerWidth(int dividerWidthPx) { - this.dividerWidth = dividerWidthPx; - invalidate(); - } - - public void setUnderlineHeight(int underlineHeightPx) { - this.underlineHeight = underlineHeightPx; - invalidate(); - } - - public void setDividerPadding(int dividerPaddingPx) { - this.dividerPadding = dividerPaddingPx; - invalidate(); - } - - public void setScrollOffset(int scrollOffsetPx) { - this.scrollOffset = scrollOffsetPx; - invalidate(); - } - - public void setShouldExpand(boolean shouldExpand) { - this.shouldExpand = shouldExpand; - if (pager != null) { - requestLayout(); - } - } - - public void setAllCaps(boolean textAllCaps) { - this.textAllCaps = textAllCaps; - } - - public void setTextSize(int textSizePx) { - this.tabTextSize = textSizePx; - updateTabStyles(); - } - - public void setTextColor(int textColor) { - setTextColor(new ColorStateList(new int[][]{new int[]{}}, new int[]{textColor})); - } - - public void setTextColor(ColorStateList colorStateList) { - this.tabTextColor = colorStateList; - updateTabStyles(); - } - - public void setTextColorResource(int resId) { - setTextColor(getResources().getColor(resId)); - } - - public void setTextColorStateListResource(int resId) { - setTextColor(getResources().getColorStateList(resId)); - } - - public void setTypeface(Typeface typeface, int style) { - this.tabTypeface = typeface; - this.tabTypefaceSelectedStyle = style; - updateTabStyles(); - } - - public void setTabBackground(int resId) { - this.tabBackgroundResId = resId; - } - - public void setTabPaddingLeftRight(int paddingPx) { - this.tabPadding = paddingPx; - updateTabStyles(); - } -} \ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/views/RemoteCNPreference.java b/main/src/main/java/de/blinkt/openvpn/views/RemoteCNPreference.java deleted file mode 100644 index bcc0dc52..00000000 --- a/main/src/main/java/de/blinkt/openvpn/views/RemoteCNPreference.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.views; - -import android.content.Context; -import android.preference.DialogPreference; -import android.util.AttributeSet; -import android.util.Pair; -import android.view.View; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.Spinner; -import android.widget.TextView; - -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; - -public class RemoteCNPreference extends DialogPreference { - - - private Spinner mSpinner; - private EditText mEditText; - private int mDNType; - private String mDn; - private TextView mRemoteTLSNote; - //private ScrollView mScrollView; - - public RemoteCNPreference(Context context, AttributeSet attrs) { - super(context, attrs); - setDialogLayoutResource(R.layout.tlsremote); - - } - - @Override - protected void onBindDialogView(View view) { - - super.onBindDialogView(view); - - mEditText = (EditText) view.findViewById(R.id.tlsremotecn); - mSpinner = (Spinner) view.findViewById(R.id.x509verifytype); - mRemoteTLSNote = (TextView) view.findViewById(R.id.tlsremotenote); - //mScrollView = (ScrollView) view.findViewById(R.id.tlsremotescroll); - if(mDn!=null) - mEditText.setText(mDn); - - populateSpinner(); - - } - - - - public String getCNText() { - return mDn; - } - - public int getAuthtype() { - return mDNType; - } - - public void setDN(String dn) { - mDn = dn; - if(mEditText!=null) - mEditText.setText(dn); - } - - public void setAuthType(int x509authtype) { - mDNType = x509authtype; - if (mSpinner!=null) - populateSpinner(); - } - - @Override - protected void onDialogClosed(boolean positiveResult) { - super.onDialogClosed(positiveResult); - - if (positiveResult) { - String dn = mEditText.getText().toString(); - int authtype = getAuthTypeFromSpinner(); - if (callChangeListener(new Pair(authtype, dn))) { - mDn = dn; - mDNType = authtype; - } - } - } - - private void populateSpinner() { - ArrayAdapter authtypes = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item); - authtypes.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - - authtypes.add(getContext().getString(R.string.complete_dn)); - authtypes.add(getContext().getString(R.string.rdn)); - authtypes.add(getContext().getString(R.string.rdn_prefix)); - if ((mDNType == VpnProfile.X509_VERIFY_TLSREMOTE || mDNType == VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING) - && !(mDn==null || "".equals(mDn))) { - authtypes.add(getContext().getString(R.string.tls_remote_deprecated)); - mRemoteTLSNote.setVisibility(View.VISIBLE); - } else { - mRemoteTLSNote.setVisibility(View.GONE); - } - mSpinner.setAdapter(authtypes); - mSpinner.setSelection(getSpinnerPositionFromAuthTYPE()); - } - - private int getSpinnerPositionFromAuthTYPE() { - switch (mDNType) { - case VpnProfile.X509_VERIFY_TLSREMOTE_DN: - return 0; - case VpnProfile.X509_VERIFY_TLSREMOTE_RDN: - return 1; - case VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX: - return 2; - case VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING: - case VpnProfile.X509_VERIFY_TLSREMOTE: - if (mDn==null || "".equals(mDn)) - return 1; - else - return 3; - - - default: - return 0; - } - } - - private int getAuthTypeFromSpinner() { - int pos = mSpinner.getSelectedItemPosition(); - switch (pos) { - case 0: - return VpnProfile.X509_VERIFY_TLSREMOTE_DN; - case 1: - return VpnProfile.X509_VERIFY_TLSREMOTE_RDN; - case 2: - return VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX; - case 3: - // This is the tls-remote entry, only visible if mDntype is a - // tls-remote type - return mDNType; - default: - return VpnProfile.X509_VERIFY_TLSREMOTE; - } - } - -} diff --git a/main/src/main/java/de/blinkt/openvpn/views/ScreenSlidePagerAdapter.java b/main/src/main/java/de/blinkt/openvpn/views/ScreenSlidePagerAdapter.java deleted file mode 100644 index 38bb54b5..00000000 --- a/main/src/main/java/de/blinkt/openvpn/views/ScreenSlidePagerAdapter.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.views; - -import android.app.Fragment; -import android.app.FragmentManager; -import android.content.Context; -import android.content.res.Resources; -import android.os.Bundle; -import android.support.annotation.StringRes; -import android.support.v4n.app.FragmentStatePagerAdapter; - -import java.util.Vector; - -import de.blinkt.openvpn.activities.MainActivity; - -/** -* Created by arne on 18.11.14. -*/ -public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { - - private final Resources res; - private Bundle mFragmentArguments; - - public void setFragmentArgs(Bundle fragmentArguments) { - mFragmentArguments = fragmentArguments; - } - - static class Tab { - public Class fragmentClass; - String mName; - - public Tab(Class fClass, String name){ - mName = name; - fragmentClass = fClass; - } - - } - - - private Vector mTabs = new Vector(); - - public ScreenSlidePagerAdapter(FragmentManager fm, Context c) { - super(fm); - res = c.getResources(); - } - - @Override - public Fragment getItem(int position) { - try { - Fragment fragment = mTabs.get(position).fragmentClass.newInstance(); - if (mFragmentArguments!=null) - fragment.setArguments(mFragmentArguments); - return fragment; - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return null; - } - - @Override - public CharSequence getPageTitle(int position) { - return mTabs.get(position).mName; - } - - @Override - public int getCount() { - return mTabs.size(); - } - - public void addTab(@StringRes int name, Class fragmentClass) { - mTabs.add(new Tab(fragmentClass, res.getString(name))); - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java b/main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java deleted file mode 100644 index 347ce708..00000000 --- a/main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.views; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.ViewConfiguration; -import android.widget.SeekBar; - -public class SeekBarTicks extends SeekBar { - private Paint mTickPaint; - private float mTickHeight; - - private float tickHeightRatio = 0.6f; - - public SeekBarTicks(Context context, AttributeSet attrs) { - super (context, attrs); - - initTicks (context, attrs, android.R.attr.seekBarStyle); - } - - - public SeekBarTicks(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - initTicks (context, attrs, defStyle); - - /*mTickHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, - tickHeightDP, - ctx.getResources().getDisplayMetrics()); */ - } - - private void initTicks(Context context, AttributeSet attrs, int defStyle) { - TypedArray a = context.obtainStyledAttributes(attrs, - new int[] { android.R.attr.secondaryProgress }, defStyle, 0); - - mTickPaint = new Paint(); - //noinspection deprecation - mTickPaint.setColor( context.getResources().getColor(android.R.color.black)); - a.recycle(); - } - - - @Override - protected synchronized void onDraw(Canvas canvas) { - drawTicks(canvas); - super.onDraw(canvas); - } - - private void drawTicks(Canvas canvas) { - - final int available = getWidth() - getPaddingLeft() - getPaddingRight(); - final int availableHeight = getHeight() - getPaddingBottom() - getPaddingTop(); - - int extrapadding = (int) ((availableHeight- (availableHeight * tickHeightRatio))/2); - - int tickSpacing = available / (getMax() ); - - for (int i = 1; i < getMax(); i++) { - final float x = getPaddingLeft() + i * tickSpacing; - - canvas.drawLine(x, getPaddingTop()+extrapadding, x, getHeight()-getPaddingBottom()-extrapadding, mTickPaint); - } - } -} diff --git a/main/src/main/java/de/blinkt/openvpn/views/SlidingTabLayout.java b/main/src/main/java/de/blinkt/openvpn/views/SlidingTabLayout.java deleted file mode 100644 index ea3b1c26..00000000 --- a/main/src/main/java/de/blinkt/openvpn/views/SlidingTabLayout.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * 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. - */ - -package de.blinkt.openvpn.views; - -import android.content.Context; -import android.graphics.Typeface; -import android.os.Build; -import android.support.v4n.view.PagerAdapter; -import android.support.v4n.view.ViewPager; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.HorizontalScrollView; -import android.widget.TextView; - -/** - * To be used with ViewPager to provide a tab indicator component which give constant feedback as to - * the user's scroll progress. - *

- * To use the component, simply add it to your view hierarchy. Then in your - * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call - * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for. - *

- * The colors can be customized in two ways. The first and simplest is to provide an array of colors - * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The - * alternative is via the {@link TabColorizer} interface which provides you complete control over - * which color is used for any individual position. - *

- * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)}, - * providing the layout ID of your custom layout. - */ -public class SlidingTabLayout extends HorizontalScrollView implements TabBarView { - - /** - * Allows complete control over the colors drawn in the tab layout. Set with - * {@link #setCustomTabColorizer(TabColorizer)}. - */ - public interface TabColorizer { - - /** - * @return return the color of the indicator used when {@code position} is selected. - */ - int getIndicatorColor(int position); - - /** - * @return return the color of the divider drawn to the right of {@code position}. - */ - int getDividerColor(int position); - - } - - private static final int TITLE_OFFSET_DIPS = 24; - private static final int TAB_VIEW_PADDING_DIPS = 16; - private static final int TAB_VIEW_TEXT_SIZE_SP = 12; - - private int mTitleOffset; - - private int mTabViewLayoutId; - private int mTabViewTextViewId; - - private ViewPager mViewPager; - private ViewPager.OnPageChangeListener mViewPagerPageChangeListener; - - private final SlidingTabStrip mTabStrip; - - public SlidingTabLayout(Context context) { - this(context, null); - } - - public SlidingTabLayout(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - // Disable the Scroll Bar - setHorizontalScrollBarEnabled(false); - // Make sure that the Tab Strips fills this View - setFillViewport(true); - - mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density); - - mTabStrip = new SlidingTabStrip(context); - addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - } - - /** - * Set the custom {@link TabColorizer} to be used. - * - * If you only require simple custmisation then you can use - * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve - * similar effects. - */ - public void setCustomTabColorizer(TabColorizer tabColorizer) { - mTabStrip.setCustomTabColorizer(tabColorizer); - } - - /** - * Sets the colors to be used for indicating the selected tab. These colors are treated as a - * circular array. Providing one color will mean that all tabs are indicated with the same color. - */ - public void setSelectedIndicatorColors(int... colors) { - mTabStrip.setSelectedIndicatorColors(colors); - } - - /** - * Sets the colors to be used for tab dividers. These colors are treated as a circular array. - * Providing one color will mean that all tabs are indicated with the same color. - */ - public void setDividerColors(int... colors) { - mTabStrip.setDividerColors(colors); - } - - /** - * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are - * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so - * that the layout can update it's scroll position correctly. - * - * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener) - */ - public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) { - mViewPagerPageChangeListener = listener; - } - - /** - * Set the custom layout to be inflated for the tab views. - * - * @param layoutResId Layout id to be inflated - * @param textViewId id of the {@link TextView} in the inflated view - */ - public void setCustomTabView(int layoutResId, int textViewId) { - mTabViewLayoutId = layoutResId; - mTabViewTextViewId = textViewId; - } - - /** - * Sets the associated view pager. Note that the assumption here is that the pager content - * (number of tabs and tab titles) does not change after this call has been made. - */ - public void setViewPager(ViewPager viewPager) { - mTabStrip.removeAllViews(); - - mViewPager = viewPager; - if (viewPager != null) { - viewPager.setOnPageChangeListener(new InternalViewPagerListener()); - populateTabStrip(); - } - } - - /** - * Create a default view to be used for tabs. This is called if a custom tab view is not set via - * {@link #setCustomTabView(int, int)}. - */ - protected TextView createDefaultTabView(Context context) { - TextView textView = new TextView(context); - textView.setGravity(Gravity.CENTER); - textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP); - textView.setTypeface(Typeface.DEFAULT_BOLD); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - // If we're running on Honeycomb or newer, then we can use the Theme's - // selectableItemBackground to ensure that the View has a pressed state - TypedValue outValue = new TypedValue(); - getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, - outValue, true); - textView.setBackgroundResource(outValue.resourceId); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style - textView.setAllCaps(true); - } - - int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density); - textView.setPadding(padding, padding, padding, padding); - - return textView; - } - - private void populateTabStrip() { - final PagerAdapter adapter = mViewPager.getAdapter(); - final View.OnClickListener tabClickListener = new TabClickListener(); - - for (int i = 0; i < adapter.getCount(); i++) { - View tabView = null; - TextView tabTitleView = null; - - if (mTabViewLayoutId != 0) { - // If there is a custom tab view layout id set, try and inflate it - tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip, - false); - tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId); - } - - if (tabView == null) { - tabView = createDefaultTabView(getContext()); - } - - if (tabTitleView == null && TextView.class.isInstance(tabView)) { - tabTitleView = (TextView) tabView; - } - - tabTitleView.setText(adapter.getPageTitle(i)); - tabView.setOnClickListener(tabClickListener); - - mTabStrip.addView(tabView); - } - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - - if (mViewPager != null) { - scrollToTab(mViewPager.getCurrentItem(), 0); - } - } - - private void scrollToTab(int tabIndex, int positionOffset) { - final int tabStripChildCount = mTabStrip.getChildCount(); - if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) { - return; - } - - View selectedChild = mTabStrip.getChildAt(tabIndex); - if (selectedChild != null) { - int targetScrollX = selectedChild.getLeft() + positionOffset; - - if (tabIndex > 0 || positionOffset > 0) { - // If we're not at the first child and are mid-scroll, make sure we obey the offset - targetScrollX -= mTitleOffset; - } - - scrollTo(targetScrollX, 0); - } - } - - private class InternalViewPagerListener implements ViewPager.OnPageChangeListener { - private int mScrollState; - - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - int tabStripChildCount = mTabStrip.getChildCount(); - if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) { - return; - } - - mTabStrip.onViewPagerPageChanged(position, positionOffset); - - View selectedTitle = mTabStrip.getChildAt(position); - int extraOffset = (selectedTitle != null) - ? (int) (positionOffset * selectedTitle.getWidth()) - : 0; - scrollToTab(position, extraOffset); - - if (mViewPagerPageChangeListener != null) { - mViewPagerPageChangeListener.onPageScrolled(position, positionOffset, - positionOffsetPixels); - } - } - - @Override - public void onPageScrollStateChanged(int state) { - mScrollState = state; - - if (mViewPagerPageChangeListener != null) { - mViewPagerPageChangeListener.onPageScrollStateChanged(state); - } - } - - @Override - public void onPageSelected(int position) { - if (mScrollState == ViewPager.SCROLL_STATE_IDLE) { - mTabStrip.onViewPagerPageChanged(position, 0f); - scrollToTab(position, 0); - } - - if (mViewPagerPageChangeListener != null) { - mViewPagerPageChangeListener.onPageSelected(position); - } - } - - } - - private class TabClickListener implements View.OnClickListener { - @Override - public void onClick(View v) { - for (int i = 0; i < mTabStrip.getChildCount(); i++) { - if (v == mTabStrip.getChildAt(i)) { - mViewPager.setCurrentItem(i); - return; - } - } - } - } - -} diff --git a/main/src/main/java/de/blinkt/openvpn/views/SlidingTabStrip.java b/main/src/main/java/de/blinkt/openvpn/views/SlidingTabStrip.java deleted file mode 100644 index 88bfb9a3..00000000 --- a/main/src/main/java/de/blinkt/openvpn/views/SlidingTabStrip.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * 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. - */ - -package de.blinkt.openvpn.views; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.View; -import android.widget.LinearLayout; - -class SlidingTabStrip extends LinearLayout { - - private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2; - private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26; - private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8; - private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5; - - private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1; - private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20; - private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f; - - private final int mBottomBorderThickness; - private final Paint mBottomBorderPaint; - - private final int mSelectedIndicatorThickness; - private final Paint mSelectedIndicatorPaint; - - private final int mDefaultBottomBorderColor; - - private final Paint mDividerPaint; - private final float mDividerHeight; - - private int mSelectedPosition; - private float mSelectionOffset; - - private SlidingTabLayout.TabColorizer mCustomTabColorizer; - private final SimpleTabColorizer mDefaultTabColorizer; - - SlidingTabStrip(Context context) { - this(context, null); - } - - SlidingTabStrip(Context context, AttributeSet attrs) { - super(context, attrs); - setWillNotDraw(false); - - final float density = getResources().getDisplayMetrics().density; - - TypedValue outValue = new TypedValue(); - context.getTheme().resolveAttribute(android.R.attr.colorForeground, outValue, true); - final int themeForegroundColor = outValue.data; - - mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor, - DEFAULT_BOTTOM_BORDER_COLOR_ALPHA); - - mDefaultTabColorizer = new SimpleTabColorizer(); - mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR); - mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor, - DEFAULT_DIVIDER_COLOR_ALPHA)); - - mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density); - mBottomBorderPaint = new Paint(); - mBottomBorderPaint.setColor(mDefaultBottomBorderColor); - - mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density); - mSelectedIndicatorPaint = new Paint(); - - mDividerHeight = DEFAULT_DIVIDER_HEIGHT; - mDividerPaint = new Paint(); - mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density)); - } - - void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) { - mCustomTabColorizer = customTabColorizer; - invalidate(); - } - - void setSelectedIndicatorColors(int... colors) { - // Make sure that the custom colorizer is removed - mCustomTabColorizer = null; - mDefaultTabColorizer.setIndicatorColors(colors); - invalidate(); - } - - void setDividerColors(int... colors) { - // Make sure that the custom colorizer is removed - mCustomTabColorizer = null; - mDefaultTabColorizer.setDividerColors(colors); - invalidate(); - } - - void onViewPagerPageChanged(int position, float positionOffset) { - mSelectedPosition = position; - mSelectionOffset = positionOffset; - invalidate(); - } - - @Override - protected void onDraw(Canvas canvas) { - final int height = getHeight(); - final int childCount = getChildCount(); - final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height); - final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null - ? mCustomTabColorizer - : mDefaultTabColorizer; - - // Thick colored underline below the current selection - if (childCount > 0) { - View selectedTitle = getChildAt(mSelectedPosition); - int left = selectedTitle.getLeft(); - int right = selectedTitle.getRight(); - int color = tabColorizer.getIndicatorColor(mSelectedPosition); - - if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) { - int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1); - if (color != nextColor) { - color = blendColors(nextColor, color, mSelectionOffset); - } - - // Draw the selection partway between the tabs - View nextTitle = getChildAt(mSelectedPosition + 1); - left = (int) (mSelectionOffset * nextTitle.getLeft() + - (1.0f - mSelectionOffset) * left); - right = (int) (mSelectionOffset * nextTitle.getRight() + - (1.0f - mSelectionOffset) * right); - } - - mSelectedIndicatorPaint.setColor(color); - - canvas.drawRect(left, height - mSelectedIndicatorThickness, right, - height, mSelectedIndicatorPaint); - } - - // Thin underline along the entire bottom edge - canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint); - - // Vertical separators between the titles - int separatorTop = (height - dividerHeightPx) / 2; - for (int i = 0; i < childCount - 1; i++) { - View child = getChildAt(i); - mDividerPaint.setColor(tabColorizer.getDividerColor(i)); - canvas.drawLine(child.getRight(), separatorTop, child.getRight(), - separatorTop + dividerHeightPx, mDividerPaint); - } - } - - /** - * Set the alpha value of the {@code color} to be the given {@code alpha} value. - */ - private static int setColorAlpha(int color, byte alpha) { - return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)); - } - - /** - * Blend {@code color1} and {@code color2} using the given ratio. - * - * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend, - * 0.0 will return {@code color2}. - */ - private static int blendColors(int color1, int color2, float ratio) { - final float inverseRation = 1f - ratio; - float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation); - float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation); - float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation); - return Color.rgb((int) r, (int) g, (int) b); - } - - private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer { - private int[] mIndicatorColors; - private int[] mDividerColors; - - @Override - public final int getIndicatorColor(int position) { - return mIndicatorColors[position % mIndicatorColors.length]; - } - - @Override - public final int getDividerColor(int position) { - return mDividerColors[position % mDividerColors.length]; - } - - void setIndicatorColors(int... colors) { - mIndicatorColors = colors; - } - - void setDividerColors(int... colors) { - mDividerColors = colors; - } - } -} \ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/views/TabBarView.java b/main/src/main/java/de/blinkt/openvpn/views/TabBarView.java deleted file mode 100644 index 71f03c03..00000000 --- a/main/src/main/java/de/blinkt/openvpn/views/TabBarView.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.views; - -import android.support.v4n.view.ViewPager; - -/** - * Created by arne on 18.11.14. - */ -public interface TabBarView { - - void setViewPager(ViewPager mPager); -} diff --git a/main/src/main/res/anim/fab_anim.xml b/main/src/main/res/anim/fab_anim.xml deleted file mode 100644 index 498533e0..00000000 --- a/main/src/main/res/anim/fab_anim.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - diff --git a/main/src/main/res/drawable-hdpi/ic_add_circle_outline_grey600_24dp.png b/main/src/main/res/drawable-hdpi/ic_add_circle_outline_grey600_24dp.png deleted file mode 100644 index 7e0a71cd..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_add_circle_outline_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_add_circle_outline_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_add_circle_outline_white_24dp.png deleted file mode 100644 index d86d598e..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_add_circle_outline_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_archive_grey600_24dp.png b/main/src/main/res/drawable-hdpi/ic_archive_grey600_24dp.png deleted file mode 100644 index 2948d5fc..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_archive_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_archive_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_archive_white_24dp.png deleted file mode 100644 index a9b0b240..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_archive_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_check_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_check_white_24dp.png deleted file mode 100644 index f42a0e2d..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_check_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_close_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_close_white_24dp.png deleted file mode 100644 index ceb1a1ee..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_close_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_content_copy_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_content_copy_white_24dp.png deleted file mode 100644 index 03b1aac4..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_content_copy_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_delete_grey600_24dp.png b/main/src/main/res/drawable-hdpi/ic_delete_grey600_24dp.png deleted file mode 100644 index b72a9f3c..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_delete_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_delete_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_delete_white_24dp.png deleted file mode 100644 index a9eac0ca..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_delete_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_doc_generic_am.png b/main/src/main/res/drawable-hdpi/ic_doc_generic_am.png deleted file mode 100644 index 55b9b7d3..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_doc_generic_am.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_edit_grey600_24dp.png b/main/src/main/res/drawable-hdpi/ic_edit_grey600_24dp.png deleted file mode 100644 index b5f88c80..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_edit_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_edit_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_edit_white_24dp.png deleted file mode 100644 index 730416c9..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_edit_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_filter_list_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_filter_list_white_24dp.png deleted file mode 100644 index 30122adf..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_filter_list_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_menu_copy_holo_dark.png b/main/src/main/res/drawable-hdpi/ic_menu_copy_holo_dark.png deleted file mode 100644 index d37d0a31..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_menu_copy_holo_dark.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_pause_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_pause_white_24dp.png deleted file mode 100644 index 4d2ea05c..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_pause_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png deleted file mode 100644 index 57c9fa54..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_receipt_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_receipt_white_24dp.png deleted file mode 100644 index bf781280..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_receipt_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_root_folder_am.png b/main/src/main/res/drawable-hdpi/ic_root_folder_am.png deleted file mode 100644 index 915e1182..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_root_folder_am.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_search_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_search_white_24dp.png deleted file mode 100755 index bbfbc96c..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_search_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_share_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_share_white_24dp.png deleted file mode 100644 index 93b3c219..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_share_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_sort_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_sort_white_24dp.png deleted file mode 100644 index 55a429b6..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_sort_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-hdpi/ic_warning_black_36dp.png b/main/src/main/res/drawable-hdpi/ic_warning_black_36dp.png deleted file mode 100644 index d1cef177..00000000 Binary files a/main/src/main/res/drawable-hdpi/ic_warning_black_36dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_add_circle_outline_grey600_24dp.png b/main/src/main/res/drawable-mdpi/ic_add_circle_outline_grey600_24dp.png deleted file mode 100644 index b5017d2a..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_add_circle_outline_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_add_circle_outline_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_add_circle_outline_white_24dp.png deleted file mode 100644 index 6a1c32aa..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_add_circle_outline_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_archive_grey600_24dp.png b/main/src/main/res/drawable-mdpi/ic_archive_grey600_24dp.png deleted file mode 100644 index a42d774c..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_archive_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_archive_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_archive_white_24dp.png deleted file mode 100644 index 8e4a0426..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_archive_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_check_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_check_white_24dp.png deleted file mode 100644 index e91f9048..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_check_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_close_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_close_white_24dp.png deleted file mode 100644 index af7f8288..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_close_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_content_copy_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_content_copy_white_24dp.png deleted file mode 100644 index 6aa238c5..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_content_copy_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_delete_grey600_24dp.png b/main/src/main/res/drawable-mdpi/ic_delete_grey600_24dp.png deleted file mode 100644 index e757fdb0..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_delete_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_delete_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_delete_white_24dp.png deleted file mode 100644 index e4ea52ef..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_delete_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_doc_generic_am.png b/main/src/main/res/drawable-mdpi/ic_doc_generic_am.png deleted file mode 100644 index a1bd14ea..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_doc_generic_am.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_edit_grey600_24dp.png b/main/src/main/res/drawable-mdpi/ic_edit_grey600_24dp.png deleted file mode 100644 index bae3480c..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_edit_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_edit_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_edit_white_24dp.png deleted file mode 100644 index 85cff0b9..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_edit_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_filter_list_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_filter_list_white_24dp.png deleted file mode 100644 index 49cec669..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_filter_list_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_menu_copy_holo_dark.png b/main/src/main/res/drawable-mdpi/ic_menu_copy_holo_dark.png deleted file mode 100644 index 97e8ac1b..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_menu_copy_holo_dark.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_pause_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_pause_white_24dp.png deleted file mode 100644 index 2272d478..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_pause_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png deleted file mode 100644 index c61e948b..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_receipt_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_receipt_white_24dp.png deleted file mode 100644 index 565c67ff..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_receipt_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_root_folder_am.png b/main/src/main/res/drawable-mdpi/ic_root_folder_am.png deleted file mode 100644 index 4352d08d..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_root_folder_am.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_search_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_search_white_24dp.png deleted file mode 100755 index faefc59c..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_search_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_share_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_share_white_24dp.png deleted file mode 100644 index 4d019722..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_share_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_sort_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_sort_white_24dp.png deleted file mode 100644 index 3d84a444..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_sort_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-mdpi/ic_warning_black_36dp.png b/main/src/main/res/drawable-mdpi/ic_warning_black_36dp.png deleted file mode 100644 index 52273c3e..00000000 Binary files a/main/src/main/res/drawable-mdpi/ic_warning_black_36dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_add_circle_outline_grey600_24dp.png b/main/src/main/res/drawable-xhdpi/ic_add_circle_outline_grey600_24dp.png deleted file mode 100644 index b9a106fd..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_add_circle_outline_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_add_circle_outline_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_add_circle_outline_white_24dp.png deleted file mode 100644 index 0399d60a..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_add_circle_outline_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_archive_grey600_24dp.png b/main/src/main/res/drawable-xhdpi/ic_archive_grey600_24dp.png deleted file mode 100644 index 6725175d..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_archive_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_archive_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_archive_white_24dp.png deleted file mode 100644 index 08228d1f..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_archive_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_check_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_check_white_24dp.png deleted file mode 100644 index e5024472..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_check_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_close_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_close_white_24dp.png deleted file mode 100644 index b7c7ffd0..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_close_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_content_copy_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_content_copy_white_24dp.png deleted file mode 100644 index 04a0cc94..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_content_copy_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_delete_grey600_24dp.png b/main/src/main/res/drawable-xhdpi/ic_delete_grey600_24dp.png deleted file mode 100644 index c6bb43e8..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_delete_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png deleted file mode 100644 index cdb230c2..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_doc_generic_am.png b/main/src/main/res/drawable-xhdpi/ic_doc_generic_am.png deleted file mode 100644 index e05c4b48..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_doc_generic_am.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_edit_grey600_24dp.png b/main/src/main/res/drawable-xhdpi/ic_edit_grey600_24dp.png deleted file mode 100644 index 4c95bd57..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_edit_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_edit_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_edit_white_24dp.png deleted file mode 100644 index 7f0ea51b..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_edit_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_filter_list_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_filter_list_white_24dp.png deleted file mode 100644 index d4ca77bf..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_filter_list_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_menu_copy_holo_dark.png b/main/src/main/res/drawable-xhdpi/ic_menu_copy_holo_dark.png deleted file mode 100644 index ba883aec..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_menu_copy_holo_dark.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png deleted file mode 100644 index f49aed75..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png deleted file mode 100644 index a3c80e73..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_receipt_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_receipt_white_24dp.png deleted file mode 100644 index 66dafa4f..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_receipt_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_root_folder_am.png b/main/src/main/res/drawable-xhdpi/ic_root_folder_am.png deleted file mode 100644 index c916e0be..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_root_folder_am.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_search_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_search_white_24dp.png deleted file mode 100755 index bfc3e393..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_search_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_share_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_share_white_24dp.png deleted file mode 100644 index dd536bca..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_share_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_sort_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_sort_white_24dp.png deleted file mode 100644 index 6d4af1bc..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_sort_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xhdpi/ic_warning_black_36dp.png b/main/src/main/res/drawable-xhdpi/ic_warning_black_36dp.png deleted file mode 100644 index e1d6f7ac..00000000 Binary files a/main/src/main/res/drawable-xhdpi/ic_warning_black_36dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_add_circle_outline_grey600_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_add_circle_outline_grey600_24dp.png deleted file mode 100644 index d13b5195..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_add_circle_outline_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_add_circle_outline_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_add_circle_outline_white_24dp.png deleted file mode 100644 index 7ae1b4a1..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_add_circle_outline_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_archive_grey600_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_archive_grey600_24dp.png deleted file mode 100644 index 25cfc91a..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_archive_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_archive_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_archive_white_24dp.png deleted file mode 100644 index aa186ce5..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_archive_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png deleted file mode 100644 index 6e03d54c..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png deleted file mode 100644 index 6b717e0d..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_content_copy_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_content_copy_white_24dp.png deleted file mode 100644 index 5fc17a4d..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_content_copy_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_delete_grey600_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_delete_grey600_24dp.png deleted file mode 100644 index 4886ab1e..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_delete_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png deleted file mode 100644 index 0e95e9b1..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_doc_generic_am.png b/main/src/main/res/drawable-xxhdpi/ic_doc_generic_am.png deleted file mode 100644 index c0988663..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_doc_generic_am.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_edit_grey600_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_edit_grey600_24dp.png deleted file mode 100644 index 6ed4351c..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_edit_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_edit_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_edit_white_24dp.png deleted file mode 100644 index 34ec7092..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_edit_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_filter_list_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_filter_list_white_24dp.png deleted file mode 100644 index 802b3cd5..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_filter_list_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_menu_copy_holo_dark.png b/main/src/main/res/drawable-xxhdpi/ic_menu_copy_holo_dark.png deleted file mode 100644 index 9dd56eff..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_menu_copy_holo_dark.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_pause_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_pause_white_24dp.png deleted file mode 100644 index 7192ad48..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_pause_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png deleted file mode 100644 index 547ef30a..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_receipt_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_receipt_white_24dp.png deleted file mode 100644 index 2161c9a5..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_receipt_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_root_folder_am.png b/main/src/main/res/drawable-xxhdpi/ic_root_folder_am.png deleted file mode 100644 index 077c851c..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_root_folder_am.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png deleted file mode 100755 index abbb9895..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_share_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_share_white_24dp.png deleted file mode 100644 index 9963c6a0..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_share_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_sort_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_sort_white_24dp.png deleted file mode 100644 index b8ef1050..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_sort_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_warning_black_36dp.png b/main/src/main/res/drawable-xxhdpi/ic_warning_black_36dp.png deleted file mode 100644 index 2aab2278..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/ic_warning_black_36dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_add_circle_outline_grey600_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_add_circle_outline_grey600_24dp.png deleted file mode 100644 index ae11fb25..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_add_circle_outline_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_add_circle_outline_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_add_circle_outline_white_24dp.png deleted file mode 100644 index 1d436703..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_add_circle_outline_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_archive_grey600_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_archive_grey600_24dp.png deleted file mode 100644 index 58d38997..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_archive_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_archive_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_archive_white_24dp.png deleted file mode 100644 index 9d538ff4..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_archive_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png deleted file mode 100644 index 87892840..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png deleted file mode 100644 index 39641921..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_content_copy_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_content_copy_white_24dp.png deleted file mode 100644 index 557c64f7..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_content_copy_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_delete_grey600_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_delete_grey600_24dp.png deleted file mode 100644 index e4e21812..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_delete_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png deleted file mode 100644 index ccf8c716..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_edit_grey600_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_edit_grey600_24dp.png deleted file mode 100644 index 0c0fd76f..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_edit_grey600_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_edit_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_edit_white_24dp.png deleted file mode 100644 index 9380370f..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_edit_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_filter_list_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_filter_list_white_24dp.png deleted file mode 100644 index 511008ce..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_filter_list_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_pause_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_pause_white_24dp.png deleted file mode 100644 index 660ac658..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_pause_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png deleted file mode 100644 index be5c062b..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_receipt_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_receipt_white_24dp.png deleted file mode 100644 index 8cac119c..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_receipt_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png deleted file mode 100755 index dd5adfc7..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_share_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_share_white_24dp.png deleted file mode 100644 index bb521c14..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_share_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_sort_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_sort_white_24dp.png deleted file mode 100644 index 4796c33b..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_sort_white_24dp.png and /dev/null differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_warning_black_36dp.png b/main/src/main/res/drawable-xxxhdpi/ic_warning_black_36dp.png deleted file mode 100644 index 58999574..00000000 Binary files a/main/src/main/res/drawable-xxxhdpi/ic_warning_black_36dp.png and /dev/null differ diff --git a/main/src/main/res/drawable/bg_rect_round.xml b/main/src/main/res/drawable/bg_rect_round.xml deleted file mode 100644 index 2c24c090..00000000 --- a/main/src/main/res/drawable/bg_rect_round.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/drawable/bg_switchbar.xml b/main/src/main/res/drawable/bg_switchbar.xml deleted file mode 100644 index 7af57ad3..00000000 --- a/main/src/main/res/drawable/bg_switchbar.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/main/src/main/res/drawable/bg_tabs.xml b/main/src/main/res/drawable/bg_tabs.xml deleted file mode 100644 index 8b859535..00000000 --- a/main/src/main/res/drawable/bg_tabs.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/main/src/main/res/drawable/ic_shortcut_cancel.xml b/main/src/main/res/drawable/ic_shortcut_cancel.xml deleted file mode 100644 index 7fd187ae..00000000 --- a/main/src/main/res/drawable/ic_shortcut_cancel.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - diff --git a/main/src/main/res/drawable/ic_shortcut_vpn_key.xml b/main/src/main/res/drawable/ic_shortcut_vpn_key.xml deleted file mode 100644 index 6d1c010a..00000000 --- a/main/src/main/res/drawable/ic_shortcut_vpn_key.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - diff --git a/main/src/main/res/drawable/oval_ripple.xml b/main/src/main/res/drawable/oval_ripple.xml deleted file mode 100644 index 7d01f62d..00000000 --- a/main/src/main/res/drawable/oval_ripple.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - diff --git a/main/src/main/res/drawable/slidingtab_background.xml b/main/src/main/res/drawable/slidingtab_background.xml deleted file mode 100644 index e923489e..00000000 --- a/main/src/main/res/drawable/slidingtab_background.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/drawable/white_rect.xml b/main/src/main/res/drawable/white_rect.xml deleted file mode 100644 index 36df6913..00000000 --- a/main/src/main/res/drawable/white_rect.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout-sw600dp-port/log_fragment.xml b/main/src/main/res/layout-sw600dp-port/log_fragment.xml deleted file mode 100644 index 7a4b60fe..00000000 --- a/main/src/main/res/layout-sw600dp-port/log_fragment.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout-sw600dp/log_fragment.xml b/main/src/main/res/layout-sw600dp/log_fragment.xml deleted file mode 100644 index 089bfb9d..00000000 --- a/main/src/main/res/layout-sw600dp/log_fragment.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/main/src/main/res/layout-v21/connection_fab.xml b/main/src/main/res/layout-v21/connection_fab.xml deleted file mode 100644 index e3e620d6..00000000 --- a/main/src/main/res/layout-v21/connection_fab.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout-v21/profile_list_fabs.xml b/main/src/main/res/layout-v21/profile_list_fabs.xml deleted file mode 100644 index 4fe403b6..00000000 --- a/main/src/main/res/layout-v21/profile_list_fabs.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout-v21/save_fab.xml b/main/src/main/res/layout-v21/save_fab.xml deleted file mode 100644 index af7847e8..00000000 --- a/main/src/main/res/layout-v21/save_fab.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - diff --git a/main/src/main/res/layout-v21/share_fab.xml b/main/src/main/res/layout-v21/share_fab.xml deleted file mode 100644 index fb0d432f..00000000 --- a/main/src/main/res/layout-v21/share_fab.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - \ No newline at end of file diff --git a/main/src/main/res/layout-v21/tabs.xml b/main/src/main/res/layout-v21/tabs.xml deleted file mode 100644 index af349a4f..00000000 --- a/main/src/main/res/layout-v21/tabs.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout/about.xml b/main/src/main/res/layout/about.xml deleted file mode 100644 index 8b40520b..00000000 --- a/main/src/main/res/layout/about.xml +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/main/src/main/res/layout/allowed_application_layout.xml b/main/src/main/res/layout/allowed_application_layout.xml deleted file mode 100644 index d8d846f9..00000000 --- a/main/src/main/res/layout/allowed_application_layout.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout/allowed_application_settings.xml b/main/src/main/res/layout/allowed_application_settings.xml deleted file mode 100644 index 96170965..00000000 --- a/main/src/main/res/layout/allowed_application_settings.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout/allowed_vpn_apps.xml b/main/src/main/res/layout/allowed_vpn_apps.xml deleted file mode 100644 index 7f5e7b8b..00000000 --- a/main/src/main/res/layout/allowed_vpn_apps.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout/basic_settings.xml b/main/src/main/res/layout/basic_settings.xml deleted file mode 100644 index eda20ddd..00000000 --- a/main/src/main/res/layout/basic_settings.xml +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/main/src/main/res/layout/config_converter.xml b/main/src/main/res/layout/config_converter.xml deleted file mode 100644 index 4070ff7c..00000000 --- a/main/src/main/res/layout/config_converter.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/main/src/main/res/layout/connection_fab.xml b/main/src/main/res/layout/connection_fab.xml deleted file mode 100644 index 681348e5..00000000 --- a/main/src/main/res/layout/connection_fab.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout/connections.xml b/main/src/main/res/layout/connections.xml deleted file mode 100644 index 598ddd92..00000000 --- a/main/src/main/res/layout/connections.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout/extauth_provider.xml b/main/src/main/res/layout/extauth_provider.xml deleted file mode 100644 index 69d1f3d8..00000000 --- a/main/src/main/res/layout/extauth_provider.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout/file_dialog_row.xml b/main/src/main/res/layout/file_dialog_row.xml deleted file mode 100644 index e2c1e0de..00000000 --- a/main/src/main/res/layout/file_dialog_row.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/main/src/main/res/layout/file_select.xml b/main/src/main/res/layout/file_select.xml deleted file mode 100644 index b6b2091a..00000000 --- a/main/src/main/res/layout/file_select.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/main/src/ui/res/layout/file_dialog_row.xml b/main/src/ui/res/layout/file_dialog_row.xml new file mode 100644 index 00000000..e2c1e0de --- /dev/null +++ b/main/src/ui/res/layout/file_dialog_row.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/main/src/ui/res/layout/file_select.xml b/main/src/ui/res/layout/file_select.xml new file mode 100644 index 00000000..b6b2091a --- /dev/null +++ b/main/src/ui/res/layout/file_select.xml @@ -0,0 +1,77 @@ + + + + + + +