From f1e5a2c7a4ef8e7c5e8df3a9ed8861548a8019f8 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Tue, 3 Feb 2015 19:40:19 +0100 Subject: Start documenting different VPN bugs and the versions the bugs manifest in. --- .../de/blinkt/openvpn/fragments/FaqFragment.java | 195 +++++++++++++++++---- .../blinkt/openvpn/fragments/FaqViewAdapter.java | 45 ++++- main/src/main/res/values-de/strings.xml | 2 + main/src/main/res/values/strings.xml | 16 +- 4 files changed, 210 insertions(+), 48 deletions(-) (limited to 'main/src') diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java index 5086530b..30be7b2a 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java @@ -6,6 +6,7 @@ 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; @@ -15,43 +16,162 @@ 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 { -private static int[] faqitems[] = - { - {R.string.faq_howto_title, R.string.faq_howto}, - {R.string.faq_vpndialog43_title, R.string.faq_vpndialog43}, - {R.string.faq_system_dialogs_title, R.string.faq_system_dialogs}, - {R.string.faq_duplicate_notification_title, R.string.faq_duplicate_notification}, - {R.string.faq_androids_clients_title, R.string.faq_android_clients}, - {R.string.battery_consumption_title, R.string.baterry_consumption}, - {R.string.tap_mode, R.string.faq_tap_mode}, - {R.string.vpn_tethering_title, R.string.faq_tethering}, - {R.string.faq_security_title, R.string.faq_security}, - {R.string.broken_images, R.string.broken_images_faq}, - {R.string.faq_shortcut, R.string.faq_howto_shortcut}, - {R.string.tap_mode, R.string.tap_faq2}, - {R.string.copying_log_entries, R.string.faq_copying}, - {R.string.tap_mode, R.string.tap_faq3}, - {R.string.faq_routing_title, R.string.faq_routing} - }; +public class FaqFragment extends Fragment { + static class FAQEntry { + + public FAQEntry(int startVersion, int endVersion, int description) { + this (startVersion, endVersion, -1, description); + } + + 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 isAtLeast442 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && + !release.startsWith("4.4.3") && !release.startsWith("4.4.3") + && !release.startsWith("4.4.4") && !release.startsWith("4.4.5") && !release.startsWith("4.4.6"); + + boolean isAtLeast443 = isAtLeast442 && !release.startsWith("4.4.2"); + if (endVersion == -441 && !isAtLeast442) + return true; + + if (endVersion == -442 && !isAtLeast443) + return true; + + + } + 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 getAndroidVersionString(c, startVersion) + " and later"; + + + 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_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, -1, 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), + 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.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), + 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), + 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), + new FAQEntry(Build.VERSION_CODES.KITKAT, Build.VERSION_CODES.KITKAT, 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), + new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.tap_mode, R.string.tap_faq3), + + }; + + + private RecyclerView mRecyclerView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v= inflater.inflate(R.layout.faq, container, false); + 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); + 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; + int columns = dpWidth / 360; columns = Math.max(1, columns); @@ -66,25 +186,24 @@ private static int[] faqitems[] = mRecyclerView.setAdapter(new FaqViewAdapter(getActivity(), getFAQEntries())); - return v; + return v; } - /* I think the problem mentioned in there should not affect, 4.3+ */ - private int[][] getFAQEntries() { - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - int[][] newFaqItems = new int[faqitems.length - 1][2]; - int j=0; - for (int i = 0;i < faqitems.length;i++) { - if (faqitems[i][0] != R.string.broken_images) { - newFaqItems[j] = faqitems[i]; - j++; - } - } - return newFaqItems; + private FAQEntry[] getFAQEntries() { + Vector faqItems = new Vector<>(); - } else { - return faqitems; + 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 index 28c12eae..19421800 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/FaqViewAdapter.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/FaqViewAdapter.java @@ -19,24 +19,47 @@ import android.widget.TextView; import de.blinkt.openvpn.R; -import static android.support.v7.widget.RecyclerView.ViewHolder; - public class FaqViewAdapter extends RecyclerView.Adapter { - private final int[][] mFaqItems; + private final FaqFragment.FAQEntry[] mFaqItems; private final Spanned[] mHtmlEntries; + private final Spanned[] mHtmlEntriesTitle; + - public FaqViewAdapter(Context context, int[][] faqItems) { + public FaqViewAdapter(Context context, FaqFragment.FAQEntry[] faqItems) { mFaqItems = faqItems; mHtmlEntries = new Spanned[faqItems.length]; + mHtmlEntriesTitle = new Spanned[faqItems.length]; + for (int i =0; i < faqItems.length; i++) { - mHtmlEntries[i] = Html.fromHtml(context.getString(faqItems[i][1])); + String versionText = mFaqItems[i].getVersionsString(context); + String title; + String textColor=""; + + if (mFaqItems[i].title==-1) + title =""; + else + title = context.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); + } + + mHtmlEntries[i] = Html.fromHtml(textColor + context.getString(faqItems[i].description)); // Add hack R.string.faq_system_dialogs_title -> R.string.faq_system_dialog_xposed - if (faqItems[i][0] == R.string.faq_system_dialogs_title) + if (faqItems[i].title == R.string.faq_system_dialogs_title) { - Spanned xposedtext = Html.fromHtml(context.getString(R.string.faq_system_dialog_xposed)); - mHtmlEntries[i] = (Spanned) TextUtils.concat(mHtmlEntries[i], xposedtext); + Spanned xPosedtext = Html.fromHtml(textColor + context.getString(R.string.faq_system_dialog_xposed)); + mHtmlEntries[i] = (Spanned) TextUtils.concat(mHtmlEntries[i], xPosedtext); } } @@ -68,8 +91,11 @@ public class FaqViewAdapter extends RecyclerView.AdapterKeine Server definiert VPN Profil duplizieren VPN Profil duplizieren: %s + bis einschließlich %s + diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml index c565b1ea..fd39aa99 100755 --- a/main/src/main/res/values/strings.xml +++ b/main/src/main/res/values/strings.xml @@ -295,7 +295,7 @@ Hardware Keystore: Icon of app trying to use OpenVPN for Android "Starting with Android 4.3 the VPN confirmation is guarded against \"overlaying apps\". This results in the dialog not reacting to touch input. If you have an app that uses overlays it may cause this behaviour. If you find an offending app contact the author of the app. This problem affect all VPN applications on Android 4.3 and later. See also <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=185\">Issue 185<a> for additional details" - Vpn Confirm Dialog on Android 4.3 and later + Vpn Confirmation Dialog Alternatively you can send me a donation with the Play Store: Thanks for donating %s! Log cleared. @@ -351,5 +351,19 @@ Multiple OpenVPN clients for Android exist. The most common ones are OpenVPN for Android (this client), OpenVPN Connect and OpenVPN Settings.<p>The clients can be grouped into two groups: OpenVPN for Android and OpenVPN Connect use the official VPNService API (Android 4.0+) and require no root and OpenVPN Settings which uses root.<p>OpenVPN for Android is an open source client and developed by Arne Schwabe. It is targeted at more advanced users and offers many settings and the ability to import profiles from files and to configure/change profiles inside the app. The client is based on the community version of OpenVPN. It is based on the OpenVPN 2.x source code. This client can be seen as the semi officially client of the community. <p>OpenVPN Connect is non open source client that is developed by OpenVPN Technologies, Inc. The client is indented to be general use client and moree targeted at the average user and allows the import of OpenVPN profiles. This client is based on the OpenVPN C++ reimplementation of the OpenVPN protocol (This was required to allow OpenVPN Technologies, Inc to publish an iOS OpenVPN app). This client is the official client of the OpenVPN technologies <p> OpenVPN Settings is the oldest of the clients and also a UI for the open source OpenVPN. In contrast to OpenVPN for Android it requires root and does not use the VPNService API. It does not depend on Android 4.0+ Differences between the OpenVPN Android clients Ignoring multicast route: %s + Android supports only CIDR routes to the VPN. Since non-CIDR routes are almost never used, OpenVPN for Android will use a /32 for routes that are not CIDR and issue a warning. + Tethering works while the VPN is active. The tethered connection will NOT use the VPN. + Early KitKat version set the wrong MSS value on TCP connections (#61948). OpenVPN for will automatically enable mssfix option to workaround this bug. + Android will keep using your proxy settings specified for the mobile/Wi-Fi connection when no DNS servers are set. OpenVPN for Android will warn you about this in the log.

When a VPN sets a DNS server Android will not a proxy. There is no API to set a proxy for a VPN connection.

+ VPN apps may stop working when uninstalled and reinstalled again. For details see #80074 + The configured client IP and the IPs in its network mask are not routed to the VPN. OpenVPN works around this bug by explicitly adding a route that corrosponds to the client IP and its netmask + Opening a tun device while another tun device is active, which is used for persist-tun support, crashes the VPNServices on the device. A reboot is required to make VPN work again. OpenVPN for Android tries to avoid reopening the tun device and if really needed first closes the current TUN before opening the new TUN device to avoid to crash. This may lead to a short window where packets are sent over the non-VPN connection. + VPN does not work at all for secondary users. + "Multiple users report that the mobile connection/mobile data connection is frequently dropped while using the VPN app. The behaviour seems to affect only some mobile provider/device combination and so far no cause/workaround for the bug could be identified. " + Only destination can be reached over the VPN that are reachable without VPN. IPv6 VPNs does not work at all. + Non CIDR Routes + Proxy behaviour for VPNs + Reinstalling VPN apps + %s and earlier -- cgit v1.2.3