summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2013-08-08 23:38:52 +0200
committerArne Schwabe <arne@rfc2549.org>2013-08-08 23:38:52 +0200
commitf7afba629cfb1e40daf32fb25801c562e113d084 (patch)
tree9e94154164ebd202a12e4bc2c448e8f4b7ed3f41
parentb30c70fc08532151cf58c7de9cd3928d557bdf8f (diff)
Log error if the IP that should be set is invalid
-rwxr-xr-xres/values/strings.xml241
-rw-r--r--src/de/blinkt/openvpn/core/OpenVpnService.java969
2 files changed, 668 insertions, 542 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 111929ca..a41f04fd 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -17,8 +17,11 @@
<string name="client_pkcs12_title">PKCS12 File</string>
<string name="ca_title">CA Certificate</string>
<string name="no_certificate">You must select a certificate</string>
- <string name="copyright_guicode">Source code and issue tracker available at http://code.google.com/p/ics-openvpn/</string>
- <string name="copyright_others">This program uses the following components; see the source code for full details on the licenses</string>
+ <string name="copyright_guicode">Source code and issue tracker available at http://code.google.com/p/ics-openvpn/
+ </string>
+ <string name="copyright_others">This program uses the following components; see the source code for full details on
+ the licenses
+ </string>
<string name="about">About</string>
<string name="vpn_list_title">Profiles</string>
<string name="vpn_type">Type</string>
@@ -31,7 +34,10 @@
<string name="ipv4_dialog_title">Enter IPv4 Address/Netmask in CIDR Format (e.g. 1.2.3.4/24)</string>
<string name="ipv4_address">IPv4 Address</string>
<string name="ipv6_address">IPv6 Address</string>
- <string name="custom_option_warning">Enter custom OpenVPN options. Use with caution. Also note that many of the tun related OpenVPN settings cannot be supported by design of the VPNSettings. If you think an important option is missing contact the author</string>
+ <string name="custom_option_warning">Enter custom OpenVPN options. Use with caution. Also note that many of the tun
+ related OpenVPN settings cannot be supported by design of the VPNSettings. If you think an important option is
+ missing contact the author
+ </string>
<string name="auth_username">Username</string>
<string name="auth_pwquery">Password</string>
<string name="static_keys_info">For the static configuration the TLS Auth Keys will be used as static keys</string>
@@ -60,16 +66,24 @@
<string name="title_cancel">Cancel Confirmation</string>
<string name="cancel_connection_query">Disconnect the connected VPN/cancel the connection attempt?</string>
<string name="remove_vpn">Remove VPN</string>
- <string name="check_remote_tlscert">Checks whether the server uses a certificate with TLS Server extensions (--remote-cert-tls server)</string>
+ <string name="check_remote_tlscert">Checks whether the server uses a certificate with TLS Server extensions
+ (--remote-cert-tls server)
+ </string>
<string name="check_remote_tlscert_title">Expect TLS server certificate</string>
<string name="remote_tlscn_check_summary">Checks the Remote Server Certificate Subject DN</string>
<string name="remote_tlscn_check_title">Certificate Hostname Check</string>
- <string name="enter_tlscn_dialog">Specify the check used to verify the remote certificate DN (e.g. C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nSpecify the complete DN or the RDN (openvpn.blinkt.de in the example) or an RDN prefix for verification.\n\nWhen using RDN prefix \"Server\" matches \"Server-1\" and \"Server-2\"\n\nLeaving the text field empty will check the RDN against the server hostname.\n\nFor more details see the OpenVPN 2.3.1+ manpage under —verify-x509-name</string>
+ <string name="enter_tlscn_dialog">Specify the check used to verify the remote certificate DN (e.g. C=DE,
+ L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nSpecify the complete DN or the RDN
+ (openvpn.blinkt.de in the example) or an RDN prefix for verification.\n\nWhen using RDN prefix \"Server\"
+ matches \"Server-1\" and \"Server-2\"\n\nLeaving the text field empty will check the RDN against the server
+ hostname.\n\nFor more details see the OpenVPN 2.3.1+ manpage under —verify-x509-name
+ </string>
<string name="enter_tlscn_title">Remote certificate subject</string>
<string name="tls_key_auth">Enables the TLS Key Authentication</string>
<string name="tls_auth_file">TLS Auth File</string>
<string name="pull_on_summary">Requests IP addresses, routes and timing options from the server.</string>
- <string name="pull_off_summary">No information is requested from the server. Settings need to be specified below.</string>
+ <string name="pull_off_summary">No information is requested from the server. Settings need to be specified below.
+ </string>
<string name="use_pull">Pull Settings</string>
<string name="dns">DNS</string>
<string name="override_dns">Override DNS Settings by Server</string>
@@ -83,7 +97,9 @@
<string name="ignore_routes_summary">Ignore routed pushed by the server.</string>
<string name="default_route_summary">Redirects all Traffic over the VPN</string>
<string name="use_default_title">Use default Route</string>
- <string name="custom_route_message">Enter custom routes. Only enter destination in CIDR format. \"10.0.0.0/8 2002::/16\" would direct the networks 10.0.0.0/8 and 2002::/16 over the VPN.</string>
+ <string name="custom_route_message">Enter custom routes. Only enter destination in CIDR format. \"10.0.0.0/8
+ 2002::/16\" would direct the networks 10.0.0.0/8 and 2002::/16 over the VPN.
+ </string>
<string name="custom_routes_title">Custom Routes</string>
<string name="log_verbosity_level">Log verbosity level</string>
<string name="float_summary">Allows authenticated packets from any IP</string>
@@ -91,7 +107,9 @@
<string name="custom_options_title">Custom Options</string>
<string name="edit_vpn">Edit VPN Settings</string>
<string name="remove_vpn_query">Remove the VPN Profile \'%s\'?</string>
- <string name="tun_error_helpful">On some custom ICS images the permission on /dev/tun might be wrong, or the tun module might be missing completely. For CM9 images try the fix ownership option under general settings</string>
+ <string name="tun_error_helpful">On some custom ICS images the permission on /dev/tun might be wrong, or the tun
+ module might be missing completely. For CM9 images try the fix ownership option under general settings
+ </string>
<string name="tun_open_error">Failed to open the tun interface</string>
<string name="error">"Error: "</string>
<string name="clear">Clear</string>
@@ -101,29 +119,52 @@
<string name="dns_server_info">DNS Server: %1$s, Domain: %2$s</string>
<string name="routes_info">Routes: %s</string>
<string name="routes_info6">Routes IPv6: %s</string>
- <string name="ip_not_cidr">Got interface information %1$s and %2$s, assuming second address is peer address of remote. Using /32 netmask for local IP. Mode given by OpenVPN is \"%3$s\".</string>
- <string name="route_not_cidr">Cannot make sense of %1$s and %2$s as IP route with CIDR netmask, using /32 as netmask.</string>
+ <string name="ip_not_cidr">Got interface information %1$s and %2$s, assuming second address is peer address of
+ remote. Using /32 netmask for local IP. Mode given by OpenVPN is \"%3$s\".
+ </string>
+ <string name="route_not_cidr">Cannot make sense of %1$s and %2$s as IP route with CIDR netmask, using /32 as
+ netmask.
+ </string>
<string name="route_not_netip">Corrected route %1$s/%2$s to %3$s/%2$s</string>
- <string name="keychain_access">Cannot access the Android Keychain Certificates. This can be caused by a firmware upgrade or by restoring a backup of the app/app settings. Please edit the VPN and reselect the certificate under basic settings to recreate the permission to access the certificate.</string>
+ <string name="keychain_access">Cannot access the Android Keychain Certificates. This can be caused by a firmware
+ upgrade or by restoring a backup of the app/app settings. Please edit the VPN and reselect the certificate under
+ basic settings to recreate the permission to access the certificate.
+ </string>
<string name="version_info">%1$s %2$s</string>
<string name="send_logfile">Send log file</string>
<string name="send">Send</string>
<string name="ics_openvpn_log_file">ICS OpenVPN log file</string>
<string name="copied_entry">Copied log entry to clip board</string>
<string name="tap_mode">Tap Mode</string>
- <string name="faq_tap_mode">Tap Mode is not possible with the non root VPN API. Therefore this application cannot provide tap support</string>
- <string name="tap_faq2">Again? Are you kidding? No, tap mode is really not supported and sending more mail asking if it will be supported will not help.</string>
- <string name="tap_faq3">A third time? Actually, one could write a a tap emulator based on tun that would add layer2 information on send and strip layer2 information on receive. But this tap emulator would also have to implement ARP and possibly a DHCP client. I am not aware of anybody doing any work in this direction. Contact me if you want to start coding on this.</string>
+ <string name="faq_tap_mode">Tap Mode is not possible with the non root VPN API. Therefore this application cannot
+ provide tap support
+ </string>
+ <string name="tap_faq2">Again? Are you kidding? No, tap mode is really not supported and sending more mail asking if
+ it will be supported will not help.
+ </string>
+ <string name="tap_faq3">A third time? Actually, one could write a a tap emulator based on tun that would add layer2
+ information on send and strip layer2 information on receive. But this tap emulator would also have to implement
+ ARP and possibly a DHCP client. I am not aware of anybody doing any work in this direction. Contact me if you
+ want to start coding on this.
+ </string>
<string name="faq">FAQ</string>
<string name="copying_log_entries">Copying log entries</string>
- <string name="faq_copying">To copy a single log entry press and and hold on the log entry. To copy/send the whole log use the Send Log option. Use the hardware menu button if not visible in the GUI.</string>
+ <string name="faq_copying">To copy a single log entry press and and hold on the log entry. To copy/send the whole
+ log use the Send Log option. Use the hardware menu button if not visible in the GUI.
+ </string>
<string name="faq_shortcut">Shortcut to start</string>
- <string name="faq_howto_shortcut">You can place a shortcut to start OpenVPN on your desktop. Depending on your homescreen program you will have to add either a shortcut or a widget.</string>
+ <string name="faq_howto_shortcut">You can place a shortcut to start OpenVPN on your desktop. Depending on your
+ homescreen program you will have to add either a shortcut or a widget.
+ </string>
<string name="no_vpn_support_image">Your image does not support the VPNService API, sorry :(</string>
<string name="encryption">Encryption</string>
<string name="cipher_dialog_title">Enter encryption method</string>
- <string name="chipher_dialog_message">Enter the encryption cipher algorithm used by OpenVPN. Leave empty to use default cipher.</string>
- <string name="auth_dialog_message">Enter the authentication digest used for OpenVPN. Leave empty to use default digest.</string>
+ <string name="chipher_dialog_message">Enter the encryption cipher algorithm used by OpenVPN. Leave empty to use
+ default cipher.
+ </string>
+ <string name="auth_dialog_message">Enter the authentication digest used for OpenVPN. Leave empty to use default
+ digest.
+ </string>
<string name="settings_auth">Authentication/Encryption</string>
<string name="file_explorer_tab">File Explorer</string>
<string name="inline_file_tab">Inline File</string>
@@ -138,23 +179,45 @@
<string name="add_profile">add Profile</string>
<string name="import_could_not_open">Could not find file %1$s mentioned in the imported config file</string>
<string name="importing_config">Importing config file from source %1$s</string>
- <string name="import_warning_custom_options">Your configuration had a few configuration options that are not mapped to UI configurations. These options were added as custom configuration options. The custom configuration is displayed below:</string>
+ <string name="import_warning_custom_options">Your configuration had a few configuration options that are not mapped
+ to UI configurations. These options were added as custom configuration options. The custom configuration is
+ displayed below:
+ </string>
<string name="import_done">Done reading config file.</string>
<string name="nobind_summary">Do not bind to local address and port</string>
<string name="no_bind">No local binding</string>
<string name="import_configuration_file">Import configuration file</string>
<string name="faq_security_title">Security considerations</string>
- <string name="faq_security">"As OpenVPN is security sensitive a few notes about security are sensible. All data on the sdcard is inherently insecure. Every app can read it (for example this program requires no special sd card rights). The data of this application can only be read by the application itself. By using the import option for cacert/cert/key in the file dialog the data is stored in the VPN profile. The VPN profiles are only accessible by this application. (Do not forget to delete the copies on the sd card afterwards). Even though accessible only by this application the data is still unencrypted. By rooting the telephone or other exploits it may be possible to retrieve the data. Saved passwords are stored in plain text as well. For pkcs12 files it is highly recommended that you import them into the android keystore."</string>
+ <string name="faq_security">"As OpenVPN is security sensitive a few notes about security are sensible. All data on
+ the sdcard is inherently insecure. Every app can read it (for example this program requires no special sd card
+ rights). The data of this application can only be read by the application itself. By using the import option for
+ cacert/cert/key in the file dialog the data is stored in the VPN profile. The VPN profiles are only accessible
+ by this application. (Do not forget to delete the copies on the sd card afterwards). Even though accessible only
+ by this application the data is still unencrypted. By rooting the telephone or other exploits it may be possible
+ to retrieve the data. Saved passwords are stored in plain text as well. For pkcs12 files it is highly
+ recommended that you import them into the android keystore."
+ </string>
<string name="import_vpn">Import</string>
<string name="broken_image_cert_title">Error showing certificate selection</string>
- <string name="broken_image_cert">Got an exception trying to show the Android 4.0+ certificate selection dialog. This should never happen as this a standard feature of Android 4.0+. Maybe your Android ROM support for certificate storage is broken</string>
+ <string name="broken_image_cert">Got an exception trying to show the Android 4.0+ certificate selection dialog. This
+ should never happen as this a standard feature of Android 4.0+. Maybe your Android ROM support for certificate
+ storage is broken
+ </string>
<string name="ipv4">IPv4</string>
<string name="ipv6">IPv6</string>
<string name="speed_waiting">Waiting for state message…</string>
<string name="converted_profile">imported profile</string>
<string name="converted_profile_i">imported profile %d</string>
<string name="broken_images">Broken Images</string>
- <string name="broken_images_faq">&lt;p&gt;Official HTC images are known to have a strange routing problem causing traffic not to flow through the tunnel (See also &lt;a href="http://code.google.com/p/ics-openvpn/issues/detail?id=18"&gt;Issue 18&lt;/a&gt; in the bug tracker.)&lt;/p&gt;&lt;p&gt;Older official SONY images from Xperia Arc S and Xperia Ray have been reported to be missing the VPNService completely from the image. (See also &lt;a href="http://code.google.com/p/ics-openvpn/issues/detail?id=29"&gt;Issue 29&lt;/a&gt; in the bug tracker.)&lt;/p&gt;&lt;p&gt;On custom build images the tun module might be missing or the rights of /dev/tun might be wrong. Some CM9 images need the "Fix ownership" option under "Device specific hacks" enabled.&lt;/p&gt;&lt;p&gt;Most importantly: If your device has a broken Android image, report it to your vendor. The more people who report an issue to the vendor, the more likely they are to fix it.&lt;/p&gt;</string>
+ <string name="broken_images_faq">&lt;p&gt;Official HTC images are known to have a strange routing problem causing
+ traffic not to flow through the tunnel (See also &lt;a
+ href="http://code.google.com/p/ics-openvpn/issues/detail?id=18"&gt;Issue 18&lt;/a&gt; in the bug tracker.)&lt;/p&gt;&lt;p&gt;Older
+ official SONY images from Xperia Arc S and Xperia Ray have been reported to be missing the VPNService completely
+ from the image. (See also &lt;a href="http://code.google.com/p/ics-openvpn/issues/detail?id=29"&gt;Issue 29&lt;/a&gt;
+ in the bug tracker.)&lt;/p&gt;&lt;p&gt;On custom build images the tun module might be missing or the rights of
+ /dev/tun might be wrong. Some CM9 images need the "Fix ownership" option under "Device specific hacks" enabled.&lt;/p&gt;&lt;p&gt;Most
+ importantly: If your device has a broken Android image, report it to your vendor. The more people who report an
+ issue to the vendor, the more likely they are to fix it.&lt;/p&gt;</string>
<string name="pkcs12_file_encryption_key">PKCS12 File Encryption Key</string>
<string name="private_key_password">Private Key Password</string>
<string name="password">Password</string>
@@ -162,23 +225,38 @@
<string name="tls_authentication">TLS Authentication</string>
<string name="generated_config">Generated Config</string>
<string name="generalsettings">Settings</string>
- <string name="owner_fix_summary">Tries to set the owner of /dev/tun to system. Some CM9 images need this to make the VPNService API work. Requires root.</string>
+ <string name="owner_fix_summary">Tries to set the owner of /dev/tun to system. Some CM9 images need this to make the
+ VPNService API work. Requires root.
+ </string>
<string name="owner_fix">Fix ownership of /dev/tun</string>
<string name="generated_config_summary">Shows the generated OpenVPN Configuration File</string>
<string name="edit_profile_title">Editing \"%s\"</string>
<string name="building_configration">Building configuration…</string>
- <string name="netchange_summary">Turning this option on will force a reconnect if the network state is changed (e.g. WiFi to/from mobile)</string>
+ <string name="netchange_summary">Turning this option on will force a reconnect if the network state is changed (e.g.
+ WiFi to/from mobile)
+ </string>
<string name="netchange">Reconnect on network change</string>
<string name="cert_from_keystore">Got certificate \'%s\' from Keystore</string>
<string name="netstatus">Network Status: %s</string>
- <string name="extracahint">The CA cert is usually returned from the Android Keystore. Specify a separate certificate if you get certificate verification errors.</string>
+ <string name="extracahint">The CA cert is usually returned from the Android Keystore. Specify a separate certificate
+ if you get certificate verification errors.
+ </string>
<string name="select_file">Select</string>
- <string name="keychain_nocacert">No CA Certificate returned while reading from Android keystore. Auhtentication will probably fail.</string>
- <string name="show_log_summary">Shows the log window on connect. The log window can always be accessed from the notification status.</string>
+ <string name="keychain_nocacert">No CA Certificate returned while reading from Android keystore. Auhtentication will
+ probably fail.
+ </string>
+ <string name="show_log_summary">Shows the log window on connect. The log window can always be accessed from the
+ notification status.
+ </string>
<string name="show_log_window">Show log window</string>
<string name="mobile_info">Running on %1$s (%2$s) %3$s, Android API %4$d</string>
<string name="error_rsa_sign">Error signing with Android keystore key %1$s: %2$s</string>
- <string name="faq_system_dialogs">The VPN connection warning telling you that this app can intercept all traffic is imposed by the system to prevent abuse of the VPNService API.\nThe VPN connection notification (The key symbol) is also imposed by the Android system to signal an ongoing VPN connection. On some images this notification plays a sound.\nAndroid introduced these system dialogs for your own safety and made sure that they cannot be circumenvented. (On some images this unfortunely includes a notifciation sound)</string>
+ <string name="faq_system_dialogs">The VPN connection warning telling you that this app can intercept all traffic is
+ imposed by the system to prevent abuse of the VPNService API.\nThe VPN connection notification (The key symbol)
+ is also imposed by the Android system to signal an ongoing VPN connection. On some images this notification
+ plays a sound.\nAndroid introduced these system dialogs for your own safety and made sure that they cannot be
+ circumenvented. (On some images this unfortunely includes a notifciation sound)
+ </string>
<string name="faq_system_dialogs_title">Connection warning and notification sound</string>
<string name="translationby">English translation by Arne Schwabe&lt;arne@rfc2549.org&gt;</string>
<string name="ipdns">IP and DNS</string>
@@ -187,46 +265,100 @@
<string name="obscure">Obscure OpenVPN Settings. Normally not needed.</string>
<string name="advanced">Advanced</string>
<string name="export_config_title">ICS Openvpn Config</string>
- <string name="warn_no_dns">No DNS servers being used. Name resolution may not work. Consider setting custom DNS Servers. Please also note that Android will keep using your proxy settings specified for your mobile/Wi-Fi connection when no DNS servers are set.</string>
+ <string name="warn_no_dns">No DNS servers being used. Name resolution may not work. Consider setting custom DNS
+ Servers. Please also note that Android will keep using your proxy settings specified for your mobile/Wi-Fi
+ connection when no DNS servers are set.
+ </string>
<string name="dns_add_error">Could not add DNS Server \"%1$s\", rejected by the system: %2$s</string>
- <string name="faq_howto">&lt;p&gt;Get a working config (tested on your computer or download from your provider/organisation)&lt;/p&gt;&lt;p&gt;If it is a single file no with no extra pem/pks12 files you can email the file yourself and open the attachment. If you have multiple files put them on your sd card.&lt;/p&gt;&lt;p&gt;Click on the email attachment/Use the folder icon in the vpn list to import the config file&lt;/p&gt;&lt;p&gt;If there are errors about missing files put the missing files on your sd card.&lt;/p&gt;&lt;p&gt;Click on the save symbol to add the imported VPN to your VPN list&lt;/p&gt;&lt;p&gt;Connect the VPN by clicking on the name of the VPN&lt;/p&gt;&lt;p&gt;If there are error or warnings in the log try to understand the warnings/error and try to fix them&lt;/p&gt; </string>
+ <string name="ip_add_error">Could not configure IP Address \"%1$s\", rejected by the system: %2$s</string>
+ <string name="faq_howto">&lt;p&gt;Get a working config (tested on your computer or download from your
+ provider/organisation)&lt;/p&gt;&lt;p&gt;If it is a single file no with no extra pem/pks12 files you can email
+ the file yourself and open the attachment. If you have multiple files put them on your sd card.&lt;/p&gt;&lt;p&gt;Click
+ on the email attachment/Use the folder icon in the vpn list to import the config file&lt;/p&gt;&lt;p&gt;If there
+ are errors about missing files put the missing files on your sd card.&lt;/p&gt;&lt;p&gt;Click on the save symbol
+ to add the imported VPN to your VPN list&lt;/p&gt;&lt;p&gt;Connect the VPN by clicking on the name of the VPN&lt;/p&gt;&lt;p&gt;If
+ there are error or warnings in the log try to understand the warnings/error and try to fix
+ them&lt;/p&gt; </string>
<string name="faq_howto_title">Quick Start</string>
- <string name="setting_loadtun_summary">Try to load the tun.ko kernel module before trying to connect. Needs rooted devices.</string>
+ <string name="setting_loadtun_summary">Try to load the tun.ko kernel module before trying to connect. Needs rooted
+ devices.
+ </string>
<string name="setting_loadtun">Load tun module</string>
<string name="importpkcs12fromconfig">Import PKCS12 from configuration into Android Keystore</string>
<string name="getproxy_error">Error getting proxy settings: %s</string>
<string name="using_proxy">Using proxy %1$s %2$d</string>
<string name="use_system_proxy">Use system proxy</string>
- <string name="use_system_proxy_summary">Use the system wide configuration for HTTP/HTTPS proxies to connect.</string>
- <string name="donatewithpaypal">You can &lt;a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;amp;cmd=_s-xclick\"&gt;donate with PayPal&lt;/a&gt; </string>
- <string name="onbootrestartsummary">OpenVPN will reconnect a VPN if it was active on system reboot/shutdown. Please read the Connection warning FAQ before using this option.</string>
+ <string name="use_system_proxy_summary">Use the system wide configuration for HTTP/HTTPS proxies to connect.
+ </string>
+ <string name="donatewithpaypal">You can &lt;a
+ href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;amp;cmd=_s-xclick\"&gt;donate
+ with PayPal&lt;/a&gt; </string>
+ <string name="onbootrestartsummary">OpenVPN will reconnect a VPN if it was active on system reboot/shutdown. Please
+ read the Connection warning FAQ before using this option.
+ </string>
<string name="onbootrestart">Reconnect on reboot</string>
<string name="ignore">Ignore</string>
<string name="restart">Restart</string>
- <string name="restart_vpn_after_change">Configuration changes are applied after restarting the VPN. (Re)start the VPN now?</string>
+ <string name="restart_vpn_after_change">Configuration changes are applied after restarting the VPN. (Re)start the
+ VPN now?
+ </string>
<string name="configuration_changed">Configuration changed</string>
<string name="log_no_last_vpn">Could not determine last connected profile for editing</string>
<string name="faq_duplicate_notification_title">Duplicate notifications</string>
- <string name="faq_duplicate_notification">If Android is under system memory (RAM) pressure, apps and service which are not needed at the moment are removed from active memory. This terminates an ongoing VPN connection. To ensure that the connection/OpenVPN survives the service runs with higher priority. To run with higher priority the application must display a notification. The key notification icon is imposed by the system as described in the previous FAQ entry. It does not count as app notification for purpose of running with higher priority.</string>
+ <string name="faq_duplicate_notification">If Android is under system memory (RAM) pressure, apps and service which
+ are not needed at the moment are removed from active memory. This terminates an ongoing VPN connection. To
+ ensure that the connection/OpenVPN survives the service runs with higher priority. To run with higher priority
+ the application must display a notification. The key notification icon is imposed by the system as described in
+ the previous FAQ entry. It does not count as app notification for purpose of running with higher priority.
+ </string>
<string name="no_vpn_profiles_defined">No VPN profiles defined.</string>
<string name="add_new_vpn_hint">Use the &lt;img src=\"ic_menu_add\"/&gt; icon to add a new VPN</string>
- <string name="vpn_import_hint">Use the &lt;img src=\"ic_menu_archive\"/&gt; icon to import an existing (.ovpn or .conf) profile from your sdcard.</string>
+ <string name="vpn_import_hint">Use the &lt;img src=\"ic_menu_archive\"/&gt; icon to import an existing (.ovpn or
+ .conf) profile from your sdcard.
+ </string>
<string name="faq_hint">Be sure to also check out the FAQ. There is a quick start guide.</string>
<string name="faq_routing_title">Routing/Interface Configuration</string>
- <string name="faq_routing">The Routing and interface configuration is not done via traditionell ifconfig/route command but by using the VPNService API. This results in a different routing configuration than on other OSes. The configuration only consists of the IP of the tunnel interface and the networks that should be routed over this interface. Especially no peer partner address or gateway address is needed. Special routes to reach the VPN Server (for example added when using redirect-gateway) are not needed either. The application will consequently ignore these settings when importing a configuration. The app ensures with the VPNService API that the connection to the server is not routed through the VPN tunnel. Since only specifing networks to be routed via tunnel is supported extra routes not pointing to the tunnel cannot be supported either. (e.g. route x.x.x.x y.y.y.y net_gateway). The log windows shows the current configuration of the VPNService upon establishing a connection. </string>
+ <string name="faq_routing">The Routing and interface configuration is not done via traditionell ifconfig/route
+ command but by using the VPNService API. This results in a different routing configuration than on other OSes.
+ The configuration only consists of the IP of the tunnel interface and the networks that should be routed over
+ this interface. Especially no peer partner address or gateway address is needed. Special routes to reach the VPN
+ Server (for example added when using redirect-gateway) are not needed either. The application will consequently
+ ignore these settings when importing a configuration. The app ensures with the VPNService API that the
+ connection to the server is not routed through the VPN tunnel. Since only specifing networks to be routed via
+ tunnel is supported extra routes not pointing to the tunnel cannot be supported either. (e.g. route x.x.x.x
+ y.y.y.y net_gateway). The log windows shows the current configuration of the VPNService upon establishing a
+ connection.
+ </string>
<string name="persisttun_summary">Do not fallback to no VPN connection when OpenVPN is reconnecting.</string>
<string name="persistent_tun_title">Persistent tun</string>
<string name="openvpn_log">OpenVPN Log</string>
<string name="import_config">Import OpenVPN configuration</string>
<string name="battery_consumption_title">Battery consumption</string>
- <string name="baterry_consumption">In my personal tests the main reason for high battery consumption of OpenVPN are the keepalive packets. Most OpenVPN servers have a configuration directive like \'keepalive 10 60\' which causes the client and server to exchange keepalive packets every ten seconds. &lt;p&gt; While these packets are small and do not use much traffic, they keep the mobile radio network busy and increase the energy consumption. (See also &lt;a href="http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine"&gt;The Radio State Machine | Android Developers&lt;/a&gt;) &lt;p&gt; This keepalive setting cannot be changed on the client. Only the system administrator of the OpenVPN can change the setting. &lt;p&gt; Unfortunately using a keepalive larger than 60 seconds with UDP can cause some NAT gateways to drop the connection due to an inactivity timeout. Using TCP with a long keepalive timeout works, but tunneling TCP over TCP performs extremely poorly on connections with high packet loss. (See &lt;a href="http://sites.inka.de/bigred/devel/tcp-tcp.html"&gt;Why TCP Over TCP Is A Bad Idea&lt;/a&gt;)</string>
- <string name="faq_tethering">The Android Tethering feature (over WiFi, USB or Bluetooth) and the VPNService API (used by this program) do not work together. For more details see the &lt;a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">issue #34&lt;/a></string>
+ <string name="baterry_consumption">In my personal tests the main reason for high battery consumption of OpenVPN are
+ the keepalive packets. Most OpenVPN servers have a configuration directive like \'keepalive 10 60\' which causes
+ the client and server to exchange keepalive packets every ten seconds. &lt;p&gt; While these packets are small
+ and do not use much traffic, they keep the mobile radio network busy and increase the energy consumption. (See
+ also &lt;a
+ href="http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine"&gt;The
+ Radio State Machine | Android Developers&lt;/a&gt;) &lt;p&gt; This keepalive setting cannot be changed on the
+ client. Only the system administrator of the OpenVPN can change the setting. &lt;p&gt; Unfortunately using a
+ keepalive larger than 60 seconds with UDP can cause some NAT gateways to drop the connection due to an
+ inactivity timeout. Using TCP with a long keepalive timeout works, but tunneling TCP over TCP performs extremely
+ poorly on connections with high packet loss. (See &lt;a href="http://sites.inka.de/bigred/devel/tcp-tcp.html"&gt;Why
+ TCP Over TCP Is A Bad Idea&lt;/a&gt;)
+ </string>
+ <string name="faq_tethering">The Android Tethering feature (over WiFi, USB or Bluetooth) and the VPNService API
+ (used by this program) do not work together. For more details see the &lt;a
+ href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">issue #34&lt;/a>
+ </string>
<string name="vpn_tethering_title">VPN and Tethering</string>
<string name="connection_retries">Connection retries</string>
<string name="reconnection_settings">Reconnection settings</string>
<string name="connectretrymessage">Number of seconds to wait between connection attempts.</string>
<string name="connectretrywait">Seconds between connections</string>
- <string name="minidump_generated">OpenVPN crashed unexpectedly. Please consider using the send Minidump option in the main menu</string>
+ <string name="minidump_generated">OpenVPN crashed unexpectedly. Please consider using the send Minidump option in
+ the main menu
+ </string>
<string name="send_minidump">Send Minidump to developer</string>
<string name="send_minidump_summary">Sends debugging information about last crash to developer</string>
<string name="notifcation_title">OpenVPN - %s</string>
@@ -251,7 +383,10 @@
<string name="notifcation_title_notconnect">Not connected</string>
<string name="start_vpn_title">Connecting to VPN %s</string>
<string name="start_vpn_ticker">Connecting to VPN %s</string>
- <string name="jelly_keystore_alphanumeric_bug">Some versions of Android 4.1 have problems if the name of the keystore certificate contains non alphanumeric characters (like spaces, underscores or dashes). Try to reimport the certificate without special characters</string>
+ <string name="jelly_keystore_alphanumeric_bug">Some versions of Android 4.1 have problems if the name of the
+ keystore certificate contains non alphanumeric characters (like spaces, underscores or dashes). Try to reimport
+ the certificate without special characters
+ </string>
<string name="encryption_cipher">Encryption cipher</string>
<string name="packet_auth">Packets authentication</string>
<string name="auth_dialog_title">Enter packet authentication method</string>
@@ -265,21 +400,33 @@
<string name="add">Add</string>
<string name="send_config">Send config file</string>
<string name="complete_dn">Complete DN</string>
- <string name="remotetlsnote">Your imported configuration used the old DEPRECATED tls-remote option which uses a different DN format.</string>
+ <string name="remotetlsnote">Your imported configuration used the old DEPRECATED tls-remote option which uses a
+ different DN format.
+ </string>
<string name="rdn">RDN (common name)</string>
<string name="rdn_prefix">RDN prefix</string>
<string name="tls_remote_deprecated">tls-remote (DEPRECATED)</string>
- <string name="help_translate">You can help translating by visiting http://crowdin.net/project/ics-openvpn/invite</string>
+ <string name="help_translate">You can help translating by visiting http://crowdin.net/project/ics-openvpn/invite
+ </string>
<string name="prompt">%1$s attempts to control %2$s</string>
- <string name="remote_warning">By proceeding, you are giving the application permission to completely control OpenVPN for Android and to intercept all network traffic. <b> Do NOT accept unless you trust the application. </b> Otherwise, you run the risk of having your data compromised by malicious software."</string>
+ <string name="remote_warning">By proceeding, you are giving the application permission to completely control OpenVPN
+ for Android and to intercept all network traffic.
+ <b>Do NOT accept unless you trust the application.</b>
+ Otherwise, you run the risk of having your data compromised by malicious software."
+ </string>
<string name="remote_trust">I trust this application.</string>
<string name="no_external_app_allowed">No app allowed to use external API</string>
<string name="allowed_apps">Allowed apps: %s</string>
<string name="clearappsdialog">Clear list of allowed external apps?\nCurrent list of allowed apps:\n\n%s</string>
- <string name="screenoff_summary">"Pause VPN when screen is off and less than 64 kB transferred data in 60s. When the \"Persistent Tun\" option is enabled pausing the VPN will leave your device with NO network connectivity. Without the \"Persistent Tun\" option the device will have no VPN connection/protection.</string>
+ <string name="screenoff_summary">"Pause VPN when screen is off and less than 64 kB transferred data in 60s. When the
+ \"Persistent Tun\" option is enabled pausing the VPN will leave your device with NO network connectivity.
+ Without the \"Persistent Tun\" option the device will have no VPN connection/protection.
+ </string>
<string name="screenoff_title">Pause VPN connection after screen off</string>
<string name="screenoff_pause">Pausing connection in screen off state: less than %1$s in %2$ss</string>
- <string name="screen_nopersistenttun">Warning: Persistent tun not enabled for this VPN. Traffic will use the normal Internet connection when the screen is off.</string>
+ <string name="screen_nopersistenttun">Warning: Persistent tun not enabled for this VPN. Traffic will use the normal
+ Internet connection when the screen is off.
+ </string>
<string name="save_password">Save Password</string>
<string name="pauseVPN">Pause VPN</string>
<string name="resumevpn">Resume VPN</string>
diff --git a/src/de/blinkt/openvpn/core/OpenVpnService.java b/src/de/blinkt/openvpn/core/OpenVpnService.java
index 438f4286..e703e579 100644
--- a/src/de/blinkt/openvpn/core/OpenVpnService.java
+++ b/src/de/blinkt/openvpn/core/OpenVpnService.java
@@ -30,305 +30,293 @@ import java.util.Vector;
import static de.blinkt.openvpn.core.OpenVPN.ConnectionStatus.*;
public class OpenVpnService extends VpnService implements StateListener, Callback, ByteCountListener {
- public static final String START_SERVICE = "de.blinkt.openvpn.START_SERVICE";
- public static final String START_SERVICE_STICKY = "de.blinkt.openvpn.START_SERVICE_STICKY";
- public static final String ALWAYS_SHOW_NOTIFICATION = "de.blinkt.openvpn.NOTIFICATION_ALWAYS_VISIBLE";
-
+ public static final String START_SERVICE = "de.blinkt.openvpn.START_SERVICE";
+ public static final String START_SERVICE_STICKY = "de.blinkt.openvpn.START_SERVICE_STICKY";
+ public static final String ALWAYS_SHOW_NOTIFICATION = "de.blinkt.openvpn.NOTIFICATION_ALWAYS_VISIBLE";
public static final String DISCONNECT_VPN = "de.blinkt.openvpn.DISCONNECT_VPN";
private static final String PAUSE_VPN = "de.blinkt.openvpn.PAUSE_VPN";
private static final String RESUME_VPN = "de.blinkt.openvpn.RESUME_VPN";
+ private static final int OPENVPN_STATUS = 1;
+ private static boolean mNotificationAlwaysVisible = false;
+ private final Vector<String> mDnslist = new Vector<String>();
+ private final Vector<CIDRIP> mRoutes = new Vector<CIDRIP>();
+ private final Vector<String> mRoutesv6 = new Vector<String>();
+ private final IBinder mBinder = new LocalBinder();
+ private Thread mProcessThread = null;
+ private VpnProfile mProfile;
+ private String mDomain = null;
+ private CIDRIP mLocalIP = null;
+ private int mMtu;
+ private String mLocalIPv6 = null;
+ private DeviceStateReceiver mDeviceStateReceiver;
+ private boolean mDisplayBytecount = false;
+ private boolean mStarting = false;
+ private long mConnecttime;
+ private boolean mOvpn3 = false;
+ private OpenVPNManagement mManagement;
+
+ // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
+ public static String humanReadableByteCount(long bytes, boolean mbit) {
+ if (mbit)
+ bytes = bytes * 8;
+ int unit = mbit ? 1000 : 1024;
+ if (bytes < unit)
+ return bytes + (mbit ? " bit" : " B");
+
+ int exp = (int) (Math.log(bytes) / Math.log(unit));
+ String pre = (mbit ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (mbit ? "" : "");
+ if (mbit)
+ return String.format(Locale.getDefault(), "%.1f %sbit", bytes / Math.pow(unit, exp), pre);
+ else
+ return String.format(Locale.getDefault(), "%.1f %sB", bytes / Math.pow(unit, exp), pre);
+ }
+ @Override
+ public IBinder onBind(Intent intent) {
+ String action = intent.getAction();
+ if (action != null && action.equals(START_SERVICE))
+ return mBinder;
+ else
+ return super.onBind(intent);
+ }
- private Thread mProcessThread=null;
-
- private final Vector<String> mDnslist=new Vector<String>();
-
- private VpnProfile mProfile;
-
- private String mDomain=null;
-
- private final Vector<CIDRIP> mRoutes=new Vector<CIDRIP>();
- private final Vector<String> mRoutesv6=new Vector<String>();
-
- private CIDRIP mLocalIP=null;
-
- private int mMtu;
- private String mLocalIPv6=null;
- private DeviceStateReceiver mDeviceStateReceiver;
-
- private boolean mDisplayBytecount=false;
-
- private boolean mStarting=false;
-
- private long mConnecttime;
-
-
- private static final int OPENVPN_STATUS = 1;
-
- private static boolean mNotificationAlwaysVisible =false;
-
- private final IBinder mBinder = new LocalBinder();
- private boolean mOvpn3 = false;
-
- private OpenVPNManagement mManagement;
-
- public class LocalBinder extends Binder {
- public OpenVpnService getService() {
- // Return this instance of LocalService so clients can call public methods
- return OpenVpnService.this;
- }
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- String action = intent.getAction();
- if( action !=null && action.equals(START_SERVICE))
- return mBinder;
- else
- return super.onBind(intent);
- }
-
- @Override
- public void onRevoke() {
- mManagement.stopVPN();
- endVpnService();
- }
-
- // Similar to revoke but do not try to stop process
- public void processDied() {
- endVpnService();
- }
+ @Override
+ public void onRevoke() {
+ mManagement.stopVPN();
+ endVpnService();
+ }
- private void endVpnService() {
- mProcessThread=null;
- OpenVPN.removeByteCountListener(this);
- unregisterDeviceStateReceiver();
- ProfileManager.setConntectedVpnProfileDisconnected(this);
- if(!mStarting) {
- stopForeground(!mNotificationAlwaysVisible);
+ // Similar to revoke but do not try to stop process
+ public void processDied() {
+ endVpnService();
+ }
- if( !mNotificationAlwaysVisible) {
- stopSelf();
- OpenVPN.removeStateListener(this);
- }
- }
- }
+ private void endVpnService() {
+ mProcessThread = null;
+ OpenVPN.removeByteCountListener(this);
+ unregisterDeviceStateReceiver();
+ ProfileManager.setConntectedVpnProfileDisconnected(this);
+ if (!mStarting) {
+ stopForeground(!mNotificationAlwaysVisible);
+
+ if (!mNotificationAlwaysVisible) {
+ stopSelf();
+ OpenVPN.removeStateListener(this);
+ }
+ }
+ }
- private void showNotification(String msg, String tickerText, boolean lowpriority, long when, ConnectionStatus status) {
- String ns = Context.NOTIFICATION_SERVICE;
- NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
+ private void showNotification(String msg, String tickerText, boolean lowpriority, long when, ConnectionStatus status) {
+ String ns = Context.NOTIFICATION_SERVICE;
+ NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
- int icon = getIconByConnectionStatus(status);
+ int icon = getIconByConnectionStatus(status);
- android.app.Notification.Builder nbuilder = new Notification.Builder(this);
+ android.app.Notification.Builder nbuilder = new Notification.Builder(this);
- if(mProfile!=null)
- nbuilder.setContentTitle(getString(R.string.notifcation_title,mProfile.mName));
- else
- nbuilder.setContentTitle(getString(R.string.notifcation_title_notconnect));
+ if (mProfile != null)
+ nbuilder.setContentTitle(getString(R.string.notifcation_title, mProfile.mName));
+ else
+ nbuilder.setContentTitle(getString(R.string.notifcation_title_notconnect));
- nbuilder.setContentText(msg);
- nbuilder.setOnlyAlertOnce(true);
- nbuilder.setOngoing(true);
- nbuilder.setContentIntent(getLogPendingIntent());
- nbuilder.setSmallIcon(icon);
+ nbuilder.setContentText(msg);
+ nbuilder.setOnlyAlertOnce(true);
+ nbuilder.setOngoing(true);
+ nbuilder.setContentIntent(getLogPendingIntent());
+ nbuilder.setSmallIcon(icon);
- if(when !=0)
- nbuilder.setWhen(when);
+ if (when != 0)
+ nbuilder.setWhen(when);
- // Try to set the priority available since API 16 (Jellybean)
+ // Try to set the priority available since API 16 (Jellybean)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
- jbNotificationExtras(lowpriority, nbuilder);
+ jbNotificationExtras(lowpriority, nbuilder);
- if(tickerText!=null && !tickerText.equals(""))
- nbuilder.setTicker(tickerText);
+ if (tickerText != null && !tickerText.equals(""))
+ nbuilder.setTicker(tickerText);
- @SuppressWarnings("deprecation")
- Notification notification = nbuilder.getNotification();
+ @SuppressWarnings("deprecation")
+ Notification notification = nbuilder.getNotification();
- mNotificationManager.notify(OPENVPN_STATUS, notification);
- startForeground(OPENVPN_STATUS, notification);
- }
+ mNotificationManager.notify(OPENVPN_STATUS, notification);
+ startForeground(OPENVPN_STATUS, notification);
+ }
private int getIconByConnectionStatus(ConnectionStatus level) {
- switch (level) {
- case LEVEL_CONNECTED:
- return R.drawable.ic_stat_vpn;
- case LEVEL_AUTH_FAILED:
- case LEVEL_NONETWORK:
- case LEVEL_NOTCONNECTED:
- return R.drawable.ic_stat_vpn_offline;
- case LEVEL_CONNECTING_NO_SERVER_REPLY_YET:
- case LEVEL_WAITING_FOR_USER_INPUT:
- return R.drawable.ic_stat_vpn_outline;
- case LEVEL_CONNECTING_SERVER_REPLIED:
- return R.drawable.ic_stat_vpn_empty_halo;
- case LEVEL_VPNPAUSED:
- return android.R.drawable.ic_media_pause;
- case UNKNOWN_LEVEL:
- default:
- return R.drawable.ic_stat_vpn;
-
- }
- }
+ switch (level) {
+ case LEVEL_CONNECTED:
+ return R.drawable.ic_stat_vpn;
+ case LEVEL_AUTH_FAILED:
+ case LEVEL_NONETWORK:
+ case LEVEL_NOTCONNECTED:
+ return R.drawable.ic_stat_vpn_offline;
+ case LEVEL_CONNECTING_NO_SERVER_REPLY_YET:
+ case LEVEL_WAITING_FOR_USER_INPUT:
+ return R.drawable.ic_stat_vpn_outline;
+ case LEVEL_CONNECTING_SERVER_REPLIED:
+ return R.drawable.ic_stat_vpn_empty_halo;
+ case LEVEL_VPNPAUSED:
+ return android.R.drawable.ic_media_pause;
+ case UNKNOWN_LEVEL:
+ default:
+ return R.drawable.ic_stat_vpn;
+ }
+ }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private void jbNotificationExtras(boolean lowpriority,
- android.app.Notification.Builder nbuilder) {
- try {
- if(lowpriority) {
- Method setpriority = nbuilder.getClass().getMethod("setPriority", int.class);
- // PRIORITY_MIN == -2
- setpriority.invoke(nbuilder, -2 );
+ private void jbNotificationExtras(boolean lowpriority,
+ android.app.Notification.Builder nbuilder) {
+ try {
+ if (lowpriority) {
+ Method setpriority = nbuilder.getClass().getMethod("setPriority", int.class);
+ // PRIORITY_MIN == -2
+ setpriority.invoke(nbuilder, -2);
- Method setUsesChronometer = nbuilder.getClass().getMethod("setUsesChronometer", boolean.class);
- setUsesChronometer.invoke(nbuilder,true);
+ Method setUsesChronometer = nbuilder.getClass().getMethod("setUsesChronometer", boolean.class);
+ setUsesChronometer.invoke(nbuilder, true);
- }
+ }
- Intent disconnectVPN = new Intent(this,LogWindow.class);
+ Intent disconnectVPN = new Intent(this, LogWindow.class);
disconnectVPN.setAction(DISCONNECT_VPN);
PendingIntent disconnectPendingIntent = PendingIntent.getActivity(this, 0, disconnectVPN, 0);
nbuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel,
- getString(R.string.cancel_connection),disconnectPendingIntent);
+ getString(R.string.cancel_connection), disconnectPendingIntent);
- Intent pauseVPN = new Intent(this,OpenVpnService.class);
+ Intent pauseVPN = new Intent(this, OpenVpnService.class);
if (mDeviceStateReceiver == null || !mDeviceStateReceiver.isUserPaused()) {
pauseVPN.setAction(PAUSE_VPN);
- PendingIntent pauseVPNPending = PendingIntent.getService(this,0,pauseVPN,0);
+ PendingIntent pauseVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0);
nbuilder.addAction(android.R.drawable.ic_media_pause,
getString(R.string.pauseVPN), pauseVPNPending);
} else {
pauseVPN.setAction(RESUME_VPN);
- PendingIntent resumeVPNPending = PendingIntent.getService(this,0,pauseVPN,0);
+ PendingIntent resumeVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0);
nbuilder.addAction(android.R.drawable.ic_media_play,
getString(R.string.resumevpn), resumeVPNPending);
}
//ignore exception
- } catch (NoSuchMethodException nsm) {
+ } catch (NoSuchMethodException nsm) {
nsm.printStackTrace();
- } catch (IllegalArgumentException e) {
+ } catch (IllegalArgumentException e) {
e.printStackTrace();
- } catch (IllegalAccessException e) {
+ } catch (IllegalAccessException e) {
e.printStackTrace();
- } catch (InvocationTargetException e) {
+ } catch (InvocationTargetException e) {
e.printStackTrace();
- }
-
- }
-
- PendingIntent getLogPendingIntent() {
- // Let the configure Button show the Log
- Intent intent = new Intent(getBaseContext(),LogWindow.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
- PendingIntent startLW = PendingIntent.getActivity(this, 0, intent, 0);
- intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
- return startLW;
-
- }
-
- synchronized void registerDeviceStateReceiver(OpenVPNManagement magnagement) {
- // Registers BroadcastReceiver to track network connection changes.
- IntentFilter filter = new IntentFilter();
- filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- filter.addAction(Intent.ACTION_SCREEN_ON);
- mDeviceStateReceiver = new DeviceStateReceiver(magnagement);
- registerReceiver(mDeviceStateReceiver, filter);
- OpenVPN.addByteCountListener(mDeviceStateReceiver);
- }
-
- synchronized void unregisterDeviceStateReceiver() {
- if(mDeviceStateReceiver!=null)
- try {
- OpenVPN.removeByteCountListener(mDeviceStateReceiver);
- this.unregisterReceiver(mDeviceStateReceiver);
- } catch (IllegalArgumentException iae) {
- // I don't know why this happens:
- // java.lang.IllegalArgumentException: Receiver not registered: de.blinkt.openvpn.NetworkSateReceiver@41a61a10
- // Ignore for now ...
- iae.printStackTrace();
- }
- mDeviceStateReceiver=null;
- }
-
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
-
- if(intent != null && intent.getBooleanExtra(ALWAYS_SHOW_NOTIFICATION, false))
- mNotificationAlwaysVisible =true;
-
- OpenVPN.addStateListener(this);
- OpenVPN.addByteCountListener(this);
-
- if(intent != null && PAUSE_VPN.equals(intent.getAction()))
- {
- if(mDeviceStateReceiver!=null)
+ }
+
+ }
+
+ PendingIntent getLogPendingIntent() {
+ // Let the configure Button show the Log
+ Intent intent = new Intent(getBaseContext(), LogWindow.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+ PendingIntent startLW = PendingIntent.getActivity(this, 0, intent, 0);
+ intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+ return startLW;
+
+ }
+
+ synchronized void registerDeviceStateReceiver(OpenVPNManagement magnagement) {
+ // Registers BroadcastReceiver to track network connection changes.
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ mDeviceStateReceiver = new DeviceStateReceiver(magnagement);
+ registerReceiver(mDeviceStateReceiver, filter);
+ OpenVPN.addByteCountListener(mDeviceStateReceiver);
+ }
+
+ synchronized void unregisterDeviceStateReceiver() {
+ if (mDeviceStateReceiver != null)
+ try {
+ OpenVPN.removeByteCountListener(mDeviceStateReceiver);
+ this.unregisterReceiver(mDeviceStateReceiver);
+ } catch (IllegalArgumentException iae) {
+ // I don't know why this happens:
+ // java.lang.IllegalArgumentException: Receiver not registered: de.blinkt.openvpn.NetworkSateReceiver@41a61a10
+ // Ignore for now ...
+ iae.printStackTrace();
+ }
+ mDeviceStateReceiver = null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+
+ if (intent != null && intent.getBooleanExtra(ALWAYS_SHOW_NOTIFICATION, false))
+ mNotificationAlwaysVisible = true;
+
+ OpenVPN.addStateListener(this);
+ OpenVPN.addByteCountListener(this);
+
+ if (intent != null && PAUSE_VPN.equals(intent.getAction())) {
+ if (mDeviceStateReceiver != null)
mDeviceStateReceiver.userPause(true);
return START_NOT_STICKY;
}
- if(intent != null && RESUME_VPN.equals(intent.getAction()))
- {
- if(mDeviceStateReceiver!=null)
+ if (intent != null && RESUME_VPN.equals(intent.getAction())) {
+ if (mDeviceStateReceiver != null)
mDeviceStateReceiver.userPause(false);
return START_NOT_STICKY;
}
- if(intent != null && START_SERVICE.equals(intent.getAction()))
- return START_NOT_STICKY;
- if(intent != null && START_SERVICE_STICKY.equals(intent.getAction())) {
- return START_REDELIVER_INTENT;
- }
-
- assert(intent!=null);
-
- // Extract information from the intent.
- String prefix = getPackageName();
- String[] argv = intent.getStringArrayExtra(prefix + ".ARGV");
- String nativelibdir = intent.getStringExtra(prefix + ".nativelib");
- String profileUUID = intent.getStringExtra(prefix + ".profileUUID");
-
- mProfile = ProfileManager.get(this,profileUUID);
-
- String startTitle = getString(R.string.start_vpn_title, mProfile.mName);
- String startTicker = getString(R.string.start_vpn_ticker, mProfile.mName);
- showNotification(startTitle, startTicker,
- false,0, LEVEL_CONNECTING_NO_SERVER_REPLY_YET);
+ if (intent != null && START_SERVICE.equals(intent.getAction()))
+ return START_NOT_STICKY;
+ if (intent != null && START_SERVICE_STICKY.equals(intent.getAction())) {
+ return START_REDELIVER_INTENT;
+ }
- // Set a flag that we are starting a new VPN
- mStarting=true;
- // Stop the previous session by interrupting the thread.
- if(mManagement!=null && mManagement.stopVPN())
- // an old was asked to exit, wait 1s
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
+ assert (intent != null);
+
+ // Extract information from the intent.
+ String prefix = getPackageName();
+ String[] argv = intent.getStringArrayExtra(prefix + ".ARGV");
+ String nativelibdir = intent.getStringExtra(prefix + ".nativelib");
+ String profileUUID = intent.getStringExtra(prefix + ".profileUUID");
+
+ mProfile = ProfileManager.get(this, profileUUID);
+
+ String startTitle = getString(R.string.start_vpn_title, mProfile.mName);
+ String startTicker = getString(R.string.start_vpn_ticker, mProfile.mName);
+ showNotification(startTitle, startTicker,
+ false, 0, LEVEL_CONNECTING_NO_SERVER_REPLY_YET);
+
+ // Set a flag that we are starting a new VPN
+ mStarting = true;
+ // Stop the previous session by interrupting the thread.
+ if (mManagement != null && mManagement.stopVPN())
+ // an old was asked to exit, wait 1s
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
e.printStackTrace();
- }
+ }
- if (mProcessThread!=null) {
- mProcessThread.interrupt();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
+ if (mProcessThread != null) {
+ mProcessThread.interrupt();
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
e.printStackTrace();
- }
- }
- // An old running VPN should now be exited
- mStarting=false;
+ }
+ }
+ // An old running VPN should now be exited
+ mStarting = false;
// Open the Management Interface
@@ -346,17 +334,17 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
}
// Start a new session by creating a new thread.
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- mOvpn3 = prefs.getBoolean("ovpn3", false);
- mOvpn3 = false;
+ mOvpn3 = prefs.getBoolean("ovpn3", false);
+ mOvpn3 = false;
- Runnable processThread;
- if(mOvpn3) {
+ Runnable processThread;
+ if (mOvpn3) {
- OpenVPNManagement mOpenVPN3 = instantiateOpenVPN3Core();
- processThread = (Runnable) mOpenVPN3;
- mManagement = mOpenVPN3;
+ OpenVPNManagement mOpenVPN3 = instantiateOpenVPN3Core();
+ processThread = (Runnable) mOpenVPN3;
+ mManagement = mOpenVPN3;
} else {
@@ -364,289 +352,280 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
processThread = new OpenVPNThread(this, argv, env, nativelibdir);
}
- mProcessThread = new Thread(processThread, "OpenVPNProcessThread");
- mProcessThread.start();
+ mProcessThread = new Thread(processThread, "OpenVPNProcessThread");
+ mProcessThread.start();
- if(mDeviceStateReceiver!=null)
- unregisterDeviceStateReceiver();
-
- registerDeviceStateReceiver(mManagement);
+ if (mDeviceStateReceiver != null)
+ unregisterDeviceStateReceiver();
+ registerDeviceStateReceiver(mManagement);
- ProfileManager.setConnectedVpnProfile(this, mProfile);
+
+ ProfileManager.setConnectedVpnProfile(this, mProfile);
return START_NOT_STICKY;
}
- private OpenVPNManagement instantiateOpenVPN3Core() {
- return null;
- }
-
- @Override
- public void onDestroy() {
- if (mProcessThread != null) {
- mManagement.stopVPN();
+ private OpenVPNManagement instantiateOpenVPN3Core() {
+ return null;
+ }
- mProcessThread.interrupt();
- }
- if (mDeviceStateReceiver!= null) {
- this.unregisterReceiver(mDeviceStateReceiver);
- }
- // Just in case unregister for state
- OpenVPN.removeStateListener(this);
+ @Override
+ public void onDestroy() {
+ if (mProcessThread != null) {
+ mManagement.stopVPN();
- }
+ mProcessThread.interrupt();
+ }
+ if (mDeviceStateReceiver != null) {
+ this.unregisterReceiver(mDeviceStateReceiver);
+ }
+ // Just in case unregister for state
+ OpenVPN.removeStateListener(this);
+ }
+ public ParcelFileDescriptor openTun() {
+ Builder builder = new Builder();
- public ParcelFileDescriptor openTun() {
- Builder builder = new Builder();
+ if (mLocalIP == null && mLocalIPv6 == null) {
+ OpenVPN.logMessage(0, "", getString(R.string.opentun_no_ipaddr));
+ return null;
+ }
- if(mLocalIP==null && mLocalIPv6==null) {
- OpenVPN.logMessage(0, "", getString(R.string.opentun_no_ipaddr));
- return null;
- }
+ if (mLocalIP != null) {
+ try {
+ builder.addAddress(mLocalIP.mIp, mLocalIP.len);
+ } catch (IllegalArgumentException iae) {
+ OpenVPN.logError(R.string.dns_add_error, mLocalIP, iae.getLocalizedMessage());
+ return null;
+ }
+ }
- if(mLocalIP!=null) {
- builder.addAddress(mLocalIP.mIp, mLocalIP.len);
- }
+ if (mLocalIPv6 != null) {
+ String[] ipv6parts = mLocalIPv6.split("/");
+ try {
+ builder.addAddress(ipv6parts[0], Integer.parseInt(ipv6parts[1]));
+ } catch (IllegalArgumentException iae) {
+ OpenVPN.logError(R.string.dns_add_error, mLocalIPv6, iae.getLocalizedMessage());
+ return null;
+ }
- if(mLocalIPv6!=null) {
- String[] ipv6parts = mLocalIPv6.split("/");
- builder.addAddress(ipv6parts[0],Integer.parseInt(ipv6parts[1]));
- }
+ }
- for (String dns : mDnslist ) {
- try {
- builder.addDnsServer(dns);
- } catch (IllegalArgumentException iae) {
- OpenVPN.logError(R.string.dns_add_error, dns,iae.getLocalizedMessage());
- }
- }
+ for (String dns : mDnslist) {
+ try {
+ builder.addDnsServer(dns);
+ } catch (IllegalArgumentException iae) {
+ OpenVPN.logError(R.string.dns_add_error, dns, iae.getLocalizedMessage());
+ }
+ }
- builder.setMtu(mMtu);
+ builder.setMtu(mMtu);
- for (CIDRIP route:mRoutes) {
- try {
- builder.addRoute(route.mIp, route.len);
- } catch (IllegalArgumentException ia) {
- OpenVPN.logMessage(0, "", getString(R.string.route_rejected) + route + " " + ia.getLocalizedMessage());
- }
- }
+ for (CIDRIP route : mRoutes) {
+ try {
+ builder.addRoute(route.mIp, route.len);
+ } catch (IllegalArgumentException ia) {
+ OpenVPN.logMessage(0, "", getString(R.string.route_rejected) + route + " " + ia.getLocalizedMessage());
+ }
+ }
- for(String v6route:mRoutesv6) {
- try {
- String[] v6parts = v6route.split("/");
- builder.addRoute(v6parts[0],Integer.parseInt(v6parts[1]));
- } catch (IllegalArgumentException ia) {
- OpenVPN.logMessage(0, "", getString(R.string.route_rejected) + v6route + " " + ia.getLocalizedMessage());
- }
- }
+ for (String v6route : mRoutesv6) {
+ try {
+ String[] v6parts = v6route.split("/");
+ builder.addRoute(v6parts[0], Integer.parseInt(v6parts[1]));
+ } catch (IllegalArgumentException ia) {
+ OpenVPN.logMessage(0, "", getString(R.string.route_rejected) + v6route + " " + ia.getLocalizedMessage());
+ }
+ }
- if(mDomain!=null)
- builder.addSearchDomain(mDomain);
+ if (mDomain != null)
+ builder.addSearchDomain(mDomain);
- OpenVPN.logInfo(R.string.last_openvpn_tun_config);
- OpenVPN.logInfo(R.string.local_ip_info,mLocalIP.mIp,mLocalIP.len,mLocalIPv6, mMtu);
- OpenVPN.logInfo(R.string.dns_server_info, joinString(mDnslist), mDomain);
- OpenVPN.logInfo(R.string.routes_info, joinString(mRoutes));
- OpenVPN.logInfo(R.string.routes_info6, joinString(mRoutesv6));
+ OpenVPN.logInfo(R.string.last_openvpn_tun_config);
+ OpenVPN.logInfo(R.string.local_ip_info, mLocalIP.mIp, mLocalIP.len, mLocalIPv6, mMtu);
+ OpenVPN.logInfo(R.string.dns_server_info, joinString(mDnslist), mDomain);
+ OpenVPN.logInfo(R.string.routes_info, joinString(mRoutes));
+ OpenVPN.logInfo(R.string.routes_info6, joinString(mRoutesv6));
- String session = mProfile.mName;
- if(mLocalIP!=null && mLocalIPv6!=null)
- session = getString(R.string.session_ipv6string,session, mLocalIP, mLocalIPv6);
- else if (mLocalIP !=null)
- session= getString(R.string.session_ipv4string, session, mLocalIP);
+ String session = mProfile.mName;
+ if (mLocalIP != null && mLocalIPv6 != null)
+ session = getString(R.string.session_ipv6string, session, mLocalIP, mLocalIPv6);
+ else if (mLocalIP != null)
+ session = getString(R.string.session_ipv4string, session, mLocalIP);
- builder.setSession(session);
+ builder.setSession(session);
- // No DNS Server, log a warning
- if(mDnslist.size()==0)
- OpenVPN.logInfo(R.string.warn_no_dns);
+ // No DNS Server, log a warning
+ if (mDnslist.size() == 0)
+ OpenVPN.logInfo(R.string.warn_no_dns);
- // Reset information
- mDnslist.clear();
- mRoutes.clear();
- mRoutesv6.clear();
- mLocalIP=null;
- mLocalIPv6=null;
- mDomain=null;
+ // Reset information
+ mDnslist.clear();
+ mRoutes.clear();
+ mRoutesv6.clear();
+ mLocalIP = null;
+ mLocalIPv6 = null;
+ mDomain = null;
- builder.setConfigureIntent(getLogPendingIntent());
+ builder.setConfigureIntent(getLogPendingIntent());
- try {
+ try {
return builder.establish();
- } catch (Exception e) {
- OpenVPN.logMessage(0, "", getString(R.string.tun_open_error));
- OpenVPN.logMessage(0, "", getString(R.string.error) + e.getLocalizedMessage());
- OpenVPN.logMessage(0, "", getString(R.string.tun_error_helpful));
- return null;
- }
-
- }
-
-
- // Ugly, but java has no such method
- private <T> String joinString(Vector<T> vec) {
- String ret = "";
- if(vec.size() > 0){
- ret = vec.get(0).toString();
- for(int i=1;i < vec.size();i++) {
- ret = ret + ", " + vec.get(i).toString();
- }
- }
- return ret;
- }
-
-
-
-
-
-
- public void addDNS(String dns) {
- mDnslist.add(dns);
- }
-
-
- public void setDomain(String domain) {
- if(mDomain==null) {
- mDomain=domain;
- }
- }
-
- public void addRoute(String dest, String mask) {
- CIDRIP route = new CIDRIP(dest, mask);
- if(route.len == 32 && !mask.equals("255.255.255.255")) {
- OpenVPN.logMessage(0, "", getString(R.string.route_not_cidr,dest,mask));
- }
-
- if(route.normalise())
- OpenVPN.logMessage(0, "", getString(R.string.route_not_netip,dest,route.len,route.mIp));
-
- mRoutes.add(route);
- }
-
- public void addRoutev6(String extra) {
- mRoutesv6.add(extra);
- }
-
- public void setMtu(int mtu) {
- mMtu=mtu;
- }
-
- public void setLocalIP(CIDRIP cdrip)
- {
- mLocalIP=cdrip;
- }
-
-
- public void setLocalIP(String local, String netmask,int mtu, String mode) {
- mLocalIP = new CIDRIP(local, netmask);
- mMtu = mtu;
-
- if(mLocalIP.len == 32 && !netmask.equals("255.255.255.255")) {
- // get the netmask as IP
- long netint = CIDRIP.getInt(netmask);
- if(Math.abs(netint - mLocalIP.getInt()) ==1) {
- if("net30".equals(mode))
- mLocalIP.len=30;
- else
- mLocalIP.len=31;
- } else {
- OpenVPN.logMessage(0, "", getString(R.string.ip_not_cidr, local,netmask,mode));
- }
- }
- }
-
- public void setLocalIPv6(String ipv6addr) {
- mLocalIPv6 = ipv6addr;
- }
-
- @Override
- public void updateState(String state,String logmessage, int resid, ConnectionStatus level) {
- // If the process is not running, ignore any state,
- // Notification should be invisible in this state
- doSendBroadcast(state, level);
- if(mProcessThread==null && !mNotificationAlwaysVisible)
- return;
-
- // Display byte count only after being connected
-
- {
- if (level == LEVEL_WAITING_FOR_USER_INPUT) {
- // The user is presented a dialog of some kind, no need to inform the user
- // with a notifcation
- return;
- } else if(level == LEVEL_CONNECTED) {
- mDisplayBytecount = true;
- mConnecttime = System.currentTimeMillis();
- } else {
- mDisplayBytecount = false;
- }
-
- // Other notifications are shown,
- // This also mean we are no longer connected, ignore bytecount messages until next
- // CONNECTED
- String ticker = getString(resid);
- showNotification(getString(resid) +" " + logmessage,ticker,false,0, level);
-
- }
- }
-
- private void doSendBroadcast(String state, ConnectionStatus level) {
- Intent vpnstatus = new Intent();
- vpnstatus.setAction("de.blinkt.openvpn.VPN_STATUS");
- vpnstatus.putExtra("status", level.toString());
- vpnstatus.putExtra("detailstatus", state);
- sendBroadcast(vpnstatus, permission.ACCESS_NETWORK_STATE);
- }
-
- @Override
- public void updateByteCount(long in, long out, long diffin, long diffout) {
- if(mDisplayBytecount) {
- String netstat = String.format(getString(R.string.statusline_bytecount),
- humanReadableByteCount(in, false),
- humanReadableByteCount(diffin/ OpenVPNManagement.mBytecountInterval, true),
- humanReadableByteCount(out, false),
- humanReadableByteCount(diffout/ OpenVPNManagement.mBytecountInterval, true));
-
- boolean lowpriority = !mNotificationAlwaysVisible;
- showNotification(netstat,null,lowpriority,mConnecttime, LEVEL_CONNECTED);
- }
-
- }
-
- // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
- public static String humanReadableByteCount(long bytes, boolean mbit) {
- if(mbit)
- bytes = bytes *8;
- int unit = mbit ? 1000 : 1024;
- if (bytes < unit)
- return bytes + (mbit ? " bit" : " B");
-
- int exp = (int) (Math.log(bytes) / Math.log(unit));
- String pre = (mbit ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (mbit ? "" : "");
- if(mbit)
- return String.format(Locale.getDefault(),"%.1f %sbit", bytes / Math.pow(unit, exp), pre);
- else
- return String.format(Locale.getDefault(),"%.1f %sB", bytes / Math.pow(unit, exp), pre);
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- Runnable r = msg.getCallback();
- if(r!=null){
- r.run();
- return true;
- } else {
- return false;
- }
- }
-
- public OpenVPNManagement getManagement() {
- return mManagement;
- }
+ } catch (Exception e) {
+ OpenVPN.logMessage(0, "", getString(R.string.tun_open_error));
+ OpenVPN.logMessage(0, "", getString(R.string.error) + e.getLocalizedMessage());
+ OpenVPN.logMessage(0, "", getString(R.string.tun_error_helpful));
+ return null;
+ }
+
+ }
+
+ // Ugly, but java has no such method
+ private <T> String joinString(Vector<T> vec) {
+ String ret = "";
+ if (vec.size() > 0) {
+ ret = vec.get(0).toString();
+ for (int i = 1; i < vec.size(); i++) {
+ ret = ret + ", " + vec.get(i).toString();
+ }
+ }
+ return ret;
+ }
+
+ public void addDNS(String dns) {
+ mDnslist.add(dns);
+ }
+
+ public void setDomain(String domain) {
+ if (mDomain == null) {
+ mDomain = domain;
+ }
+ }
+
+ public void addRoute(String dest, String mask) {
+ CIDRIP route = new CIDRIP(dest, mask);
+ if (route.len == 32 && !mask.equals("255.255.255.255")) {
+ OpenVPN.logMessage(0, "", getString(R.string.route_not_cidr, dest, mask));
+ }
+
+ if (route.normalise())
+ OpenVPN.logMessage(0, "", getString(R.string.route_not_netip, dest, route.len, route.mIp));
+
+ mRoutes.add(route);
+ }
+
+ public void addRoutev6(String extra) {
+ mRoutesv6.add(extra);
+ }
+
+ public void setMtu(int mtu) {
+ mMtu = mtu;
+ }
+
+ public void setLocalIP(CIDRIP cdrip) {
+ mLocalIP = cdrip;
+ }
+
+ public void setLocalIP(String local, String netmask, int mtu, String mode) {
+ mLocalIP = new CIDRIP(local, netmask);
+ mMtu = mtu;
+
+ if (mLocalIP.len == 32 && !netmask.equals("255.255.255.255")) {
+ // get the netmask as IP
+ long netint = CIDRIP.getInt(netmask);
+ if (Math.abs(netint - mLocalIP.getInt()) == 1) {
+ if ("net30".equals(mode))
+ mLocalIP.len = 30;
+ else
+ mLocalIP.len = 31;
+ } else {
+ OpenVPN.logMessage(0, "", getString(R.string.ip_not_cidr, local, netmask, mode));
+ }
+ }
+ }
+
+ public void setLocalIPv6(String ipv6addr) {
+ mLocalIPv6 = ipv6addr;
+ }
+
+ @Override
+ public void updateState(String state, String logmessage, int resid, ConnectionStatus level) {
+ // If the process is not running, ignore any state,
+ // Notification should be invisible in this state
+ doSendBroadcast(state, level);
+ if (mProcessThread == null && !mNotificationAlwaysVisible)
+ return;
+
+ // Display byte count only after being connected
+
+ {
+ if (level == LEVEL_WAITING_FOR_USER_INPUT) {
+ // The user is presented a dialog of some kind, no need to inform the user
+ // with a notifcation
+ return;
+ } else if (level == LEVEL_CONNECTED) {
+ mDisplayBytecount = true;
+ mConnecttime = System.currentTimeMillis();
+ } else {
+ mDisplayBytecount = false;
+ }
+
+ // Other notifications are shown,
+ // This also mean we are no longer connected, ignore bytecount messages until next
+ // CONNECTED
+ String ticker = getString(resid);
+ showNotification(getString(resid) + " " + logmessage, ticker, false, 0, level);
+
+ }
+ }
+
+ private void doSendBroadcast(String state, ConnectionStatus level) {
+ Intent vpnstatus = new Intent();
+ vpnstatus.setAction("de.blinkt.openvpn.VPN_STATUS");
+ vpnstatus.putExtra("status", level.toString());
+ vpnstatus.putExtra("detailstatus", state);
+ sendBroadcast(vpnstatus, permission.ACCESS_NETWORK_STATE);
+ }
+
+ @Override
+ public void updateByteCount(long in, long out, long diffin, long diffout) {
+ if (mDisplayBytecount) {
+ String netstat = String.format(getString(R.string.statusline_bytecount),
+ humanReadableByteCount(in, false),
+ humanReadableByteCount(diffin / OpenVPNManagement.mBytecountInterval, true),
+ humanReadableByteCount(out, false),
+ humanReadableByteCount(diffout / OpenVPNManagement.mBytecountInterval, true));
+
+ boolean lowpriority = !mNotificationAlwaysVisible;
+ showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED);
+ }
+
+ }
+
+ @Override
+ public boolean handleMessage(Message msg) {
+ Runnable r = msg.getCallback();
+ if (r != null) {
+ r.run();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public OpenVPNManagement getManagement() {
+ return mManagement;
+ }
+
+ public class LocalBinder extends Binder {
+ public OpenVpnService getService() {
+ // Return this instance of LocalService so clients can call public methods
+ return OpenVpnService.this;
+ }
+ }
}