diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 0a04128..0000000 --- a/LICENSE +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/README.md b/README.md deleted file mode 100644 index cd36e2b..0000000 --- a/README.md +++ /dev/null @@ -1,52 +0,0 @@ -![LibreSpeed-Android Logo](https://github.com/adolfintel/speedtest-android/blob/master/.github/Readme-Logo.png?raw=true) - -# LibreSpeed Android Template -The Speedtest Android template allows you to configure and distribute an Android app that performs a speedtest using your existing [LibreSpeed](https://github.com/librespeed/speedtest) server(s). - -The template is easy to configure, customize and distribute. - -## Try it - -[Get it on F-Droid](https://f-droid.org/packages/com.dosse.speedtest/) - -Alternatively, you can [download a demo APK](https://downloads.fdossena.com/geth.php?r=speedtest-android-apk) - -## Compatibility -Android 4.0.3 and up (SDK 15), all architectures. - -## Features -* Download -* Upload -* Ping -* Jitter -* IP Address, ISP, distance from server (optional) -* Telemetry (optional) -* Results sharing (optional) -* Multiple Points of Test (optional) - -![Screenshot](https://github.com/librespeed/speedtest-android/blob/master/.github/screenshots.png?raw=true) - -## Server requirements -One or more servers with [LibreSpeed](https://github.com/librespeed/speedtest) installed. - -## Donate -[![Donate with Liberapay](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/fdossena/donate) -[Donate with PayPal](https://www.paypal.me/sineisochronic) - -## License -Copyright (C) 2019 Federico Dossena - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . diff --git a/Speedtest-Android/.gitignore b/Speedtest-Android/.gitignore deleted file mode 100644 index 603b140..0000000 --- a/Speedtest-Android/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -/build -/captures -.externalNativeBuild -.cxx diff --git a/Speedtest-Android/.idea/codeStyles/Project.xml b/Speedtest-Android/.idea/codeStyles/Project.xml deleted file mode 100644 index 681f41a..0000000 --- a/Speedtest-Android/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
-
-
\ No newline at end of file diff --git a/Speedtest-Android/.idea/gradle.xml b/Speedtest-Android/.idea/gradle.xml deleted file mode 100644 index d291b3d..0000000 --- a/Speedtest-Android/.idea/gradle.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Speedtest-Android/.idea/misc.xml b/Speedtest-Android/.idea/misc.xml deleted file mode 100644 index 37a7509..0000000 --- a/Speedtest-Android/.idea/misc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/Speedtest-Android/.idea/runConfigurations.xml b/Speedtest-Android/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460..0000000 --- a/Speedtest-Android/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Speedtest-Android/.idea/vcs.xml b/Speedtest-Android/.idea/vcs.xml deleted file mode 100644 index 6c0b863..0000000 --- a/Speedtest-Android/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Speedtest-Android/app/.gitignore b/Speedtest-Android/app/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/Speedtest-Android/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/Speedtest-Android/app/build.gradle b/Speedtest-Android/app/build.gradle deleted file mode 100644 index b664645..0000000 --- a/Speedtest-Android/app/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 28 - buildToolsVersion "29.0.0" - defaultConfig { - applicationId "your.name.here.speedtest" - minSdkVersion 15 - targetSdkVersion 28 - versionCode 5 - versionName '1.1.3' - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) -} diff --git a/Speedtest-Android/app/proguard-rules.pro b/Speedtest-Android/app/proguard-rules.pro deleted file mode 100644 index f1b4245..0000000 --- a/Speedtest-Android/app/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/Speedtest-Android/app/src/main/AndroidManifest.xml b/Speedtest-Android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 685d61d..0000000 --- a/Speedtest-Android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Speedtest-Android/app/src/main/assets/ServerList.json b/Speedtest-Android/app/src/main/assets/ServerList.json deleted file mode 100644 index 7719f0f..0000000 --- a/Speedtest-Android/app/src/main/assets/ServerList.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "name":"Helsinki, Finland", - "server":"//fi.openspeed.org", - "dlURL":"garbage.php", - "ulURL":"empty.php", - "pingURL":"empty.php", - "getIpURL":"getIP.php" - } -] diff --git a/Speedtest-Android/app/src/main/assets/SpeedtestConfig.json b/Speedtest-Android/app/src/main/assets/SpeedtestConfig.json deleted file mode 100644 index 0967ef4..0000000 --- a/Speedtest-Android/app/src/main/assets/SpeedtestConfig.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/Speedtest-Android/app/src/main/assets/TelemetryConfig.json b/Speedtest-Android/app/src/main/assets/TelemetryConfig.json deleted file mode 100644 index 0967ef4..0000000 --- a/Speedtest-Android/app/src/main/assets/TelemetryConfig.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/Speedtest-Android/app/src/main/assets/privacy_en.html b/Speedtest-Android/app/src/main/assets/privacy_en.html deleted file mode 100644 index 053c477..0000000 --- a/Speedtest-Android/app/src/main/assets/privacy_en.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - -

Privacy Policy

-

This Speedtest app is configured with telemetry enabled.

-

What data we collect

-

- At the end of the test, the following data is collected and stored: -

-

-

How we use the data

-

- Data collected through this service is used to: -

- No personal information is disclosed to third parties. -

-

Your consent

-

- By starting the test, you consent to the terms of this privacy policy. -

-

Data removal

-

- If you want to have your information deleted, you need to provide either the ID of the test or your IP address. This is the only way to identify your data, without this information we won't be able to comply with your request.

- Contact this email address for all deletion requests: TO BE FILLED BY DEVELOPER. -

- - diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/Speedtest.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/Speedtest.java deleted file mode 100644 index dae6064..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/Speedtest.java +++ /dev/null @@ -1,203 +0,0 @@ -package com.fdossena.speedtest.core; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; - -import com.fdossena.speedtest.core.config.SpeedtestConfig; -import com.fdossena.speedtest.core.config.TelemetryConfig; -import com.fdossena.speedtest.core.serverSelector.ServerSelector; -import com.fdossena.speedtest.core.serverSelector.TestPoint; -import com.fdossena.speedtest.core.worker.SpeedtestWorker; - -public class Speedtest { - private ArrayList servers=new ArrayList<>(); - private TestPoint selectedServer=null; - private SpeedtestConfig config=new SpeedtestConfig(); - private TelemetryConfig telemetryConfig=new TelemetryConfig(); - private int state=0; //0=configs, 1=test points, 2=server selection, 3=ready, 4=testing, 5=finished - - private Object mutex=new Object(); - - private String originalExtra=""; - - public Speedtest(){ - - } - - public void setSpeedtestConfig(SpeedtestConfig c){ - synchronized (mutex){ - if(state!=0) throw new IllegalStateException("Cannot change config at this moment"); - config=c.clone(); - String extra=config.getTelemetry_extra(); - if(extra!=null&&!extra.isEmpty()) originalExtra=extra; - } - } - - public void setTelemetryConfig(TelemetryConfig c){ - synchronized (mutex) { - if (state != 0) throw new IllegalStateException("Cannot change config at this moment"); - telemetryConfig = c.clone(); - } - } - - public void addTestPoint(TestPoint t){ - synchronized (mutex) { - if (state == 0) state = 1; - if (state > 1) throw new IllegalStateException("Cannot add test points at this moment"); - servers.add(t); - } - } - - public void addTestPoints(TestPoint[] s){ - synchronized (mutex) { - for (TestPoint t : s) addTestPoint(t); - } - } - - public void addTestPoint(JSONObject json){ - synchronized (mutex) { - addTestPoint(new TestPoint(json)); - } - } - - public void addTestPoints(JSONArray json){ - synchronized (mutex) { - for (int i = 0; i < json.length(); i++) - try { - addTestPoint(json.getJSONObject(i)); - } catch (JSONException t) { - } - } - } - - public TestPoint[] getTestPoints(){ - synchronized (mutex) { - return servers.toArray(new TestPoint[0]); - } - } - - private ServerSelector ss=null; - public void selectServer(final ServerSelectedHandler callback){ - synchronized (mutex) { - if (state == 0) throw new IllegalStateException("No test points added"); - if (state == 2) throw new IllegalStateException("Server selection is in progress"); - if (state > 2) throw new IllegalStateException("Server already selected"); - state = 2; - ss = new ServerSelector(getTestPoints(), config.getPing_connectTimeout()) { - @Override - public void onServerSelected(TestPoint server) { - selectedServer = server; - synchronized (mutex) { - if (server != null) state = 3; else state = 1; - } - callback.onServerSelected(server); - } - }; - ss.start(); - } - } - - public void setSelectedServer(TestPoint t){ - synchronized (mutex) { - if (state == 2) throw new IllegalStateException("Server selection is in progress"); - if (t == null) throw new IllegalArgumentException("t is null"); - selectedServer = t; - state = 3; - } - } - - private SpeedtestWorker st=null; - public void start(final SpeedtestHandler callback){ - synchronized (mutex) { - if (state < 3) throw new IllegalStateException("Server hasn't been selected yet"); - if (state == 4) throw new IllegalStateException("Test already running"); - state = 4; - try { - JSONObject extra = new JSONObject(); - if (originalExtra != null && !originalExtra.isEmpty()) - extra.put("extra", originalExtra); - extra.put("server", selectedServer.getName()); - config.setTelemetry_extra(extra.toString()); - } catch (Throwable t) { - } - st = new SpeedtestWorker(selectedServer, config, telemetryConfig) { - @Override - public void onDownloadUpdate(double dl, double progress) { - callback.onDownloadUpdate(dl, progress); - } - - @Override - public void onUploadUpdate(double ul, double progress) { - callback.onUploadUpdate(ul, progress); - } - - @Override - public void onPingJitterUpdate(double ping, double jitter, double progress) { - callback.onPingJitterUpdate(ping, jitter, progress); - } - - @Override - public void onIPInfoUpdate(String ipInfo) { - callback.onIPInfoUpdate(ipInfo); - } - - @Override - public void onTestIDReceived(String id) { - String shareURL=prepareShareURL(telemetryConfig); - if(shareURL!=null) shareURL=String.format(shareURL,id); - callback.onTestIDReceived(id,shareURL); - } - - @Override - public void onEnd() { - synchronized (mutex) { - state = 5; - } - callback.onEnd(); - } - - @Override - public void onCriticalFailure(String err) { - synchronized (mutex) { - state = 5; - } - callback.onCriticalFailure(err); - } - }; - } - } - - private String prepareShareURL(TelemetryConfig c){ - if(c==null) return null; - String server=c.getServer(), shareURL=c.getShareURL(); - if(server==null||server.isEmpty()||shareURL==null||shareURL.isEmpty()) return null; - if(!server.endsWith("/")) server=server+"/"; - while(shareURL.startsWith("/")) shareURL=shareURL.substring(1); - if(server.startsWith("//")) server="https:"+server; - return server+shareURL; - } - - public void abort(){ - synchronized (mutex) { - if (state == 2) ss.stopASAP(); - if (state == 4) st.abort(); - state = 5; - } - } - - public static abstract class ServerSelectedHandler{ - public abstract void onServerSelected(TestPoint server); - } - public static abstract class SpeedtestHandler{ - public abstract void onDownloadUpdate(double dl, double progress); - public abstract void onUploadUpdate(double ul, double progress); - public abstract void onPingJitterUpdate(double ping, double jitter, double progress); - public abstract void onIPInfoUpdate(String ipInfo); - public abstract void onTestIDReceived(String id, String shareURL); - public abstract void onEnd(); - public abstract void onCriticalFailure(String err); - } -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/base/Connection.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/base/Connection.java deleted file mode 100644 index 132be25..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/base/Connection.java +++ /dev/null @@ -1,237 +0,0 @@ -package com.fdossena.speedtest.core.base; - -import android.os.Build; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintStream; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.URL; -import java.util.HashMap; -import java.util.Locale; - -import javax.net.SocketFactory; -import javax.net.ssl.SSLSocketFactory; - -public class Connection { - private Socket socket; - private String host; private int port; - private int mode=MODE_NOT_SET; - private static final int MODE_NOT_SET=0, MODE_HTTP=1, MODE_HTTPS=2; - - private static final String USER_AGENT="Speedtest-Android/1.1.3 (SDK "+Build.VERSION.SDK_INT+"; "+Build.PRODUCT+"; Android "+Build.VERSION.RELEASE+")", - LOCALE= Build.VERSION.SDK_INT>=21?Locale.getDefault().toLanguageTag():null; - - public Connection(String url, int connectTimeout, int soTimeout, int recvBuffer, int sendBuffer){ - boolean tryHTTP=false, tryHTTPS=false; - Locale.getDefault().toString(); - if(url.startsWith("http://")){ - tryHTTP=true; - try{ - URL u=new URL(url); - host=u.getHost(); - port=u.getPort(); - }catch(Throwable t){ - throw new IllegalArgumentException("Malformed URL (HTTP)"); - } - }else if(url.startsWith("https://")){ - tryHTTPS=true; - try{ - URL u=new URL(url); - host=u.getHost(); - port=u.getPort(); - }catch(Throwable t){ - throw new IllegalArgumentException("Malformed URL (HTTPS)"); - } - }else if(url.startsWith("//")){ - tryHTTP=true; - tryHTTPS=true; - try{ - URL u=new URL("http:"+url); - host=u.getHost(); - port=u.getPort(); - }catch(Throwable t){ - throw new IllegalArgumentException("Malformed URL (HTTP/HTTPS)"); - } - }else{ - throw new IllegalArgumentException("Malformed URL (Unknown or unspecified protocol)"); - } - try{ - if(tryHTTPS){ - SocketFactory factory = SSLSocketFactory.getDefault(); - socket=factory.createSocket(); - if(connectTimeout>0){ - socket.connect(new InetSocketAddress(host, port==-1?443:port),connectTimeout); - }else{ - socket.connect(new InetSocketAddress(host, port==-1?443:port)); - } - mode=MODE_HTTPS; - } - }catch(Throwable t){} - try{ - if(tryHTTP){ - SocketFactory factory = SocketFactory.getDefault(); - socket=factory.createSocket(); - if(connectTimeout>0) { - socket.connect(new InetSocketAddress(host, port == -1 ? 80 : port), connectTimeout); - }else{ - socket.connect(new InetSocketAddress(host, port == -1 ? 80 : port)); - } - mode=MODE_HTTP; - } - }catch(Throwable t){} - if(mode==MODE_NOT_SET) throw new IllegalStateException("Failed to connect"); - if(soTimeout>0) { - try { - socket.setSoTimeout(soTimeout); - } catch(Throwable t){} - } - if(recvBuffer>0){ - try{ - socket.setReceiveBufferSize(recvBuffer); - }catch(Throwable t){} - } - if(sendBuffer>0){ - try{ - socket.setSendBufferSize(sendBuffer); - }catch(Throwable t){} - } - } - - private static final int DEFAULT_CONNECT_TIMEOUT=2000, DEFAULT_SO_TIMEOUT=5000; - public Connection(String url){ - this(url,DEFAULT_CONNECT_TIMEOUT,DEFAULT_SO_TIMEOUT,-1,-1); - } - - public InputStream getInputStream(){ - try{ - return socket.getInputStream(); - }catch (Throwable t){ - return null; - } - } - - public OutputStream getOutputStream(){ - try{ - return socket.getOutputStream(); - }catch (Throwable t){ - return null; - } - } - - private PrintStream ps=null; - public PrintStream getPrintStream(){ - if(ps==null){ - try{ - ps=new PrintStream(getOutputStream(),false,"utf-8"); - }catch(Throwable t){ - ps=null; - } - } - return ps; - } - private InputStreamReader isr=null; - public InputStreamReader getInputStreamReader(){ - if(isr==null){ - try{ - isr=new InputStreamReader(getInputStream(),"utf-8"); - }catch(Throwable t){ - isr=null; - } - } - return isr; - } - - public void GET(String path, boolean keepAlive) throws Exception{ - try{ - if(!path.startsWith("/")) path="/"+path; - PrintStream ps=getPrintStream(); - ps.print("GET "+path+" HTTP/1.1\r\n"); - ps.print("Host: "+host+"\r\n"); - ps.print("User-Agent: "+USER_AGENT); - ps.print("Connection: "+(keepAlive?"keep-alive":"close")+"\r\n"); - ps.print("Accept-Encoding: identity\r\n"); - if(LOCALE!=null) ps.print("Accept-Language: "+LOCALE+"\r\n"); - ps.print("\r\n"); - ps.flush(); - }catch (Throwable t){ - throw new Exception("Failed to send GET request"); - } - } - - public void POST(String path, boolean keepAlive, String contentType, long contentLength) throws Exception{ - try{ - if(!path.startsWith("/")) path="/"+path; - PrintStream ps=getPrintStream(); - ps.print("POST "+path+" HTTP/1.1\r\n"); - ps.print("Host: "+host+"\r\n"); - ps.print("User-Agent: "+USER_AGENT+"\r\n"); - ps.print("Connection: "+(keepAlive?"keep-alive":"close")+"\r\n"); - ps.print("Accept-Encoding: identity\r\n"); - if(LOCALE!=null) ps.print("Accept-Language: "+LOCALE+"\r\n"); - if(contentType!=null) ps.print("Content-Type: "+contentType+"\r\n"); - ps.print("Content-Encoding: identity\r\n"); - if(contentLength>=0) ps.print("Content-Length: "+contentLength+"\r\n"); - ps.print("\r\n"); - ps.flush(); - }catch (Throwable t){ - throw new Exception("Failed to send POST request"); - } - } - - public String readLineUnbuffered(){ - try { - InputStreamReader in = getInputStreamReader(); - StringBuilder sb=new StringBuilder(); - while(true){ - int c=in.read(); - if(c==-1) break; - sb.append((char)c); - if(c=='\n') break; - } - return sb.toString(); - }catch(Throwable t){ - return null; - } - } - - public HashMap parseResponseHeaders() throws Exception{ - try{ - HashMap ret=new HashMap<>(); - String s=readLineUnbuffered(); - if(!s.contains("200 OK")) throw new Exception("Did not receive an HTTP 200 ("+s.trim()+")"); - while(true){ - s=readLineUnbuffered(); - if(s.trim().isEmpty()) break; - if(s.contains(":")){ - ret.put(s.substring(0,s.indexOf(":")).trim().toLowerCase(),s.substring(s.indexOf(":")+1).trim()); - } - } - return ret; - }catch(Throwable t){ - throw new Exception("Failed to get response headers ("+t+")"); - } - } - - public void close(){ - try{ - socket.close(); - }catch(Throwable t){} - socket=null; - } - - public String getHost() { - return host; - } - - public int getPort() { - return port; - } - - public int getMode() { - return mode; - } - -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/base/Utils.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/base/Utils.java deleted file mode 100644 index 51d5cd2..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/base/Utils.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.fdossena.speedtest.core.base; - -import java.net.URLEncoder; - -public class Utils { - public static String urlEncode(String s){ - try{return URLEncoder.encode(s, "utf-8");}catch(Throwable t){return null;} - } - public static void sleep(long ms){ - try{Thread.sleep(ms);}catch (Throwable t){} - } - public static void sleep(long ms, int ns){ - try{Thread.sleep(ms,ns);}catch (Throwable t){} - } - public static String url_sep(String url){ - if(url.contains("?")) return "&"; else return "?"; - } -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/config/SpeedtestConfig.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/config/SpeedtestConfig.java deleted file mode 100644 index c7d7584..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/config/SpeedtestConfig.java +++ /dev/null @@ -1,415 +0,0 @@ -package com.fdossena.speedtest.core.config; - -import org.json.JSONException; -import org.json.JSONObject; - -public class SpeedtestConfig { - private int dl_ckSize=100, ul_ckSize=20; - private int dl_parallelStreams=3, ul_parallelStreams=3; - private int dl_streamDelay=300, ul_streamDelay=300; - private double dl_graceTime=1.5, ul_graceTime=1.5; - private int dl_connectTimeout=5000, dl_soTimeout=10000, ul_connectTimeout=5000, ul_soTimeout=10000, ping_connectTimeout=2000, ping_soTimeout=5000; - private int dl_recvBuffer=-1, dl_sendBuffer=-1, ul_recvBuffer=-1, ul_sendBuffer=16384, ping_recvBuffer=-1, ping_sendBuffer=-1; - private String errorHandlingMode=ONERROR_ATTEMPT_RESTART; - public static final String ONERROR_FAIL="fail", ONERROR_ATTEMPT_RESTART="attempt-restart", ONERROR_MUST_RESTART="must-restart"; - private int time_dl_max=15, time_ul_max=15; - private boolean time_auto=true; - private int count_ping=10; - private String telemetry_extra=""; - private double overheadCompensationFactor=1.06; - private boolean getIP_isp=true; - private String getIP_distance=DISTANCE_KM; - public static final String DISTANCE_NO="no", DISTANCE_MILES="mi", DISTANCE_KM="km"; - private boolean useMebibits=false; - private String test_order="IP_D_U"; - - private void check(){ - if(dl_ckSize<1) throw new IllegalArgumentException("dl_ckSize must be at least 1"); - if(ul_ckSize<1) throw new IllegalArgumentException("ul_ckSize must be at least 1"); - if(dl_parallelStreams<1) throw new IllegalArgumentException("dl_parallelStreams must be at least 1"); - if(ul_parallelStreams<1) throw new IllegalArgumentException("ul_parallelStreams must be at least 1"); - if(dl_streamDelay<0) throw new IllegalArgumentException("dl_streamDelay must be at least 0"); - if(ul_streamDelay<0) throw new IllegalArgumentException("ul_streamDelay must be at least 0"); - if(dl_graceTime<0) throw new IllegalArgumentException("dl_graceTime must be at least 0"); - if(ul_graceTime<0) throw new IllegalArgumentException("ul_graceTime must be at least 0"); - if(!(errorHandlingMode.equals(ONERROR_FAIL)||errorHandlingMode.equals(ONERROR_ATTEMPT_RESTART)||errorHandlingMode.equals(ONERROR_MUST_RESTART))) throw new IllegalArgumentException("errorHandlingMode must be fail, attempt-restart, or must-restart"); - if(time_dl_max<1) throw new IllegalArgumentException("time_dl_max must be at least 1"); - if(time_ul_max<1) throw new IllegalArgumentException("time_ul_max must be at least 1"); - if(count_ping<1) throw new IllegalArgumentException("count_ping must be at least 1"); - if(overheadCompensationFactor<1) throw new IllegalArgumentException("overheadCompensationFactor must be at least 1"); - if(!(getIP_distance.equals(DISTANCE_NO)||getIP_distance.equals(DISTANCE_KM)||getIP_distance.equals(DISTANCE_MILES))) throw new IllegalArgumentException("getIP_distance must be no, km or miles"); - for(char c:test_order.toCharArray()){ - if(!(c=='I'||c=='P'||c=='D'||c=='U'||c=='_')) throw new IllegalArgumentException("test_order can only contain characters I, P, D, U, _"); - } - } - - public SpeedtestConfig(){ - check(); - } - - public SpeedtestConfig(int dl_ckSize, int ul_ckSize, int dl_parallelStreams, int ul_parallelStreams, int dl_streamDelay, int ul_streamDelay, double dl_graceTime, double ul_graceTime, int dl_connectTimeout, int dl_soTimeout, int ul_connectTimeout, int ul_soTimeout, int ping_connectTimeout, int ping_soTimeout, int dl_recvBuffer, int dl_sendBuffer, int ul_recvBuffer, int ul_sendBuffer, int ping_recvBuffer, int ping_sendBuffer, String errorHandlingMode, int time_dl_max, int time_ul_max, boolean time_auto, int count_ping, String telemetry_extra, double overheadCompensationFactor, boolean getIP_isp, String getIP_distance, boolean useMebibits, String test_order) { - this.dl_ckSize = dl_ckSize; - this.ul_ckSize = ul_ckSize; - this.dl_parallelStreams = dl_parallelStreams; - this.ul_parallelStreams = ul_parallelStreams; - this.dl_streamDelay = dl_streamDelay; - this.ul_streamDelay = ul_streamDelay; - this.dl_graceTime = dl_graceTime; - this.ul_graceTime = ul_graceTime; - this.dl_connectTimeout = dl_connectTimeout; - this.dl_soTimeout = dl_soTimeout; - this.ul_connectTimeout = ul_connectTimeout; - this.ul_soTimeout = ul_soTimeout; - this.ping_connectTimeout = ping_connectTimeout; - this.ping_soTimeout = ping_soTimeout; - this.dl_recvBuffer = dl_recvBuffer; - this.dl_sendBuffer = dl_sendBuffer; - this.ul_recvBuffer = ul_recvBuffer; - this.ul_sendBuffer = ul_sendBuffer; - this.ping_recvBuffer = ping_recvBuffer; - this.ping_sendBuffer = ping_sendBuffer; - this.errorHandlingMode = errorHandlingMode; - this.time_dl_max = time_dl_max; - this.time_ul_max = time_ul_max; - this.time_auto = time_auto; - this.count_ping = count_ping; - this.telemetry_extra = telemetry_extra; - this.overheadCompensationFactor = overheadCompensationFactor; - this.getIP_isp = getIP_isp; - this.getIP_distance = getIP_distance; - this.useMebibits = useMebibits; - this.test_order = test_order; - check(); - } - - public SpeedtestConfig(JSONObject json){ - try { - if (json.has("dl_ckSize")) this.dl_ckSize = json.getInt("dl_ckSize"); - if (json.has("ul_ckSize")) this.ul_ckSize = json.getInt("ul_ckSize"); - if (json.has("dl_parallelStreams")) - this.dl_parallelStreams = json.getInt("dl_parallelStreams"); - if (json.has("ul_parallelStreams")) - this.ul_parallelStreams = json.getInt("ul_parallelStreams"); - if (json.has("dl_streamDelay")) this.dl_streamDelay = json.getInt("dl_streamDelay"); - if (json.has("ul_streamDelay")) this.ul_streamDelay = json.getInt("ul_streamDelay"); - if (json.has("dl_graceTime")) this.dl_graceTime = json.getDouble("dl_graceTime"); - if (json.has("ul_graceTime")) this.ul_graceTime = json.getDouble("ul_graceTime"); - if (json.has("dl_connectTimeout")) - this.dl_connectTimeout = json.getInt("dl_connectTimeout"); - if (json.has("ul_connectTimeout")) - this.ul_connectTimeout = json.getInt("ul_connectTimeout"); - if (json.has("ping_connectTimeout")) - this.ping_connectTimeout = json.getInt("ping_connectTimeout"); - if (json.has("dl_soTimeout")) this.dl_soTimeout = json.getInt("dl_soTimeout"); - if (json.has("ul_soTimeout")) this.ul_soTimeout = json.getInt("ul_soTimeout"); - if (json.has("ping_soTimeout")) this.ping_soTimeout = json.getInt("ping_soTimeout"); - if (json.has("dl_recvBuffer")) this.dl_recvBuffer = json.getInt("dl_recvBuffer"); - if (json.has("ul_recvBuffer")) this.ul_recvBuffer = json.getInt("ul_recvBuffer"); - if (json.has("ping_recvBuffer")) this.ping_recvBuffer = json.getInt("ping_recvBuffer"); - if (json.has("dl_sendBuffer")) this.dl_sendBuffer = json.getInt("dl_sendBuffer"); - if (json.has("ul_sendBuffer")) this.ul_sendBuffer = json.getInt("ul_sendBuffer"); - if (json.has("ping_sendBuffer")) this.ping_sendBuffer = json.getInt("ping_sendBuffer"); - if (json.has("errorHandlingMode")) - this.errorHandlingMode = json.getString("errorHandlingMode"); - if (json.has("time_dl_max")) this.time_dl_max = json.getInt("time_dl_max"); - if (json.has("time_ul_max")) this.time_ul_max = json.getInt("time_ul_max"); - if (json.has("count_ping")) this.count_ping = json.getInt("count_ping"); - if (json.has("telemetry_extra")) - this.telemetry_extra = json.getString("telemetry_extra"); - if (json.has("overheadCompensationFactor")) - this.overheadCompensationFactor = json.getDouble("overheadCompensationFactor"); - if (json.has("getIP_isp")) this.getIP_isp = json.getBoolean("getIP_isp"); - if (json.has("getIP_distance")) this.getIP_distance = json.getString("getIP_distance"); - if (json.has("test_order")) this.test_order = json.getString("test_order"); - if (json.has("useMebibits")) this.useMebibits = json.getBoolean("useMebibits"); - check(); - }catch(JSONException t){ - throw new IllegalArgumentException("Invalid JSON ("+t.toString()+")"); - } - } - - public int getDl_ckSize() { - return dl_ckSize; - } - - public int getUl_ckSize() { - return ul_ckSize; - } - - public int getDl_parallelStreams() { - return dl_parallelStreams; - } - - public int getUl_parallelStreams() { - return ul_parallelStreams; - } - - public int getDl_streamDelay() { - return dl_streamDelay; - } - - public int getUl_streamDelay() { - return ul_streamDelay; - } - - public double getDl_graceTime() { - return dl_graceTime; - } - - public double getUl_graceTime() { - return ul_graceTime; - } - - public int getDl_connectTimeout() { - return dl_connectTimeout; - } - - public int getDl_soTimeout() { - return dl_soTimeout; - } - - public int getUl_connectTimeout() { - return ul_connectTimeout; - } - - public int getUl_soTimeout() { - return ul_soTimeout; - } - - public int getPing_connectTimeout() { - return ping_connectTimeout; - } - - public int getPing_soTimeout() { - return ping_soTimeout; - } - - public int getDl_recvBuffer() { - return dl_recvBuffer; - } - - public int getDl_sendBuffer() { - return dl_sendBuffer; - } - - public int getUl_recvBuffer() { - return ul_recvBuffer; - } - - public int getUl_sendBuffer() { - return ul_sendBuffer; - } - - public int getPing_recvBuffer() { - return ping_recvBuffer; - } - - public int getPing_sendBuffer() { - return ping_sendBuffer; - } - - public String getErrorHandlingMode() { - return errorHandlingMode; - } - - public int getTime_dl_max() { - return time_dl_max; - } - - public int getTime_ul_max() { - return time_ul_max; - } - - public boolean getTime_auto() { - return time_auto; - } - - public int getCount_ping() { - return count_ping; - } - - public String getTelemetry_extra() { - return telemetry_extra; - } - - public double getOverheadCompensationFactor() { - return overheadCompensationFactor; - } - - public boolean getGetIP_isp() { - return getIP_isp; - } - - public String getGetIP_distance() { - return getIP_distance; - } - - public boolean getUseMebibits() { - return useMebibits; - } - - public String getTest_order() { - return test_order; - } - - public void setDl_ckSize(int dl_ckSize) { - if(dl_ckSize<1) throw new IllegalArgumentException("dl_ckSize must be at least 1"); - this.dl_ckSize = dl_ckSize; - } - - public void setUl_ckSize(int ul_ckSize) { - if(ul_ckSize<1) throw new IllegalArgumentException("ul_ckSize must be at least 1"); - this.ul_ckSize = ul_ckSize; - } - - public void setDl_parallelStreams(int dl_parallelStreams) { - if(dl_parallelStreams<1) throw new IllegalArgumentException("dl_parallelStreams must be at least 1"); - this.dl_parallelStreams = dl_parallelStreams; - } - - public void setUl_parallelStreams(int ul_parallelStreams) { - if(ul_parallelStreams<1) throw new IllegalArgumentException("ul_parallelStreams must be at least 1"); - this.ul_parallelStreams = ul_parallelStreams; - } - - public void setDl_streamDelay(int dl_streamDelay) { - if(dl_streamDelay<0) throw new IllegalArgumentException("dl_streamDelay must be at least 0"); - this.dl_streamDelay = dl_streamDelay; - } - - public void setUl_streamDelay(int ul_streamDelay) { - if(ul_streamDelay<0) throw new IllegalArgumentException("ul_streamDelay must be at least 0"); - this.ul_streamDelay = ul_streamDelay; - } - - public void setDl_graceTime(double dl_graceTime) { - if(dl_graceTime<0) throw new IllegalArgumentException("dl_graceTime must be at least 0"); - this.dl_graceTime = dl_graceTime; - } - - public void setUl_graceTime(double ul_graceTime) { - if(ul_graceTime<0) throw new IllegalArgumentException("ul_graceTime must be at least 0"); - this.ul_graceTime = ul_graceTime; - } - - public void setDl_connectTimeout(int dl_connectTimeout) { - - this.dl_connectTimeout = dl_connectTimeout; - } - - public void setDl_soTimeout(int dl_soTimeout) { - - this.dl_soTimeout = dl_soTimeout; - } - - public void setUl_connectTimeout(int ul_connectTimeout) { - - this.ul_connectTimeout = ul_connectTimeout; - } - - public void setUl_soTimeout(int ul_soTimeout) { - - this.ul_soTimeout = ul_soTimeout; - } - - public void setPing_connectTimeout(int ping_connectTimeout) { - - this.ping_connectTimeout = ping_connectTimeout; - } - - public void setPing_soTimeout(int ping_soTimeout) { - - this.ping_soTimeout = ping_soTimeout; - } - - public void setDl_recvBuffer(int dl_recvBuffer) { - - this.dl_recvBuffer = dl_recvBuffer; - } - - public void setDl_sendBuffer(int dl_sendBuffer) { - - this.dl_sendBuffer = dl_sendBuffer; - } - - public void setUl_recvBuffer(int ul_recvBuffer) { - - this.ul_recvBuffer = ul_recvBuffer; - } - - public void setUl_sendBuffer(int ul_sendBuffer) { - - this.ul_sendBuffer = ul_sendBuffer; - } - - public void setPing_recvBuffer(int ping_recvBuffer) { - - this.ping_recvBuffer = ping_recvBuffer; - } - - public void setPing_sendBuffer(int ping_sendBuffer) { - - this.ping_sendBuffer = ping_sendBuffer; - } - - public void setErrorHandlingMode(String errorHandlingMode) { - if(!(errorHandlingMode.equals(ONERROR_FAIL)||errorHandlingMode.equals(ONERROR_ATTEMPT_RESTART)||errorHandlingMode.equals(ONERROR_MUST_RESTART))) throw new IllegalArgumentException("errorHandlingMode must be fail, attempt-restart, or must-restart"); - this.errorHandlingMode = errorHandlingMode; - } - - public void setTime_dl_max(int time_dl_max) { - if(time_dl_max<1) throw new IllegalArgumentException("time_dl_max must be at least 1"); - this.time_dl_max = time_dl_max; - } - - public void setTime_ul_max(int time_ul_max) { - if(time_ul_max<1) throw new IllegalArgumentException("time_ul_max must be at least 1"); - this.time_ul_max = time_ul_max; - } - - public void setTime_auto(boolean time_auto) { - - this.time_auto = time_auto; - } - - public void setCount_ping(int count_ping) { - if(count_ping<1) throw new IllegalArgumentException("count_ping must be at least 1"); - this.count_ping = count_ping; - } - - public void setTelemetry_extra(String telemetry_extra) { - - this.telemetry_extra = telemetry_extra; - } - - public void setOverheadCompensationFactor(double overheadCompensationFactor) { - if(overheadCompensationFactor<1) throw new IllegalArgumentException("overheadCompensationFactor must be at least 1"); - this.overheadCompensationFactor = overheadCompensationFactor; - } - - public void setGetIP_isp(boolean getIP_isp) { - - this.getIP_isp = getIP_isp; - } - - public void setGetIP_distance(String getIP_distance) { - if(!(getIP_distance.equals(DISTANCE_NO)||getIP_distance.equals(DISTANCE_KM)||getIP_distance.equals(DISTANCE_MILES))) throw new IllegalArgumentException("getIP_distance must be no, km or miles"); - this.getIP_distance = getIP_distance; - } - - public void setUseMebibits(boolean useMebibits) { - - this.useMebibits = useMebibits; - } - - public void setTest_order(String test_order) { - for(char c:test_order.toCharArray()){ - if(!(c=='I'||c=='P'||c=='D'||c=='U'||c=='_')) throw new IllegalArgumentException("test_order can only contain characters I, P, D, U, _"); - } - this.test_order = test_order; - } - - public SpeedtestConfig clone(){ - return new SpeedtestConfig(dl_ckSize, ul_ckSize, dl_parallelStreams, ul_parallelStreams, dl_streamDelay, ul_streamDelay, dl_graceTime, ul_graceTime, dl_connectTimeout, dl_soTimeout, ul_connectTimeout, ul_soTimeout, ping_connectTimeout, ping_soTimeout, dl_recvBuffer, dl_sendBuffer, ul_recvBuffer, ul_sendBuffer, ping_recvBuffer, ping_sendBuffer, errorHandlingMode, time_dl_max, time_ul_max, time_auto, count_ping, telemetry_extra, overheadCompensationFactor, getIP_isp, getIP_distance, useMebibits, test_order); - } -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/config/TelemetryConfig.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/config/TelemetryConfig.java deleted file mode 100644 index ffb72fe..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/config/TelemetryConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.fdossena.speedtest.core.config; - -import org.json.JSONException; -import org.json.JSONObject; - -public class TelemetryConfig { - private String telemetryLevel=LEVEL_DISABLED, server=null, path=null, shareURL=null; - public static final String LEVEL_DISABLED="disabled", LEVEL_BASIC="basic", LEVEL_FULL="full"; - - private void check(){ - if(!(telemetryLevel.equals(LEVEL_DISABLED)||telemetryLevel.equals(LEVEL_BASIC)||telemetryLevel.equals(LEVEL_FULL))) throw new IllegalArgumentException("Telemetry level must be disabled, basic or full"); - } - - public TelemetryConfig(){} - - public TelemetryConfig(String telemetryLevel, String server, String path, String shareURL){ - this.telemetryLevel=telemetryLevel; - this.server=server; - this.path=path; - this.shareURL=shareURL; - check(); - } - - public TelemetryConfig(JSONObject json){ - try{ - if(json.has("telemetryLevel")) telemetryLevel=json.getString("telemetryLevel"); - if(json.has("server")) server=json.getString("server"); - if(json.has("path")) path=json.getString("path"); - if(json.has("shareURL")) shareURL=json.getString("shareURL"); - check(); - }catch(JSONException t){ - throw new IllegalArgumentException("Invalid JSON ("+t.toString()+")"); - } - } - - public String getTelemetryLevel() { - return telemetryLevel; - } - - public String getServer() { - return server; - } - - public String getPath() { - return path; - } - - public String getShareURL() { - return shareURL; - } - - public TelemetryConfig clone(){ - return new TelemetryConfig(telemetryLevel,server,path,shareURL); - } -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/download/DownloadStream.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/download/DownloadStream.java deleted file mode 100644 index b4acee5..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/download/DownloadStream.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.fdossena.speedtest.core.download; - -import com.fdossena.speedtest.core.config.SpeedtestConfig; -import com.fdossena.speedtest.core.base.Connection; -import com.fdossena.speedtest.core.base.Utils; -import com.fdossena.speedtest.core.log.Logger; - -public abstract class DownloadStream { - private String server, path; - private int ckSize; - private int connectTimeout, soTimeout, recvBuffer, sendBuffer; - private Connection c=null; - private Downloader downloader; - private String errorHandlingMode= SpeedtestConfig.ONERROR_ATTEMPT_RESTART; - private long currentDownloaded=0, previouslyDownloaded=0; - private boolean stopASAP=false; - private Logger log; - - public DownloadStream(String server, String path, int ckSize, String errorHandlingMode, int connectTimeout, int soTimeout, int recvBuffer, int sendBuffer, Logger log){ - this.server=server; - this.path=path; - this.ckSize=ckSize; - this.errorHandlingMode=errorHandlingMode; - this.connectTimeout=connectTimeout; - this.soTimeout=soTimeout; - this.recvBuffer=recvBuffer; - this.sendBuffer=sendBuffer; - this.log=log; - init(); - } - - private void init(){ - if(stopASAP) return; - new Thread(){ - public void run(){ - if(c!=null){ - try{c.close();}catch (Throwable t){} - } - if(downloader !=null) downloader.stopASAP(); - currentDownloaded=0; - try { - c = new Connection(server, connectTimeout, soTimeout, recvBuffer, sendBuffer); - if(stopASAP){ - try{c.close();}catch (Throwable t){} - return; - } - downloader =new Downloader(c,path,ckSize) { - @Override - public void onProgress(long downloaded) { - currentDownloaded=downloaded; - } - - @Override - public void onError(String err) { - log("A downloader died"); - if(errorHandlingMode.equals(SpeedtestConfig.ONERROR_FAIL)){ - DownloadStream.this.onError(err); - return; - } - if(errorHandlingMode.equals(SpeedtestConfig.ONERROR_ATTEMPT_RESTART)||errorHandlingMode.equals(SpeedtestConfig.ONERROR_MUST_RESTART)){ - previouslyDownloaded+=currentDownloaded; - Utils.sleep(100); - init(); - } - } - }; - }catch (Throwable t){ - log("A downloader failed hard"); - try{c.close();}catch (Throwable t1){} - if(errorHandlingMode.equals(SpeedtestConfig.ONERROR_MUST_RESTART)){ - Utils.sleep(100); - init(); - }else onError(t.toString()); - } - } - }.start(); - - } - - public abstract void onError(String err); - - public void stopASAP(){ - stopASAP=true; - if(downloader !=null) downloader.stopASAP(); - } - - public long getTotalDownloaded(){ - return previouslyDownloaded+currentDownloaded; - } - - public void resetDownloadCounter(){ - previouslyDownloaded=0; - currentDownloaded=0; - if(downloader !=null) downloader.resetDownloadCounter(); - } - - public void join(){ - while(downloader==null) Utils.sleep(0,100); - try{downloader.join();}catch (Throwable t){} - } - - private void log(String s){ - if(log!=null) log.l(s); - } - -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/download/Downloader.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/download/Downloader.java deleted file mode 100644 index a876ac9..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/download/Downloader.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.fdossena.speedtest.core.download; - -import java.io.InputStream; - -import com.fdossena.speedtest.core.base.Connection; -import com.fdossena.speedtest.core.base.Utils; - -public abstract class Downloader extends Thread{ - private Connection c; - private String path; - private int ckSize; - private boolean stopASAP=false, resetASAP=false; - private long totDownloaded=0; - - public Downloader(Connection c, String path, int ckSize){ - this.c=c; - this.path=path; - this.ckSize=ckSize<1?1:ckSize; - start(); - } - - private static final int BUFFER_SIZE=16384; - public void run(){ - try{ - String s=path; - s+= Utils.url_sep(s)+"ckSize="+ckSize; - long lastProgressEvent=System.currentTimeMillis(); - long ckBytes=ckSize*1048576, newRequestThreshold=ckBytes/4; - long bytesLeft=0; - InputStream in=c.getInputStream(); - byte[] buf=new byte[BUFFER_SIZE]; - for(;;){ - if(stopASAP) break; - if(bytesLeft<=newRequestThreshold){ - c.GET(s, true); - bytesLeft+=ckBytes; - } - if(stopASAP) break; - int l=in.read(buf); - if(stopASAP) break; - bytesLeft-=l; - if(resetASAP){ - totDownloaded=0; - resetASAP=false; - } - totDownloaded+=l; - if(System.currentTimeMillis()-lastProgressEvent>200){ - lastProgressEvent=System.currentTimeMillis(); - onProgress(totDownloaded); - } - } - c.close(); - }catch(Throwable t){ - try{c.close();}catch(Throwable t1){} - onError(t.toString()); - } - } - - public void stopASAP(){ - this.stopASAP=true; - } - - public abstract void onProgress(long downloaded); - public abstract void onError(String err); - - public void resetDownloadCounter(){ - resetASAP=true; - } - - public long getDownloaded() { - return resetASAP?0:totDownloaded; - } -} \ No newline at end of file diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/getIP/GetIP.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/getIP/GetIP.java deleted file mode 100644 index 51dd07f..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/getIP/GetIP.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.fdossena.speedtest.core.getIP; - -import java.io.BufferedReader; -import java.util.HashMap; - -import com.fdossena.speedtest.core.config.SpeedtestConfig; -import com.fdossena.speedtest.core.base.Connection; -import com.fdossena.speedtest.core.base.Utils; - -public abstract class GetIP extends Thread{ - private Connection c; - private String path; - private boolean isp; - private String distance; - public GetIP(Connection c, String path, boolean isp, String distance){ - this.c=c; - this.path=path; - this.isp=isp; - if(!(distance==null||distance.equals(SpeedtestConfig.DISTANCE_KM)||distance.equals(SpeedtestConfig.DISTANCE_MILES))) throw new IllegalArgumentException("Distance must be null, mi or km"); - this.distance=distance; - start(); - } - - public void run(){ - try{ - String s=path; - if(isp){ - s+= Utils.url_sep(s)+"isp=true"; - if(!distance.equals(SpeedtestConfig.DISTANCE_NO)){ - s+=Utils.url_sep(s)+"distance="+distance; - } - } - c.GET(s,true); - HashMap h=c.parseResponseHeaders(); - BufferedReader br=new BufferedReader(c.getInputStreamReader()); - if(h.get("content-length")!=null){ - //standard encoding - char[] buf=new char[Integer.parseInt(h.get("content-length"))]; - br.read(buf); - String data=new String(buf); - onDataReceived(data); - }else{ - //chunked encoding hack. TODO: improve this garbage with proper chunked support - c.readLineUnbuffered(); //ignore first line - String data=c.readLineUnbuffered(); //actual info we want - c.readLineUnbuffered(); //ignore last line (0) - onDataReceived(data); - } - - c.close(); - }catch(Throwable t){ - try{c.close();}catch(Throwable t1){} - onError(t.toString()); - } - } - - public abstract void onDataReceived(String data); - public abstract void onError(String err); -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/log/Logger.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/log/Logger.java deleted file mode 100644 index 76d27a4..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/log/Logger.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.fdossena.speedtest.core.log; - -public class Logger { - private String log=""; - public Logger(){} - - public String getLog(){ - synchronized (this){ - return log; - } - } - - public void l(String s){ - synchronized (this){ - log+=System.currentTimeMillis()+" "+s+"\n"; - } - } -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/ping/PingStream.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/ping/PingStream.java deleted file mode 100644 index e661d6f..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/ping/PingStream.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.fdossena.speedtest.core.ping; - -import com.fdossena.speedtest.core.config.SpeedtestConfig; -import com.fdossena.speedtest.core.base.Connection; -import com.fdossena.speedtest.core.base.Utils; -import com.fdossena.speedtest.core.log.Logger; - -public abstract class PingStream { - private String server, path; - private int remainingPings=10; - private int connectTimeout, soTimeout, recvBuffer, sendBuffer; - private Connection c=null; - private Pinger pinger; - private String errorHandlingMode= SpeedtestConfig.ONERROR_ATTEMPT_RESTART; - private boolean stopASAP=false; - private Logger log; - - public PingStream(String server, String path, int pings, String errorHandlingMode, int connectTimeout, int soTimeout, int recvBuffer, int sendBuffer, Logger log){ - this.server=server; - this.path=path; - remainingPings=pings<1?1:pings; - this.errorHandlingMode=errorHandlingMode; - this.connectTimeout=connectTimeout; - this.soTimeout=soTimeout; - this.recvBuffer=recvBuffer; - this.sendBuffer=sendBuffer; - this.log=log; - init(); - } - - private void init(){ - if(stopASAP) return; - if(c!=null){ - try{c.close();}catch (Throwable t){} - } - new Thread(){ - public void run(){ - if(pinger !=null) pinger.stopASAP(); - if(remainingPings<=0) return; - try { - c = new Connection(server, connectTimeout, soTimeout, recvBuffer, sendBuffer); - if(stopASAP){ - try{c.close();}catch (Throwable t){} - return; - } - pinger =new Pinger(c,path) { - @Override - public boolean onPong(long ns) { - boolean r=PingStream.this.onPong(ns); - if(--remainingPings<=0||!r){ - onDone(); - return false; - } else return true; - } - - @Override - public void onError(String err) { - log("A pinger died"); - if(errorHandlingMode.equals(SpeedtestConfig.ONERROR_FAIL)){ - PingStream.this.onError(err); - return; - } - if(errorHandlingMode.equals(SpeedtestConfig.ONERROR_ATTEMPT_RESTART)||errorHandlingMode.equals(SpeedtestConfig.ONERROR_MUST_RESTART)){ - Utils.sleep(100); - init(); - } - } - }; - }catch (Throwable t){ - log("A pinger failed hard"); - try{c.close();}catch (Throwable t1){} - if(errorHandlingMode.equals(SpeedtestConfig.ONERROR_MUST_RESTART)){ - Utils.sleep(100); - init(); - }else onError(t.toString()); - } - } - }.start(); - } - - public abstract void onError(String err); - public abstract boolean onPong(long ns); - public abstract void onDone(); - - public void stopASAP(){ - stopASAP=true; - if(pinger !=null) pinger.stopASAP(); - } - - public void join(){ - while(pinger==null) Utils.sleep(0,100); - try{pinger.join();}catch (Throwable t){} - } - - private void log(String s){ - if(log!=null) log.l(s); - } - -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/ping/Pinger.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/ping/Pinger.java deleted file mode 100644 index f896080..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/ping/Pinger.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.fdossena.speedtest.core.ping; - -import java.io.InputStream; - -import com.fdossena.speedtest.core.base.Connection; - -public abstract class Pinger extends Thread{ - private Connection c; - private String path; - private boolean stopASAP=false; - - public Pinger(Connection c, String path){ - this.c=c; - this.path=path; - start(); - } - - public void run(){ - try{ - String s=path; - InputStream in=c.getInputStream(); - for(;;){ - if(stopASAP) break; - c.GET(s,true); - if(stopASAP) break; - long t=System.nanoTime(); - if(c.readLineUnbuffered().trim().isEmpty()) throw new Exception("Persistent connection died"); - t=System.nanoTime()-t; - if(stopASAP) break; - while(!c.readLineUnbuffered().trim().isEmpty()); - if(stopASAP) break; - if(!onPong(t/2)) break; - } - c.close(); - }catch(Throwable t){ - try{c.close();}catch(Throwable t1){} - onError(t.toString()); - } - } - - public abstract boolean onPong(long ns); - public abstract void onError(String err); - - public void stopASAP(){ - this.stopASAP=true; - } -} \ No newline at end of file diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/serverSelector/ServerSelector.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/serverSelector/ServerSelector.java deleted file mode 100644 index ecdded0..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/serverSelector/ServerSelector.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.fdossena.speedtest.core.serverSelector; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; - -import com.fdossena.speedtest.core.config.SpeedtestConfig; -import com.fdossena.speedtest.core.ping.PingStream; - -public abstract class ServerSelector { - private ArrayList servers=new ArrayList<>(); - private static final int PARALLELISM=6; - private TestPoint selectedTestPoint=null; - private int state=NOT_STARTED; - private static final int NOT_STARTED=0, WORKING=1, DONE=2; - private int timeout; - private static final int PINGS=3, SLOW_THRESHOLD=500; - private boolean stopASAP=false; - - public ServerSelector(TestPoint[] servers, int timeout){ - addTestPoints(servers); - this.timeout=timeout; - } - public void addTestPoint(TestPoint t){ - if(state!=NOT_STARTED) throw new IllegalStateException("Cannot add test points at this time"); - if(t==null) return; - servers.add(t); - } - public void addTestPoint(JSONObject t){ - if(state!=NOT_STARTED) throw new IllegalStateException("Cannot add test points at this time"); - servers.add(new TestPoint(t)); - } - public void addTestPoints(JSONArray a){ - if(state!=NOT_STARTED) throw new IllegalStateException("Cannot add test points at this time"); - for(int i=0;i= servers.size()){ - if(activeStreams<=0){ - selectedTestPoint=null; - for(TestPoint t:servers){ - if(t.ping==-1) continue; - if(selectedTestPoint==null||t.ping h=c.parseResponseHeaders(); - String data=""; - String transferEncoding=h.get("transfer-encoding"); - if(transferEncoding!=null&&transferEncoding.equalsIgnoreCase("chunked")){ - c.readLineUnbuffered(); - } - data=c.readLineUnbuffered(); - onDataReceived(data); - c.close(); - }catch(Throwable t){ - try{c.close();}catch(Throwable t1){} - onError(t.toString()); - } - } - - public abstract void onDataReceived(String data); - public abstract void onError(String err); -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/upload/UploadStream.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/upload/UploadStream.java deleted file mode 100644 index 4ae3c02..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/upload/UploadStream.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.fdossena.speedtest.core.upload; - -import com.fdossena.speedtest.core.base.Connection; -import com.fdossena.speedtest.core.base.Utils; -import com.fdossena.speedtest.core.config.SpeedtestConfig; -import com.fdossena.speedtest.core.log.Logger; - -public abstract class UploadStream { - private String server, path; - private int ckSize; - private int connectTimeout, soTimeout, recvBuffer, sendBuffer; - private Connection c=null; - private Uploader uploader; - private String errorHandlingMode= SpeedtestConfig.ONERROR_ATTEMPT_RESTART; - private long currentUploaded=0, previouslyUploaded=0; - private boolean stopASAP=false; - private Logger log; - - public UploadStream(String server, String path, int ckSize, String errorHandlingMode, int connectTimeout, int soTimeout, int recvBuffer, int sendBuffer, Logger log){ - this.server=server; - this.path=path; - this.ckSize=ckSize; - this.errorHandlingMode=errorHandlingMode; - this.connectTimeout=connectTimeout; - this.soTimeout=soTimeout; - this.recvBuffer=recvBuffer; - this.sendBuffer=sendBuffer; - this.log=log; - init(); - } - - private void init(){ - if(stopASAP) return; - new Thread(){ - public void run(){ - if(c!=null){ - try{c.close();}catch (Throwable t){} - } - if(uploader !=null) uploader.stopASAP(); - currentUploaded=0; - try { - c = new Connection(server, connectTimeout, soTimeout, recvBuffer, sendBuffer); - if(stopASAP){ - try{c.close();}catch (Throwable t){} - return; - } - uploader =new Uploader(c,path,ckSize) { - @Override - public void onProgress(long uploaded) { - currentUploaded=uploaded; - } - - @Override - public void onError(String err) { - log("An uploader died"); - if(errorHandlingMode.equals(SpeedtestConfig.ONERROR_FAIL)){ - UploadStream.this.onError(err); - return; - } - if(errorHandlingMode.equals(SpeedtestConfig.ONERROR_ATTEMPT_RESTART)||errorHandlingMode.equals(SpeedtestConfig.ONERROR_MUST_RESTART)){ - previouslyUploaded+=currentUploaded; - Utils.sleep(100); - init(); - } - } - }; - }catch (Throwable t){ - log("An uploader failed hard"); - try{c.close();}catch (Throwable t1){} - if(errorHandlingMode.equals(SpeedtestConfig.ONERROR_MUST_RESTART)){ - Utils.sleep(100); - init(); - }else onError(t.toString()); - } - } - }.start(); - } - - public abstract void onError(String err); - - public void stopASAP(){ - stopASAP=true; - if(uploader !=null) uploader.stopASAP(); - } - - public long getTotalUploaded(){ - return previouslyUploaded+currentUploaded; - } - - public void resetUploadCounter(){ - previouslyUploaded=0; - currentUploaded=0; - if(uploader !=null) uploader.resetUploadCounter(); - } - - public void join(){ - while(uploader==null) Utils.sleep(0,100); - try{uploader.join();}catch (Throwable t){} - } - - private void log(String s){ - if(log!=null) log.l(s); - } - -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/upload/Uploader.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/upload/Uploader.java deleted file mode 100644 index 34a0a9f..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/upload/Uploader.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.fdossena.speedtest.core.upload; - -import java.io.OutputStream; -import java.util.Random; - -import com.fdossena.speedtest.core.base.Connection; - -public abstract class Uploader extends Thread{ - private Connection c; - private String path; - private boolean stopASAP=false, resetASAP=false; - private long totUploaded=0; - private byte[] garbage; - - public Uploader(Connection c, String path, int ckSize){ - this.c=c; - this.path=path; - garbage=new byte[ckSize*1048576]; - Random r=new Random(System.nanoTime()); - r.nextBytes(garbage); - start(); - } - - private static final int BUFFER_SIZE=16384; - public void run(){ - try{ - String s=path; - long lastProgressEvent=System.currentTimeMillis(); - OutputStream out=c.getOutputStream(); - byte[] buf=new byte[BUFFER_SIZE]; - for(;;){ - if(stopASAP) break; - c.POST(s,true,"application/octet-stream",garbage.length); - for(int offset=0;offset=garbage.length)?(garbage.length-offset):BUFFER_SIZE; - out.write(garbage,offset,l); - if(stopASAP) break; - if(resetASAP){ - totUploaded=0; - resetASAP=false; - } - totUploaded+=l; - if(System.currentTimeMillis()-lastProgressEvent>200){ - lastProgressEvent=System.currentTimeMillis(); - onProgress(totUploaded); - } - } - if(stopASAP) break; - while(!c.readLineUnbuffered().trim().isEmpty()); - } - c.close(); - }catch(Throwable t){ - try{c.close();}catch(Throwable t1){} - onError(t.toString()); - } - } - - public void stopASAP(){ - this.stopASAP=true; - } - - public abstract void onProgress(long uploaded); - public abstract void onError(String err); - - public void resetUploadCounter(){ - resetASAP=true; - } - - public long getUploaded() { - return resetASAP?0:totUploaded; - } -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/worker/SpeedtestWorker.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/worker/SpeedtestWorker.java deleted file mode 100644 index d5d3af9..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/core/worker/SpeedtestWorker.java +++ /dev/null @@ -1,277 +0,0 @@ -package com.fdossena.speedtest.core.worker; - -import org.json.JSONObject; - -import com.fdossena.speedtest.core.base.Connection; -import com.fdossena.speedtest.core.base.Utils; -import com.fdossena.speedtest.core.config.SpeedtestConfig; -import com.fdossena.speedtest.core.config.TelemetryConfig; -import com.fdossena.speedtest.core.download.DownloadStream; -import com.fdossena.speedtest.core.getIP.GetIP; -import com.fdossena.speedtest.core.log.Logger; -import com.fdossena.speedtest.core.ping.PingStream; -import com.fdossena.speedtest.core.serverSelector.TestPoint; -import com.fdossena.speedtest.core.telemetry.Telemetry; -import com.fdossena.speedtest.core.upload.UploadStream; - -import java.util.Locale; - -public abstract class SpeedtestWorker extends Thread{ - private TestPoint backend; - private SpeedtestConfig config; - private TelemetryConfig telemetryConfig; - private boolean stopASAP=false; - private double dl=-1, ul=-1, ping=-1, jitter=-1; - private String ipIsp=""; - private Logger log=new Logger(); - - public SpeedtestWorker(TestPoint backend, SpeedtestConfig config, TelemetryConfig telemetryConfig){ - this.backend=backend; - this.config=config==null?new SpeedtestConfig():config; - this.telemetryConfig=telemetryConfig==null?new TelemetryConfig():telemetryConfig; - start(); - } - - public void run(){ - log.l("Test started"); - try { - for (char t : config.getTest_order().toCharArray()) { - if(stopASAP) break; - if (t == '_') Utils.sleep(1000); - if (t == 'I') getIP(); - if (t == 'D') dlTest(); - if (t == 'U') ulTest(); - if (t == 'P') pingTest(); - } - }catch (Throwable t){ - onCriticalFailure(t.toString()); - } - try{ - sendTelemetry(); - }catch (Throwable t){} - onEnd(); - } - - private boolean getIPCalled=false; - private void getIP(){ - if(getIPCalled) return; else getIPCalled=true; - final long start=System.currentTimeMillis(); - Connection c = null; - try { - c = new Connection(backend.getServer(), config.getPing_connectTimeout(), config.getPing_soTimeout(), -1, -1); - } catch (Throwable t) { - if (config.getErrorHandlingMode().equals(SpeedtestConfig.ONERROR_FAIL)){ - abort(); - onCriticalFailure(t.toString()); - } - return; - } - GetIP g = new GetIP(c, backend.getGetIpURL(), config.getGetIP_isp(), config.getGetIP_distance()) { - @Override - public void onDataReceived(String data) { - ipIsp=data; - try{ - data=new JSONObject(data).getString("processedString"); - }catch (Throwable t){} - log.l("GetIP: "+ data+ " (took "+(System.currentTimeMillis()-start)+"ms)"); - onIPInfoUpdate(data); - } - - @Override - public void onError(String err) { - log.l("GetIP: FAILED (took "+(System.currentTimeMillis()-start)+"ms)"); - abort(); - onCriticalFailure(err); - } - }; - while (g.isAlive()) Utils.sleep(0, 100); - } - - private boolean dlCalled=false; - private void dlTest(){ - if(dlCalled) return; else dlCalled=true; - final long start=System.currentTimeMillis(); - onDownloadUpdate(0,0); - DownloadStream[] streams=new DownloadStream[config.getDl_parallelStreams()]; - for(int i=0;i=config.getDl_graceTime()*1000){ - graceTimeDone=true; - for(DownloadStream d:streams) d.resetDownloadCounter(); - startT=System.currentTimeMillis(); - continue; - } - if(stopASAP||t+bonusT>=config.getTime_dl_max()*1000){ - for(DownloadStream d:streams) d.stopASAP(); - for(DownloadStream d:streams) d.join(); - break; - } - if(graceTimeDone) { - long totDownloaded = 0; - for (DownloadStream d : streams) totDownloaded += d.getTotalDownloaded(); - double speed = totDownloaded / ((t<100?100:t) / 1000.0); - if (config.getTime_auto()) { - double b = (3.2 * speed) / 100000.0; - bonusT += b > 400 ? 400 : b; - } - double progress = (t + bonusT) / (double) (config.getTime_dl_max() * 1000); - speed = (speed * 8 * config.getOverheadCompensationFactor()) / (config.getUseMebibits() ? 1048576.0 : 1000000.0); - dl = speed; - onDownloadUpdate(dl, progress>1?1:progress); - } - Utils.sleep(100); - } - if(stopASAP) return; - log.l("Download: "+ dl+ " (took "+(System.currentTimeMillis()-start)+"ms)"); - onDownloadUpdate(dl,1); - } - - private boolean ulCalled=false; - private void ulTest(){ - if(ulCalled) return; else ulCalled=true; - final long start=System.currentTimeMillis(); - onUploadUpdate(0,0); - UploadStream[] streams=new UploadStream[config.getUl_parallelStreams()]; - for(int i=0;i=config.getUl_graceTime()*1000){ - graceTimeDone=true; - for(UploadStream u:streams) u.resetUploadCounter(); - startT=System.currentTimeMillis(); - continue; - } - if(stopASAP||t+bonusT>=config.getTime_ul_max()*1000){ - for(UploadStream u:streams) u.stopASAP(); - for(UploadStream u:streams) u.join(); - break; - } - if(graceTimeDone) { - long totUploaded = 0; - for (UploadStream u : streams) totUploaded += u.getTotalUploaded(); - double speed = totUploaded / ((t<100?100:t) / 1000.0); - if (config.getTime_auto()) { - double b = (3.2 * speed) / 100000.0; - bonusT += b > 400 ? 400 : b; - } - double progress = (t + bonusT) / (double) (config.getTime_ul_max() * 1000); - speed = (speed * 8 * config.getOverheadCompensationFactor()) / (config.getUseMebibits() ? 1048576.0 : 1000000.0); - ul = speed; - onUploadUpdate(ul, progress>1?1:progress); - } - Utils.sleep(100); - } - if(stopASAP) return; - log.l("Upload: "+ ul+ " (took "+(System.currentTimeMillis()-start)+"ms)"); - onUploadUpdate(ul,1); - } - - private boolean pingCalled=false; - private void pingTest(){ - if(pingCalled) return; else pingCalled=true; - final long start=System.currentTimeMillis(); - onPingJitterUpdate(0,0,0); - PingStream ps=new PingStream(backend.getServer(),backend.getPingURL(),config.getCount_ping(),config.getErrorHandlingMode(),config.getPing_connectTimeout(),config.getPing_soTimeout(),config.getPing_recvBuffer(),config.getPing_sendBuffer(),log) { - private double minPing=Double.MAX_VALUE, prevPing=-1; - private int counter=0; - @Override - public void onError(String err) { - log.l("Ping: FAILED (took "+(System.currentTimeMillis()-start)+"ms)"); - abort(); - onCriticalFailure(err); - } - - @Override - public boolean onPong(long ns) { - counter++; - double ms = ns / 1000000.0; - if (ms < minPing) minPing = ms; - ping = minPing; - if (prevPing == -1) { - jitter=0; - }else { - double j = Math.abs(ms - prevPing); - jitter=j>jitter?(jitter*0.3+j*0.7):(jitter*0.8+j*0.2); - } - prevPing = ms; - double progress = counter / (double) config.getCount_ping(); - onPingJitterUpdate(ping, jitter, progress>1?1:progress); - return !stopASAP; - } - - @Override - public void onDone() { - } - }; - ps.join(); - if(stopASAP) return; - log.l("Ping: "+ ping+" "+jitter+ " (took "+(System.currentTimeMillis()-start)+"ms)"); - onPingJitterUpdate(ping,jitter,1); - } - - private void sendTelemetry(){ - if(telemetryConfig.getTelemetryLevel().equals(TelemetryConfig.LEVEL_DISABLED)) return; - if(stopASAP&&telemetryConfig.getTelemetryLevel().equals(TelemetryConfig.LEVEL_BASIC)) return; - try{ - Connection c=new Connection(telemetryConfig.getServer(),-1,-1,-1,-1); - Telemetry t=new Telemetry(c,telemetryConfig.getPath(),telemetryConfig.getTelemetryLevel(),ipIsp,config.getTelemetry_extra(),dl==-1?"":String.format(Locale.ENGLISH,"%.2f",dl),ul==-1?"":String.format(Locale.ENGLISH,"%.2f",ul),ping==-1?"":String.format(Locale.ENGLISH,"%.2f",ping),jitter==-1?"":String.format(Locale.ENGLISH,"%.2f",jitter),log.getLog()) { - @Override - public void onDataReceived(String data) { - if(data.startsWith("id")){ - onTestIDReceived(data.split(" ")[1]); - } - } - - @Override - public void onError(String err) { - System.err.println("Telemetry error: "+err); - } - }; - t.join(); - }catch (Throwable t){ - System.err.println("Failed to send telemetry: "+t.toString()); - t.printStackTrace(System.err); - } - } - - public void abort(){ - if(stopASAP) return; - log.l("Manually aborted"); - stopASAP=true; - } - - public abstract void onDownloadUpdate(double dl, double progress); - public abstract void onUploadUpdate(double ul, double progress); - public abstract void onPingJitterUpdate(double ping, double jitter, double progress); - public abstract void onIPInfoUpdate(String ipInfo); - public abstract void onTestIDReceived(String id); - public abstract void onEnd(); - - public abstract void onCriticalFailure(String err); - -} diff --git a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/ui/GaugeView.java b/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/ui/GaugeView.java deleted file mode 100644 index 11a0571..0000000 --- a/Speedtest-Android/app/src/main/java/com/fdossena/speedtest/ui/GaugeView.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.fdossena.speedtest.ui; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.RectF; -import android.util.AttributeSet; -import android.view.View; - -import your.name.here.speedtest.R; - -public class GaugeView extends View { - private float strokeWidth; - private int backgroundColor; - private int fillColor; - private int startAngle; - private int angles; - private int maxValue; - private int value=0; - - public GaugeView(Context context, AttributeSet attrs) { - super(context, attrs); - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GaugeView, 0, 0); - setStrokeWidth(a.getDimension(R.styleable.GaugeView_gauge_strokeWidth, 10)); - setBackgroundColor(a.getColor(R.styleable.GaugeView_gauge_backgroundColor, 0xFFCCCCCC)); - setFillColor(a.getColor(R.styleable.GaugeView_gauge_fillColor, 0xFFFFFFFF)); - setStartAngle(a.getInt(R.styleable.GaugeView_gauge_startAngle, 135)); - setAngles(a.getInt(R.styleable.GaugeView_gauge_angles, 270)); - setMaxValue(a.getInt(R.styleable.GaugeView_gauge_maxValue, 1000)); - } - - public GaugeView(Context context) { - super(context); - } - - private Paint paint=null; - private RectF rect=null; - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - float size = getWidth()16*1024*1024) throw new Exception("Too big"); - options.inJustDecodeBounds = false; - DisplayMetrics displayMetrics = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); - int vh = displayMetrics.heightPixels, vw = displayMetrics.widthPixels; - double desired=Math.max(vw,vh) * 0.7; - double scale=desired/Math.max(iw,ih); - final Bitmap b = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.testbackground, options),(int)(iw*scale), (int)(ih*scale), true); - runOnUiThread(new Runnable() { - @Override - public void run() { - v.setImageBitmap(b); - } - }); - }catch (Throwable t){ - System.err.println("Failed to load testbackground ("+t.getMessage()+")"); - } - page_init(); - } - }.start(); - } - - private static Speedtest st=null; - - private void page_init(){ - transition(R.id.page_init,TRANSITION_LENGTH); - final TextView t=((TextView)findViewById(R.id.init_text)); - runOnUiThread(new Runnable() { - @Override - public void run() { - t.setText(R.string.init_init); - } - }); - SpeedtestConfig config=null; - TelemetryConfig telemetryConfig=null; - TestPoint[] servers=null; - try{ - String c=readFileFromAssets("SpeedtestConfig.json"); - JSONObject o=new JSONObject(c); - config=new SpeedtestConfig(o); - c=readFileFromAssets("TelemetryConfig.json"); - o=new JSONObject(c); - telemetryConfig=new TelemetryConfig(o); - if(telemetryConfig.getTelemetryLevel().equals(TelemetryConfig.LEVEL_DISABLED)){ - runOnUiThread(new Runnable() { - @Override - public void run() { - hideView(R.id.privacy_open); - } - }); - } - c=readFileFromAssets("ServerList.json"); - JSONArray a=new JSONArray(c); - if(a.length()==0) throw new Exception("No test points"); - ArrayList s=new ArrayList<>(); - for(int i=0;i availableServers=new ArrayList<>(); - for(TestPoint t:servers) { - if (t.getPing() != -1) availableServers.add(t); - } - int selectedId=availableServers.indexOf(selected); - final Spinner spinner=(Spinner)findViewById(R.id.serverList); - ArrayList options=new ArrayList(); - for(TestPoint t:availableServers){ - options.add(t.getName()); - } - ArrayAdapter adapter=new ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,options.toArray(new String[0])); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spinner.setAdapter(adapter); - spinner.setSelection(selectedId); - final Button b=(Button)findViewById(R.id.start); - b.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - reinitOnResume=false; - page_test(availableServers.get(spinner.getSelectedItemPosition())); - b.setOnClickListener(null); - } - }); - TextView t=(TextView)findViewById(R.id.privacy_open); - t.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - page_privacy(); - } - }); - } - - private void page_privacy(){ - transition(R.id.page_privacy,TRANSITION_LENGTH); - reinitOnResume=false; - ((WebView)findViewById(R.id.privacy_policy)).loadUrl(getString(R.string.privacy_policy)); - TextView t=(TextView)findViewById(R.id.privacy_close); - t.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - transition(R.id.page_serverSelect,TRANSITION_LENGTH); - reinitOnResume=true; - } - }); - } - - private void page_test(final TestPoint selected){ - transition(R.id.page_test,TRANSITION_LENGTH); - st.setSelectedServer(selected); - ((TextView)findViewById(R.id.serverName)).setText(selected.getName()); - ((TextView)findViewById(R.id.dlText)).setText(format(0)); - ((TextView)findViewById(R.id.ulText)).setText(format(0)); - ((TextView)findViewById(R.id.pingText)).setText(format(0)); - ((TextView)findViewById(R.id.jitterText)).setText(format(0)); - ((ProgressBar)findViewById(R.id.dlProgress)).setProgress(0); - ((ProgressBar)findViewById(R.id.ulProgress)).setProgress(0); - ((GaugeView)findViewById(R.id.dlGauge)).setValue(0); - ((GaugeView)findViewById(R.id.ulGauge)).setValue(0); - ((TextView)findViewById(R.id.ipInfo)).setText(""); - ((ImageView)findViewById(R.id.logo_inapp)).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - String url=getString(R.string.logo_inapp_link); - if(url.isEmpty()) return; - Intent i=new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(url)); - startActivity(i); - } - }); - final View endTestArea=findViewById(R.id.endTestArea); - final int endTestAreaHeight=endTestArea.getHeight(); - ViewGroup.LayoutParams p=endTestArea.getLayoutParams(); - p.height=0; - endTestArea.setLayoutParams(p); - findViewById(R.id.shareButton).setVisibility(View.GONE); - st.start(new Speedtest.SpeedtestHandler() { - @Override - public void onDownloadUpdate(final double dl, final double progress) { - runOnUiThread(new Runnable() { - @Override - public void run() { - ((TextView)findViewById(R.id.dlText)).setText(progress==0?"...": format(dl)); - ((GaugeView)findViewById(R.id.dlGauge)).setValue(progress==0?0:mbpsToGauge(dl)); - ((ProgressBar)findViewById(R.id.dlProgress)).setProgress((int)(100*progress)); - } - }); - } - - @Override - public void onUploadUpdate(final double ul, final double progress) { - runOnUiThread(new Runnable() { - @Override - public void run() { - ((TextView)findViewById(R.id.ulText)).setText(progress==0?"...": format(ul)); - ((GaugeView)findViewById(R.id.ulGauge)).setValue(progress==0?0:mbpsToGauge(ul)); - ((ProgressBar)findViewById(R.id.ulProgress)).setProgress((int)(100*progress)); - } - }); - - } - - @Override - public void onPingJitterUpdate(final double ping, final double jitter, final double progress) { - runOnUiThread(new Runnable() { - @Override - public void run() { - ((TextView)findViewById(R.id.pingText)).setText(progress==0?"...": format(ping)); - ((TextView)findViewById(R.id.jitterText)).setText(progress==0?"...": format(jitter)); - } - }); - } - - @Override - public void onIPInfoUpdate(final String ipInfo) { - runOnUiThread(new Runnable() { - @Override - public void run() { - ((TextView)findViewById(R.id.ipInfo)).setText(ipInfo); - } - }); - } - - @Override - public void onTestIDReceived(final String id, final String shareURL) { - if(shareURL==null||shareURL.isEmpty()||id==null||id.isEmpty()) return; - runOnUiThread(new Runnable() { - @Override - public void run() { - Button shareButton=(Button)findViewById(R.id.shareButton); - shareButton.setVisibility(View.VISIBLE); - shareButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent share = new Intent(android.content.Intent.ACTION_SEND); - share.setType("text/plain"); - share.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); - share.putExtra(Intent.EXTRA_TEXT, shareURL); - startActivity(Intent.createChooser(share, getString(R.string.test_share))); - } - }); - } - }); - } - - @Override - public void onEnd() { - runOnUiThread(new Runnable() { - @Override - public void run() { - final Button restartButton=(Button)findViewById(R.id.restartButton); - restartButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - page_init(); - restartButton.setOnClickListener(null); - } - }); - } - }); - final long startT=System.currentTimeMillis(), endT=startT+TRANSITION_LENGTH; - new Thread(){ - public void run(){ - while(System.currentTimeMillis()=Build.VERSION_CODES.N) { - l = getResources().getConfiguration().getLocales().get(0); - }else{ - l=getResources().getConfiguration().locale; - } - if(d<10) return String.format(l,"%.2f",d); - if(d<100) return String.format(l,"%.1f",d); - return ""+Math.round(d); - } - - private int mbpsToGauge(double s){ - return (int)(1000*(1-(1/(Math.pow(1.3,Math.sqrt(s)))))); - } - - private String readFileFromAssets(String name) throws Exception{ - BufferedReader b=new BufferedReader(new InputStreamReader(getAssets().open(name))); - String ret=""; - try{ - for(;;){ - String s=b.readLine(); - if(s==null) break; - ret+=s; - } - }catch(EOFException e){} - return ret; - } - - private void hideView(int id){ - View v=findViewById(id); - if(v!=null) v.setVisibility(View.GONE); - } - - private boolean reinitOnResume=false; - @Override - protected void onResume() { - super.onResume(); - if(reinitOnResume){ - reinitOnResume=false; - page_init(); - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - try{st.abort();}catch (Throwable t){} - } - - @Override - public void onBackPressed() { - if(currentPage==R.id.page_privacy) - transition(R.id.page_serverSelect,TRANSITION_LENGTH); - else super.onBackPressed(); - } - - //PAGE TRANSITION SYSTEM - - private int currentPage=-1; - private boolean transitionBusy=false; //TODO: improve mutex - private int TRANSITION_LENGTH=300; - - private void transition(final int page, final int duration){ - if(transitionBusy){ - new Thread(){ - public void run(){ - try{sleep(10);}catch (Throwable t){} - transition(page,duration); - } - }.start(); - }else transitionBusy=true; - if(page==currentPage) return; - final ViewGroup oldPage=currentPage==-1?null:(ViewGroup)findViewById(currentPage), - newPage=page==-1?null:(ViewGroup)findViewById(page); - new Thread(){ - public void run(){ - long t=System.currentTimeMillis(), endT=t+duration; - runOnUiThread(new Runnable() { - @Override - public void run() { - if(newPage!=null){ - newPage.setAlpha(0); - newPage.setVisibility(View.VISIBLE); - } - if(oldPage!=null){ - oldPage.setAlpha(1); - } - } - }); - while(t - - - - - - - - - - - - - - - - - - - - - - - -