From 282eab5f4f584e24dfe39e2e803e6b09c118ab4d Mon Sep 17 00:00:00 2001 From: Josef Schlehofer Date: Mon, 10 Aug 2026 22:33:52 +0200 Subject: [PATCH 01/10] Modernize the Gradle build Gradle 9 with AGP 9 built-in Kotlin, a version catalog, SDK 37 and the org.librespeed.speedtest application id. Co-Authored-By: Claude Fable 5 --- .gitignore | 1 + Speedtest-Android/app/build.gradle | 24 ------- Speedtest-Android/app/build.gradle.kts | 68 +++++++++++++++++++ Speedtest-Android/build.gradle | 27 -------- Speedtest-Android/build.gradle.kts | 4 ++ Speedtest-Android/gradle.properties | 18 +---- Speedtest-Android/gradle/libs.versions.toml | 30 ++++++++ .../gradle/wrapper/gradle-wrapper.properties | 5 +- Speedtest-Android/settings.gradle | 2 - Speedtest-Android/settings.gradle.kts | 18 +++++ 10 files changed, 127 insertions(+), 70 deletions(-) delete mode 100644 Speedtest-Android/app/build.gradle create mode 100644 Speedtest-Android/app/build.gradle.kts delete mode 100644 Speedtest-Android/build.gradle create mode 100644 Speedtest-Android/build.gradle.kts create mode 100644 Speedtest-Android/gradle/libs.versions.toml delete mode 100644 Speedtest-Android/settings.gradle create mode 100644 Speedtest-Android/settings.gradle.kts diff --git a/.gitignore b/.gitignore index 098af8c..10cb847 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /_PRIVATE .directory +.DS_Store diff --git a/Speedtest-Android/app/build.gradle b/Speedtest-Android/app/build.gradle deleted file mode 100644 index 78bbc7e..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 9 - versionName '1.2.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/build.gradle.kts b/Speedtest-Android/app/build.gradle.kts new file mode 100644 index 0000000..3fc8771 --- /dev/null +++ b/Speedtest-Android/app/build.gradle.kts @@ -0,0 +1,68 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.compose) +} + +android { + namespace = "org.librespeed.speedtest" + compileSdk = 37 + + defaultConfig { + applicationId = "org.librespeed.speedtest" + minSdk = 26 + targetSdk = 36 + versionCode = 10 + versionName = "2.0.0" + } + + signingConfigs { + //populated from the environment in CI; local builds fall back to the debug key + create("release") { + val keystorePath = System.getenv("SIGNING_KEYSTORE") + if (!keystorePath.isNullOrEmpty()) { + storeFile = file(keystorePath) + storePassword = System.getenv("SIGNING_STORE_PASSWORD") + keyAlias = System.getenv("SIGNING_KEY_ALIAS") + keyPassword = System.getenv("SIGNING_KEY_PASSWORD") + } + } + } + + buildTypes { + release { + isMinifyEnabled = true + isShrinkResources = true + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + if (!System.getenv("SIGNING_KEYSTORE").isNullOrEmpty()) { + signingConfig = signingConfigs.getByName("release") + } + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + buildFeatures { + compose = true + buildConfig = true + } +} + +dependencies { + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.material3) + implementation(libs.androidx.compose.material3.window.size) + implementation(libs.androidx.compose.material.icons.extended) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.lifecycle.runtime.compose) + implementation(libs.androidx.lifecycle.viewmodel.compose) + implementation(libs.androidx.navigation.compose) + implementation(libs.androidx.datastore.preferences) + debugImplementation(libs.androidx.compose.ui.tooling) + testImplementation(libs.junit) +} diff --git a/Speedtest-Android/build.gradle b/Speedtest-Android/build.gradle deleted file mode 100644 index 801467d..0000000 --- a/Speedtest-Android/build.gradle +++ /dev/null @@ -1,27 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - google() - jcenter() - - } - dependencies { - classpath 'com.android.tools.build:gradle:4.1.3' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - google() - jcenter() - - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/Speedtest-Android/build.gradle.kts b/Speedtest-Android/build.gradle.kts new file mode 100644 index 0000000..020183f --- /dev/null +++ b/Speedtest-Android/build.gradle.kts @@ -0,0 +1,4 @@ +plugins { + alias(libs.plugins.android.application) apply false + alias(libs.plugins.kotlin.compose) apply false +} diff --git a/Speedtest-Android/gradle.properties b/Speedtest-Android/gradle.properties index 82618ce..96093a6 100644 --- a/Speedtest-Android/gradle.properties +++ b/Speedtest-Android/gradle.properties @@ -1,15 +1,3 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true - - +org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8 +android.useAndroidX=true +org.gradle.caching=true diff --git a/Speedtest-Android/gradle/libs.versions.toml b/Speedtest-Android/gradle/libs.versions.toml new file mode 100644 index 0000000..327ddbc --- /dev/null +++ b/Speedtest-Android/gradle/libs.versions.toml @@ -0,0 +1,30 @@ +[versions] +agp = "9.3.1" +kotlin = "2.4.10" +coreKtx = "1.19.0" +activityCompose = "1.13.0" +composeBom = "2026.06.01" +lifecycle = "2.11.0" +navigationCompose = "2.9.8" +datastore = "1.2.1" + +[libraries] +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" } +androidx-compose-material3-window-size = { group = "androidx.compose.material3", name = "material3-window-size-class" } +androidx-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycle" } +androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycle" } +androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" } +androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" } +junit = { group = "junit", name = "junit", version = "4.13.2" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } diff --git a/Speedtest-Android/gradle/wrapper/gradle-wrapper.properties b/Speedtest-Android/gradle/wrapper/gradle-wrapper.properties index 5f38c9b..1e922f4 100644 --- a/Speedtest-Android/gradle/wrapper/gradle-wrapper.properties +++ b/Speedtest-Android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ -#Mon Apr 12 15:03:57 CEST 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip diff --git a/Speedtest-Android/settings.gradle b/Speedtest-Android/settings.gradle deleted file mode 100644 index 33b9b25..0000000 --- a/Speedtest-Android/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -include ':app' -rootProject.name='Speedtest-Android' diff --git a/Speedtest-Android/settings.gradle.kts b/Speedtest-Android/settings.gradle.kts new file mode 100644 index 0000000..3ca903b --- /dev/null +++ b/Speedtest-Android/settings.gradle.kts @@ -0,0 +1,18 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "LibreSpeed" +include(":app") From 6e450ac58e9e253cc8fb2ee3afb125139a3341fb Mon Sep 17 00:00:00 2001 From: Josef Schlehofer Date: Mon, 10 Aug 2026 22:33:53 +0200 Subject: [PATCH 02/10] Fix the engine networking Corrects the malformed User-Agent header, accepts any 2xx response, tracks the IP version, estimates loss from unreturned pings and submits telemetry to the tested server. Co-Authored-By: Claude Fable 5 --- .../fdossena/speedtest/core/Speedtest.java | 22 +- .../speedtest/core/base/Connection.java | 19 +- .../speedtest/core/ping/PingStream.java | 5 + .../fdossena/speedtest/core/ping/Pinger.java | 5 +- .../core/serverSelector/ServerSelector.java | 1 + .../core/serverSelector/TestPoint.java | 11 + .../core/worker/SpeedtestWorker.java | 67 ++- .../com/fdossena/speedtest/ui/GaugeView.java | 122 ---- .../fdossena/speedtest/ui/MainActivity.java | 528 ------------------ 9 files changed, 103 insertions(+), 677 deletions(-) delete mode 100644 Speedtest-Android/app/src/main/java/com/fdossena/speedtest/ui/GaugeView.java delete mode 100644 Speedtest-Android/app/src/main/java/com/fdossena/speedtest/ui/MainActivity.java 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 index 03a52c8..0164e29 100644 --- 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 @@ -195,15 +195,20 @@ public void onPingJitterUpdate(double ping, double jitter, double progress) { callback.onPingJitterUpdate(ping, jitter, progress); } + @Override + public void onLossUpdate(double loss) { + callback.onLossUpdate(loss); + } + @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); + public void onTestIDReceived(String id, String shareURLTemplate) { + String shareURL=shareURLTemplate; + if(shareURL!=null&&id!=null) shareURL=String.format(shareURL,id); callback.onTestIDReceived(id,shareURL); } @@ -226,16 +231,6 @@ public void onCriticalFailure(String 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(); @@ -251,6 +246,7 @@ 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 onLossUpdate(double loss); public abstract void onIPInfoUpdate(String ipInfo); public abstract void onTestIDReceived(String id, String shareURL); public abstract void onEnd(); 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 index 6e722e2..f46fafb 100644 --- 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 @@ -17,11 +17,21 @@ public class Connection { private Socket socket; + + public boolean isIPv6(){ + return socket!=null&&socket.getInetAddress() instanceof java.net.Inet6Address; + } 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.2.3 (SDK "+Build.VERSION.SDK_INT+"; "+Build.PRODUCT+"; Android "+Build.VERSION.RELEASE+")", + private static String userAgent="LibreSpeed-Android (SDK "+Build.VERSION.SDK_INT+"; "+Build.PRODUCT+"; Android "+Build.VERSION.RELEASE+")"; + + public static void setUserAgent(String ua){ + userAgent=ua; + } + + private static final String LOCALE= Build.VERSION.SDK_INT>=21?Locale.getDefault().toLanguageTag():null; public Connection(String url, int connectTimeout, int soTimeout, int recvBuffer, int sendBuffer){ @@ -150,7 +160,7 @@ public void GET(String path, boolean keepAlive) throws Exception{ 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("User-Agent: "+userAgent+"\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"); @@ -167,7 +177,7 @@ public void POST(String path, boolean keepAlive, String contentType, long conten 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("User-Agent: "+userAgent+"\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"); @@ -201,7 +211,8 @@ 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()+")"); + String[] statusParts=s.trim().split(" "); + if(statusParts.length<2||!statusParts[1].startsWith("2")) throw new Exception("Did not receive an HTTP 2xx ("+s.trim()+")"); while(true){ s=readLineUnbuffered(); if(s.trim().isEmpty()) break; 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 index e661d6f..40a3aca 100644 --- 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 @@ -10,6 +10,11 @@ public abstract class PingStream { private int remainingPings=10; private int connectTimeout, soTimeout, recvBuffer, sendBuffer; private Connection c=null; + + public Boolean usedIPv6(){ + Connection conn=c; + return conn==null?null:conn.isIPv6(); + } private Pinger pinger; private String errorHandlingMode= SpeedtestConfig.ONERROR_ATTEMPT_RESTART; private boolean stopASAP=false; 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 index 8b0c534..5aeb3fb 100644 --- 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 @@ -31,7 +31,10 @@ public void run(){ if(l==null) break; l=l.trim().toLowerCase(); if(l.equals("transfer-encoding: chunked")) chunked=true; - if(l.contains("200 ok")) ok=true; + if(l.startsWith("http/")){ + String[] statusParts=l.split(" "); + if(statusParts.length>=2&&statusParts[1].startsWith("2")) ok=true; + } if(l.trim().isEmpty()){ if(chunked){c.readLineUnbuffered(); c.readLineUnbuffered();} break; 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 index b353fdb..8148431 100644 --- 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 @@ -84,6 +84,7 @@ public void onError(String err) { public boolean onPong(long ns) { float p=ns/1000000f; if(tp.ping==-1||p0){ + loss=pongsReceived>=expected?0:100.0*(expected-pongsReceived)/expected; + onLossUpdate(loss); + } } private void sendTelemetry(){ if(telemetryConfig.getTelemetryLevel().equals(TelemetryConfig.LEVEL_DISABLED)) return; if(stopASAP&&telemetryConfig.getTelemetryLevel().equals(TelemetryConfig.LEVEL_BASIC)) return; + //the tested server may run its own results backend (this is what the web client uses); + //try it first, then fall back to the centrally configured endpoint + String base=testServerTelemetryBase(); + String localId=submitTelemetry(backend.getServer(),base.isEmpty()?"results/telemetry.php":base+"/results/telemetry.php"); + if(localId!=null){ + onTestIDReceived(localId,shareUrlTemplate(backend.getServer(),base.isEmpty()?"results/?id=%s":base+"/results/?id=%s")); + return; + } + String centralId=submitTelemetry(telemetryConfig.getServer(),telemetryConfig.getPath()); + if(centralId!=null){ + onTestIDReceived(centralId,shareUrlTemplate(telemetryConfig.getServer(),telemetryConfig.getShareURL())); + } + } + + //endpoints usually live in /backend/, the results backend in /results/ + private String testServerTelemetryBase(){ + String pingURL=backend.getPingURL()==null?"":backend.getPingURL(); + int slash=pingURL.lastIndexOf('/'); + String dir=slash==-1?"":pingURL.substring(0,slash); + if(dir.endsWith("backend")) dir=dir.substring(0,dir.length()-"backend".length()); + while(dir.startsWith("/")) dir=dir.substring(1); + while(dir.endsWith("/")) dir=dir.substring(0,dir.length()-1); + return dir; + } + + private String submitTelemetry(String server, String path){ + if(server==null||server.isEmpty()||path==null||path.isEmpty()) return null; 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()) { + Connection c=new Connection(server,-1,-1,-1,-1); + final String[] result=new String[1]; + Telemetry t=new Telemetry(c,path,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]); + if(data!=null&&data.startsWith("id")){ + String[] parts=data.split(" "); + if(parts.length>1) result[0]=parts[1]; } } @Override public void onError(String err) { - System.err.println("Telemetry error: "+err); + System.err.println("Telemetry error ("+server+"): "+err); } }; t.join(); + return result[0]; }catch (Throwable t){ - System.err.println("Failed to send telemetry: "+t.toString()); - t.printStackTrace(System.err); + System.err.println("Failed to send telemetry to "+server+": "+t); + return null; } } + private String shareUrlTemplate(String serverBase, String sharePath){ + if(serverBase==null||serverBase.isEmpty()||sharePath==null||sharePath.isEmpty()) return null; + String server=serverBase; + if(!server.endsWith("/")) server=server+"/"; + String path=sharePath; + while(path.startsWith("/")) path=path.substring(1); + if(server.startsWith("//")) server="https:"+server; + return server+path; + } + public void abort(){ if(stopASAP) return; log.l("Manually aborted"); @@ -268,8 +316,9 @@ public void abort(){ 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 onLossUpdate(double loss); public abstract void onIPInfoUpdate(String ipInfo); - public abstract void onTestIDReceived(String id); + public abstract void onTestIDReceived(String id, String shareURLTemplate); 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(){ - new Thread(){ - @Override - public void run() { - runOnUiThread(new Runnable() { - @Override - public void run() { - 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); - } - }); - } - if(st!=null){ - try{st.abort();}catch (Throwable e){} - } - st=new Speedtest(); - st.setSpeedtestConfig(config); - st.setTelemetryConfig(telemetryConfig); - c=readFileFromAssets("ServerList.json"); - if(c.startsWith("\"")||c.startsWith("'")){ //fetch server list from URL - if(!st.loadServerList(c.subSequence(1,c.length()-1).toString())){ - throw new Exception("Failed to load server list"); - } - }else{ //use provided server list - 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 Date: Mon, 10 Aug 2026 22:33:53 +0200 Subject: [PATCH 03/10] Rewrite the app in Compose Material 3 Four-tab UI following the design mockups: gauge with live graphs, server management with favorites and distances, history with result and test details, sharing as image, link or text, Czech translation and an adaptive icon. Co-Authored-By: Claude Fable 5 --- .../app/src/main/AndroidManifest.xml | 34 +- .../app/src/main/assets/ServerList.json | 11 +- .../src/main/assets/ServerListFallback.json | 1 + .../org/librespeed/speedtest/MainActivity.kt | 41 ++ .../speedtest/data/AppPreferences.kt | 149 +++++ .../librespeed/speedtest/data/ClientInfo.kt | 13 + .../speedtest/data/CustomServerFactory.kt | 47 ++ .../librespeed/speedtest/data/GeoDistance.kt | 34 ++ .../speedtest/data/HistoryDatabase.kt | 134 +++++ .../librespeed/speedtest/data/NetworkInfo.kt | 50 ++ .../librespeed/speedtest/engine/TestEngine.kt | 91 +++ .../librespeed/speedtest/share/ShareImage.kt | 184 ++++++ .../librespeed/speedtest/share/ShareResult.kt | 89 +++ .../java/org/librespeed/speedtest/ui/App.kt | 162 ++++++ .../speedtest/ui/components/Sparkline.kt | 51 ++ .../speedtest/ui/components/SpeedGauge.kt | 116 ++++ .../speedtest/ui/history/HistoryScreen.kt | 189 ++++++ .../speedtest/ui/history/HistoryViewModel.kt | 40 ++ .../speedtest/ui/result/ResultScreen.kt | 410 ++++++++++++++ .../speedtest/ui/result/ShareScreen.kt | 167 ++++++ .../speedtest/ui/result/TestDetailsScreen.kt | 184 ++++++ .../speedtest/ui/servers/ServerSheet.kt | 259 +++++++++ .../speedtest/ui/servers/ServersScreen.kt | 357 ++++++++++++ .../speedtest/ui/settings/SettingsScreen.kt | 335 +++++++++++ .../speedtest/ui/speedtest/SpeedtestScreen.kt | 390 +++++++++++++ .../ui/speedtest/SpeedtestViewModel.kt | 342 +++++++++++ .../librespeed/speedtest/ui/theme/Theme.kt | 78 +++ .../app/src/main/res/drawable/ic_launcher.png | Bin 20326 -> 0 bytes .../res/drawable/ic_launcher_foreground.xml | 52 ++ .../app/src/main/res/drawable/ic_logo.xml | 52 ++ .../app/src/main/res/drawable/logo.png | Bin 37296 -> 0 bytes .../app/src/main/res/drawable/logo_inapp.png | Bin 37343 -> 0 bytes .../src/main/res/drawable/testbackground.png | Bin 278762 -> 0 bytes .../app/src/main/res/layout/activity_main.xml | 536 ------------------ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../app/src/main/res/values-cs/strings.xml | 148 +++++ .../app/src/main/res/values-v21/styles.xml | 15 - .../app/src/main/res/values/attrs.xml | 11 - .../app/src/main/res/values/colors.xml | 25 +- .../app/src/main/res/values/dimens.xml | 42 -- .../app/src/main/res/values/strings.xml | 164 +++++- .../app/src/main/res/values/styles.xml | 15 - .../app/src/main/res/values/themes.xml | 3 + .../app/src/main/res/xml/file_paths.xml | 4 + 44 files changed, 4344 insertions(+), 686 deletions(-) create mode 100644 Speedtest-Android/app/src/main/assets/ServerListFallback.json create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/MainActivity.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/AppPreferences.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/ClientInfo.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/CustomServerFactory.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/GeoDistance.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/HistoryDatabase.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/NetworkInfo.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/engine/TestEngine.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/share/ShareImage.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/share/ShareResult.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/App.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/components/Sparkline.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/components/SpeedGauge.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/history/HistoryScreen.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/history/HistoryViewModel.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/ResultScreen.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/ShareScreen.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/TestDetailsScreen.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/servers/ServerSheet.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/servers/ServersScreen.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/settings/SettingsScreen.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/speedtest/SpeedtestScreen.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/speedtest/SpeedtestViewModel.kt create mode 100644 Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/theme/Theme.kt delete mode 100644 Speedtest-Android/app/src/main/res/drawable/ic_launcher.png create mode 100644 Speedtest-Android/app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 Speedtest-Android/app/src/main/res/drawable/ic_logo.xml delete mode 100644 Speedtest-Android/app/src/main/res/drawable/logo.png delete mode 100644 Speedtest-Android/app/src/main/res/drawable/logo_inapp.png delete mode 100644 Speedtest-Android/app/src/main/res/drawable/testbackground.png delete mode 100644 Speedtest-Android/app/src/main/res/layout/activity_main.xml create mode 100644 Speedtest-Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 Speedtest-Android/app/src/main/res/values-cs/strings.xml delete mode 100644 Speedtest-Android/app/src/main/res/values-v21/styles.xml delete mode 100644 Speedtest-Android/app/src/main/res/values/attrs.xml delete mode 100644 Speedtest-Android/app/src/main/res/values/dimens.xml delete mode 100644 Speedtest-Android/app/src/main/res/values/styles.xml create mode 100644 Speedtest-Android/app/src/main/res/values/themes.xml create mode 100644 Speedtest-Android/app/src/main/res/xml/file_paths.xml diff --git a/Speedtest-Android/app/src/main/AndroidManifest.xml b/Speedtest-Android/app/src/main/AndroidManifest.xml index 685d61d..8416062 100644 --- a/Speedtest-Android/app/src/main/AndroidManifest.xml +++ b/Speedtest-Android/app/src/main/AndroidManifest.xml @@ -1,19 +1,31 @@ - + + + + + + + android:theme="@style/Theme.LibreSpeed"> + + + + + android:name=".MainActivity" + android:exported="true" + android:launchMode="singleTop"> @@ -21,6 +33,4 @@ - - - \ 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 index 7719f0f..38317ea 100644 --- a/Speedtest-Android/app/src/main/assets/ServerList.json +++ b/Speedtest-Android/app/src/main/assets/ServerList.json @@ -1,10 +1 @@ -[ - { - "name":"Helsinki, Finland", - "server":"//fi.openspeed.org", - "dlURL":"garbage.php", - "ulURL":"empty.php", - "pingURL":"empty.php", - "getIpURL":"getIP.php" - } -] +"//librespeed.org/backend-servers/servers.php" \ No newline at end of file diff --git a/Speedtest-Android/app/src/main/assets/ServerListFallback.json b/Speedtest-Android/app/src/main/assets/ServerListFallback.json new file mode 100644 index 0000000..f2a4cc1 --- /dev/null +++ b/Speedtest-Android/app/src/main/assets/ServerListFallback.json @@ -0,0 +1 @@ +[{"name":"Amsterdam, Netherlands (Clouvider)","server":"https:\/\/ams.speedtest.clouvider.net\/backend","id":51,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Clouvider","sponsorURL":"https:\/\/www.clouvider.co.uk\/"},{"name":"Amsterdam, Netherlands (Sharktech)","server":"https:\/\/amsspeed.sharktech.net","id":94,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Sharktech","sponsorURL":"https:\/\/sharktech.net"},{"name":"Argalasti, Magnesia, Greece (Cosmote)","server":"https:\/\/argalasti.skoultsos.eu\/","id":104,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"skoultsos.eu","sponsorURL":"https:\/\/skoultsos.eu"},{"name":"Atlanta, United States (Clouvider)","server":"https:\/\/atl.speedtest.clouvider.net\/backend","id":53,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Clouvider","sponsorURL":"https:\/\/www.clouvider.co.uk\/"},{"name":"Bangalore, India (DigitalOcean)","server":"https:\/\/in1.backend.librespeed.org\/","id":75,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"DigitalOcean","sponsorURL":"https:\/\/www.digitalocean.com"},{"name":"Bari, Italy (GARR)","server":"https:\/\/st-be-ba1.infra.garr.it","id":33,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Consortium GARR","sponsorURL":"https:\/\/garr.it"},{"name":"Belgrade, Serbia (SOX)","server":"https:\/\/speedtest1.sox.rs\/librespeed\/","id":106,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Serbian Open eXchange","sponsorURL":"https:\/\/sox.rs"},{"name":"Bologna, Italy (GARR)","server":"https:\/\/st-be-bo1.infra.garr.it","id":34,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Consortium GARR","sponsorURL":"https:\/\/garr.it"},{"name":"Bucharest, Romania (ByteShield)","server":"https:\/\/speedtest.byteshield.ro:6060\/","id":98,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"ByteShield Hosting SRL","sponsorURL":"NULL"},{"name":"Chicago, USA (Sharktech)","server":"https:\/\/chispeed.sharktech.net","id":93,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Sharktech","sponsorURL":"https:\/\/sharktech.net"},{"name":"Denver, USA (Sharktech)","server":"https:\/\/denspeed.sharktech.net","id":92,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Sharktech","sponsorURL":"https:\/\/sharktech.net"},{"name":"Frankfurt, Germany (Clouvider)","server":"https:\/\/fra.speedtest.clouvider.net\/backend","id":50,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Clouvider","sponsorURL":"https:\/\/www.clouvider.co.uk\/"},{"name":"Frankfurt, Germany (FRA01)","server":"https:\/\/speedtest.lumischvps.cloud\/","id":86,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"LumischVPS","sponsorURL":"https:\/\/discord.gg\/GxYzPwJmA2"},{"name":"Frankfurt, Germany (FS IT-Systeme GmbH)","server":"https:\/\/speed.fs-it.systems\/","id":105,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"FS IT-Systeme GmbH","sponsorURL":"https:\/\/go.bytevault.systems\/fsit-web-spd1"},{"name":"Ghom, Iran (Amin IDC)","server":"https:\/\/fastme.ir\/","id":77,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Bardia Moshiri","sponsorURL":"https:\/\/bardia.tech\/"},{"name":"Grand Rapids, Michigan (RackGenius)","server":"https:\/\/mispeed.rackgenius.com\/","id":100,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"RackGenius","sponsorURL":"https:\/\/rackgenius.com\/"},{"name":"Helsinki, Finland (3) (Hetzner)","server":"https:\/\/finew.openspeed.org\/","id":22,"dlURL":"backend437\/garbage.php","ulURL":"backend437\/empty.php","pingURL":"backend437\/empty.php","getIpURL":"backend437\/getIP.php","sponsorName":"Daily Health Insurance Group","sponsorURL":"https:\/\/dhig.net\/"},{"name":"Helsinki, Finland (5) (Hetzner)","server":"https:\/\/fast.kabi.tk\/","id":24,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"KABI.tk","sponsorURL":"https:\/\/kabi.tk"},{"name":"Helsinki, Finland (Hetzner)","server":"https:\/\/www.librespeed.fi\/","id":101,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Pekka Jalonen","sponsorURL":"https:\/\/jalonen.net\/"},{"name":"Johannesburg, South Africa (Host Africa)","server":"https:\/\/za1.backend.librespeed.org\/","id":70,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"HOSTAFRICA","sponsorURL":"https:\/\/www.hostafrica.co.za"},{"name":"Las Vegas, USA (Sharktech)","server":"https:\/\/lasspeed.sharktech.net","id":90,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Sharktech","sponsorURL":"https:\/\/sharktech.net"},{"name":"London, England (Clouvider)","server":"https:\/\/lon.speedtest.clouvider.net\/backend","id":49,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Clouvider","sponsorURL":"https:\/\/www.clouvider.co.uk\/"},{"name":"Los Angeles, United States (1) (Clouvider)","server":"https:\/\/la.speedtest.clouvider.net\/backend","id":54,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Clouvider","sponsorURL":"https:\/\/www.clouvider.co.uk\/"},{"name":"Los Angeles, USA (Sharktech)","server":"https:\/\/laxspeed.sharktech.net","id":91,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Sharktech","sponsorURL":"https:\/\/sharktech.net"},{"name":"New York, United States (2) (Clouvider)","server":"https:\/\/nyc.speedtest.clouvider.net\/backend","id":52,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Clouvider","sponsorURL":"https:\/\/www.clouvider.co.uk\/"},{"name":"Nottingham, England (LayerIP)","server":"https:\/\/uk1.backend.librespeed.org","id":43,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"fosshost.org","sponsorURL":"https:\/\/fosshost.org"},{"name":"Novi Sad, Vojvodina, Serbia (E-CAPS.net)","server":"https:\/\/speed1.e-caps.net","id":103,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"E-CAPS.net","sponsorURL":"https:\/\/e-caps.net"},{"name":"Nuremberg, Germany (1) (Hetzner)","server":"https:\/\/de1.backend.librespeed.org","id":28,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Snopyta","sponsorURL":"https:\/\/snopyta.org"},{"name":"Nuremberg, Germany (2) (Hetzner)","server":"https:\/\/de4.backend.librespeed.org","id":27,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"LibreSpeed","sponsorURL":"https:\/\/librespeed.org"},{"name":"Nuremberg, Germany (3) (Hetzner)","server":"https:\/\/de3.backend.librespeed.org","id":30,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"LibreSpeed","sponsorURL":"https:\/\/librespeed.org"},{"name":"Nuremberg, Germany (4) (Hetzner)","server":"https:\/\/de5.backend.librespeed.org","id":31,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"LibreSpeed","sponsorURL":"https:\/\/librespeed.org"},{"name":"Nuremberg, Germany (6) (Hetzner)","server":"https:\/\/librespeed.lukas-heinrich.com\/","id":46,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"luki9100","sponsorURL":"https:\/\/lukas-heinrich.com\/"},{"name":"Ohio, USA (Rust backend)","server":"https:\/\/librespeed-rs.ir\/","id":95,"dlURL":"backend\/garbage","ulURL":"backend\/empty","pingURL":"backend\/empty","getIpURL":"backend\/getIP","sponsorName":"Sudo Dios","sponsorURL":"https:\/\/github.com\/SudoDios"},{"name":"Poznan, Poland (INEA)","server":"https:\/\/speedtest.kamilszczepanski.com","id":74,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Kamil Szczepa?ski","sponsorURL":"https:\/\/kamilszczepanski.com"},{"name":"Prague, Czech Republic (CESNET)","server":"https:\/\/speedtest.cesnet.cz","id":79,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"CESNET","sponsorURL":"https:\/\/www.cesnet.cz"},{"name":"Prague, Czech Republic (Turris)","server":"https:\/\/librespeed.turris.cz","id":85,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Turris","sponsorURL":"https:\/\/www.turris.com"},{"name":"Roma, Italy (GARR)","server":"https:\/\/st-be-rm2.infra.garr.it","id":35,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Consortium GARR","sponsorURL":"https:\/\/garr.it"},{"name":"Serbia (SOX)","server":"https:\/\/speedtest2.sox.rs","id":87,"dlURL":"libre\/backend\/garbage.php","ulURL":"libre\/backend\/empty.php","pingURL":"libre\/backend\/empty.php","getIpURL":"libre\/backend\/getIP.php","sponsorName":"Serbian Open eXchange (SOX)","sponsorURL":"https:\/\/sox.rs"},{"name":"Singapore (Salvatore Cahyo)","server":"https:\/\/speedtest.dsgroupmedia.com","id":68,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Salvatore Cahyo","sponsorURL":"https:\/\/salvatorecahyo.my.id"},{"name":"Tehran, Iran (Fanava)","server":"https:\/\/speedme.ir\/","id":76,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Bardia Moshiri","sponsorURL":"https:\/\/bardia.tech"},{"name":"Tehran, Iran (Faraso)","server":"https:\/\/st.bardia.tech","id":80,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"Bardia Moshiri","sponsorURL":"https:\/\/bardia.tech\/"},{"name":"Tokyo, Japan (A573)","server":"https:\/\/librespeed.a573.net\/","id":82,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"A573","sponsorURL":"https:\/\/mirror.a573.net\/"},{"name":"Vilnius, Lithuania (RackRay)","server":"https:\/\/lt1.backend.librespeed.org\/","id":69,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Time4VPS","sponsorURL":"https:\/\/www.time4vps.com"},{"name":"Virginia, United States, OVH","server":"https:\/\/speed.riverside.rocks\/","id":78,"dlURL":"garbage.php","ulURL":"empty.php","pingURL":"empty.php","getIpURL":"getIP.php","sponsorName":"Riverside Rocks","sponsorURL":"https:\/\/riverside.rocks"},{"name":"Volzhsky, Russia (PowerNet)","server":"https:\/\/speedtest.powernet.com.ru\/","id":102,"dlURL":"backend\/garbage.php","ulURL":"backend\/empty.php","pingURL":"backend\/empty.php","getIpURL":"backend\/getIP.php","sponsorName":"PowerNet","sponsorURL":"powernet.com.ru\/"}] \ No newline at end of file diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/MainActivity.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/MainActivity.kt new file mode 100644 index 0000000..1014db3 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/MainActivity.kt @@ -0,0 +1,41 @@ +package org.librespeed.speedtest + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi +import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import org.librespeed.speedtest.data.AppPreferences +import org.librespeed.speedtest.data.ClientInfo +import org.librespeed.speedtest.ui.App +import org.librespeed.speedtest.ui.theme.LibreSpeedTheme +import org.librespeed.speedtest.ui.theme.ThemeMode + +class MainActivity : ComponentActivity() { + + @OptIn(ExperimentalMaterial3WindowSizeClassApi::class, androidx.compose.material3.ExperimentalMaterial3Api::class) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + com.fdossena.speedtest.core.base.Connection.setUserAgent(ClientInfo.userAgent) + enableEdgeToEdge() + setContent { + val prefs = remember { AppPreferences(applicationContext) } + val themeMode by prefs.themeMode.collectAsStateWithLifecycle(initialValue = "system") + val windowSizeClass = calculateWindowSizeClass(this) + LibreSpeedTheme( + mode = when (themeMode) { + "light" -> ThemeMode.LIGHT + "dark" -> ThemeMode.DARK + else -> ThemeMode.SYSTEM + } + ) { + App(windowWidth = windowSizeClass.widthSizeClass) + } + } + } + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/AppPreferences.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/AppPreferences.kt new file mode 100644 index 0000000..15fd715 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/AppPreferences.kt @@ -0,0 +1,149 @@ +package org.librespeed.speedtest.data + +import android.content.Context +import androidx.datastore.preferences.core.booleanPreferencesKey +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.stringPreferencesKey +import androidx.datastore.preferences.core.stringSetPreferencesKey +import androidx.datastore.preferences.preferencesDataStore +import com.fdossena.speedtest.core.serverSelector.TestPoint +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map +import org.json.JSONArray +import org.json.JSONObject + +private val Context.dataStore by preferencesDataStore(name = "settings") + +//the public list carries a stable id; custom servers fall back to name+server +fun TestPoint.key(): String = if (serverId > 0) "id:$serverId" else "${name}|${server}" + +class AppPreferences(private val context: Context) { + + private object Keys { + val FAVORITES = stringSetPreferencesKey("favorite_servers") + val CUSTOM_SERVERS = stringPreferencesKey("custom_servers") + val REMEMBERED_SERVER = stringPreferencesKey("remembered_server") + val THEME_MODE = stringPreferencesKey("theme_mode") + val USE_MBYTES = booleanPreferencesKey("use_mbytes") + val TELEMETRY = booleanPreferencesKey("telemetry_enabled") + val SINGLE_CONNECTION = booleanPreferencesKey("single_connection") + val GEO_CACHE = stringPreferencesKey("geo_cache") + } + + suspend fun getGeoCache(): Map> = try { + val json = JSONObject(context.dataStore.data.first()[Keys.GEO_CACHE] ?: "{}") + json.keys().asSequence().mapNotNull { name -> + val parts = json.getString(name).split(",") + parts.takeIf { it.size == 2 }?.let { name to (it[0].toDouble() to it[1].toDouble()) } + }.toMap() + } catch (_: Exception) { + emptyMap() + } + + suspend fun putGeoCache(name: String, lat: Double, lon: Double) { + context.dataStore.edit { preferences -> + val json = try { + JSONObject(preferences[Keys.GEO_CACHE] ?: "{}") + } catch (_: Exception) { + JSONObject() + } + json.put(name, "$lat,$lon") + preferences[Keys.GEO_CACHE] = json.toString() + } + } + + val themeMode: Flow = + context.dataStore.data.map { it[Keys.THEME_MODE] ?: "system" } + + val useMBytes: Flow = + context.dataStore.data.map { it[Keys.USE_MBYTES] ?: false } + + val telemetryEnabled: Flow = + context.dataStore.data.map { it[Keys.TELEMETRY] ?: false } + + val singleConnection: Flow = + context.dataStore.data.map { it[Keys.SINGLE_CONNECTION] ?: false } + + suspend fun setSingleConnection(value: Boolean) { + context.dataStore.edit { it[Keys.SINGLE_CONNECTION] = value } + } + + suspend fun setThemeMode(mode: String) { + context.dataStore.edit { it[Keys.THEME_MODE] = mode } + } + + suspend fun setUseMBytes(value: Boolean) { + context.dataStore.edit { it[Keys.USE_MBYTES] = value } + } + + suspend fun setTelemetryEnabled(value: Boolean) { + context.dataStore.edit { it[Keys.TELEMETRY] = value } + } + + val favorites: Flow> = + context.dataStore.data.map { it[Keys.FAVORITES] ?: emptySet() } + + val rememberedServer: Flow = + context.dataStore.data.map { it[Keys.REMEMBERED_SERVER] } + + val customServers: Flow> = + context.dataStore.data.map { preferences -> + parseCustomServers(preferences[Keys.CUSTOM_SERVERS] ?: "[]") + } + + suspend fun toggleFavorite(key: String) { + context.dataStore.edit { preferences -> + val current = preferences[Keys.FAVORITES] ?: emptySet() + preferences[Keys.FAVORITES] = if (key in current) current - key else current + key + } + } + + suspend fun setRememberedServer(key: String?) { + context.dataStore.edit { preferences -> + if (key == null) preferences.remove(Keys.REMEMBERED_SERVER) + else preferences[Keys.REMEMBERED_SERVER] = key + } + } + + suspend fun addCustomServer(testPoint: TestPoint) { + context.dataStore.edit { preferences -> + val list = parseCustomServers(preferences[Keys.CUSTOM_SERVERS] ?: "[]") + if (list.any { it.key() == testPoint.key() }) return@edit + val array = JSONArray() + (list + testPoint).forEach { array.put(it.toJson()) } + preferences[Keys.CUSTOM_SERVERS] = array.toString() + } + } + + suspend fun removeCustomServer(key: String) { + context.dataStore.edit { preferences -> + val list = parseCustomServers(preferences[Keys.CUSTOM_SERVERS] ?: "[]") + val array = JSONArray() + list.filter { it.key() != key }.forEach { array.put(it.toJson()) } + preferences[Keys.CUSTOM_SERVERS] = array.toString() + } + } + + private fun parseCustomServers(json: String): List = try { + val array = JSONArray(json) + (0 until array.length()).mapNotNull { index -> + try { + TestPoint(array.getJSONObject(index)) + } catch (_: Exception) { + null + } + } + } catch (_: Exception) { + emptyList() + } + + private fun TestPoint.toJson(): JSONObject = JSONObject() + .put("name", name) + .put("server", server) + .put("dlURL", dlURL) + .put("ulURL", ulURL) + .put("pingURL", pingURL) + .put("getIpURL", getIpURL) + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/ClientInfo.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/ClientInfo.kt new file mode 100644 index 0000000..275d181 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/ClientInfo.kt @@ -0,0 +1,13 @@ +package org.librespeed.speedtest.data + +import android.os.Build +import org.librespeed.speedtest.BuildConfig + +object ClientInfo { + + val client: String = "LibreSpeed Android ${BuildConfig.VERSION_NAME}" + + val userAgent: String = + "LibreSpeed-Android/${BuildConfig.VERSION_NAME} (SDK ${Build.VERSION.SDK_INT}; Android ${Build.VERSION.RELEASE})" + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/CustomServerFactory.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/CustomServerFactory.kt new file mode 100644 index 0000000..d5a928f --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/CustomServerFactory.kt @@ -0,0 +1,47 @@ +package org.librespeed.speedtest.data + +import com.fdossena.speedtest.core.serverSelector.TestPoint +import java.net.URI + +object CustomServerFactory { + + /** + * Builds a TestPoint from a user supplied URL. The engine only uses host:port of "server", + * so any sub-path has to move into the endpoint fields. Without a scheme the engine tries + * HTTPS first and falls back to HTTP ("//host"). + */ + @Throws(IllegalArgumentException::class) + fun create(name: String, url: String): TestPoint { + require(name.isNotBlank()) { "Name cannot be empty" } + val trimmed = url.trim().trimEnd('/') + val uri = try { + URI(if (trimmed.contains("://")) trimmed else "https://$trimmed") + } catch (e: Exception) { + throw IllegalArgumentException("Invalid URL", e) + } + val host = uri.host ?: throw IllegalArgumentException("Invalid URL") + //IPv6 literals must stay bracketed inside the URL + val bracketedHost = if (host.contains(":") && !host.startsWith("[")) "[$host]" else host + val scheme = when { + trimmed.startsWith("http://") -> "http://" + trimmed.startsWith("https://") -> "https://" + else -> "//" + } + val server = buildString { + append(scheme) + append(bracketedHost) + if (uri.port != -1) append(":${uri.port}") + } + val basePath = uri.path.trim('/') + fun endpoint(file: String) = if (basePath.isEmpty()) file else "$basePath/$file" + return TestPoint( + name.trim(), + server, + endpoint("garbage.php"), + endpoint("empty.php"), + endpoint("empty.php"), + endpoint("getIP.php") + ) + } + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/GeoDistance.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/GeoDistance.kt new file mode 100644 index 0000000..842e40a --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/GeoDistance.kt @@ -0,0 +1,34 @@ +package org.librespeed.speedtest.data + +import kotlin.math.asin +import kotlin.math.cos +import kotlin.math.pow +import kotlin.math.sin +import kotlin.math.sqrt + +object GeoDistance { + + fun km(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double { + val earthRadiusKm = 6371.0 + val dLat = Math.toRadians(lat2 - lat1) + val dLon = Math.toRadians(lon2 - lon1) + val a = sin(dLat / 2).pow(2) + + cos(Math.toRadians(lat1)) * cos(Math.toRadians(lat2)) * sin(dLon / 2).pow(2) + return 2 * earthRadiusKm * asin(sqrt(a)) + } + + /** "Prague, Czech Republic (CESNET)" -> "Prague, Czech Republic" */ + fun cleanName(name: String): String = name.substringBefore("(").trim().trimEnd(',') + + /** "Prague, Czech Republic (CESNET)" -> "CESNET" or null */ + fun sponsor(name: String): String? = + name.substringAfter("(", "").removeSuffix(")").trim().ifEmpty { null } + + /** "https://librespeed.org/backend/" -> "librespeed.org/backend" */ + fun hostLabel(url: String): String = url + .removePrefix("https://") + .removePrefix("http://") + .removePrefix("//") + .trimEnd('/') + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/HistoryDatabase.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/HistoryDatabase.kt new file mode 100644 index 0000000..5d210e4 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/HistoryDatabase.kt @@ -0,0 +1,134 @@ +package org.librespeed.speedtest.data + +import android.content.ContentValues +import android.content.Context +import android.database.sqlite.SQLiteDatabase +import android.database.sqlite.SQLiteOpenHelper +import org.json.JSONArray + +data class HistoryEntry( + val id: Long = 0, + val date: Long, + val server: String, + val ping: Double, + val jitter: Double, + val download: Double, + val upload: Double, + val loss: Double, + val ipInfo: String?, + val ipVersion: Int, + val shareUrl: String?, + val networkType: String? = null, + val downloadSamples: List = emptyList(), + val uploadSamples: List = emptyList(), + val durationMs: Long = 0 +) + +class HistoryDatabase(context: Context) : SQLiteOpenHelper(context, "history.db", null, 3) { + + override fun onCreate(db: SQLiteDatabase) { + db.execSQL( + "CREATE TABLE history (" + + "id INTEGER PRIMARY KEY AUTOINCREMENT," + + "date INTEGER NOT NULL," + + "server TEXT NOT NULL," + + "ping REAL NOT NULL," + + "jitter REAL NOT NULL," + + "download REAL NOT NULL," + + "upload REAL NOT NULL," + + "loss REAL NOT NULL," + + "ipInfo TEXT," + + "ipVersion INTEGER NOT NULL DEFAULT 0," + + "shareUrl TEXT," + + "networkType TEXT," + + "dlSamples TEXT," + + "ulSamples TEXT," + + "duration INTEGER NOT NULL DEFAULT 0)" + ) + } + + override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { + if (oldVersion < 2) { + db.execSQL("ALTER TABLE history ADD COLUMN networkType TEXT") + db.execSQL("ALTER TABLE history ADD COLUMN dlSamples TEXT") + db.execSQL("ALTER TABLE history ADD COLUMN ulSamples TEXT") + } + if (oldVersion < 3) { + db.execSQL("ALTER TABLE history ADD COLUMN duration INTEGER NOT NULL DEFAULT 0") + } + } + + fun insert(entry: HistoryEntry): Long = writableDatabase.insert( + "history", null, + ContentValues().apply { + put("date", entry.date) + put("server", entry.server) + put("ping", entry.ping) + put("jitter", entry.jitter) + put("download", entry.download) + put("upload", entry.upload) + put("loss", entry.loss) + put("ipInfo", entry.ipInfo) + put("ipVersion", entry.ipVersion) + put("shareUrl", entry.shareUrl) + put("networkType", entry.networkType) + put("dlSamples", entry.downloadSamples.toJson()) + put("ulSamples", entry.uploadSamples.toJson()) + put("duration", entry.durationMs) + } + ) + + fun readAll(): List = query("SELECT * FROM history ORDER BY date DESC", null) + + fun read(id: Long): HistoryEntry? = query("SELECT * FROM history WHERE id=?", arrayOf(id.toString())).firstOrNull() + + fun delete(id: Long) { + writableDatabase.delete("history", "id=?", arrayOf(id.toString())) + } + + fun clear() { + writableDatabase.delete("history", null, null) + } + + private fun query(sql: String, args: Array?): List { + val result = mutableListOf() + readableDatabase.rawQuery(sql, args).use { cursor -> + while (cursor.moveToNext()) { + result.add( + HistoryEntry( + id = cursor.getLong(cursor.getColumnIndexOrThrow("id")), + date = cursor.getLong(cursor.getColumnIndexOrThrow("date")), + server = cursor.getString(cursor.getColumnIndexOrThrow("server")), + ping = cursor.getDouble(cursor.getColumnIndexOrThrow("ping")), + jitter = cursor.getDouble(cursor.getColumnIndexOrThrow("jitter")), + download = cursor.getDouble(cursor.getColumnIndexOrThrow("download")), + upload = cursor.getDouble(cursor.getColumnIndexOrThrow("upload")), + loss = cursor.getDouble(cursor.getColumnIndexOrThrow("loss")), + ipInfo = cursor.getString(cursor.getColumnIndexOrThrow("ipInfo")), + ipVersion = cursor.getInt(cursor.getColumnIndexOrThrow("ipVersion")), + shareUrl = cursor.getString(cursor.getColumnIndexOrThrow("shareUrl")), + networkType = cursor.getString(cursor.getColumnIndexOrThrow("networkType")), + downloadSamples = cursor.getString(cursor.getColumnIndexOrThrow("dlSamples")).fromJson(), + uploadSamples = cursor.getString(cursor.getColumnIndexOrThrow("ulSamples")).fromJson(), + durationMs = cursor.getLong(cursor.getColumnIndexOrThrow("duration")) + ) + ) + } + } + return result + } + + private fun List.toJson(): String { + val array = JSONArray() + forEach { array.put(it) } + return array.toString() + } + + private fun String?.fromJson(): List = try { + val array = JSONArray(this ?: "[]") + (0 until array.length()).map { array.getDouble(it) } + } catch (_: Exception) { + emptyList() + } + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/NetworkInfo.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/NetworkInfo.kt new file mode 100644 index 0000000..9520141 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/data/NetworkInfo.kt @@ -0,0 +1,50 @@ +package org.librespeed.speedtest.data + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.net.wifi.WifiInfo +import android.net.wifi.WifiManager +import android.os.Build + +object NetworkInfo { + + /** Best-effort description like "Wi-Fi 6", "Wi-Fi", "Ethernet" or "Cellular"; null when unknown. */ + fun describe(context: Context): String? { + return try { + val connectivity = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val capabilities = connectivity.getNetworkCapabilities(connectivity.activeNetwork) ?: return null + when { + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> wifiName(context, capabilities) + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> "Ethernet" + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> "Cellular" + else -> null + } + } catch (_: Exception) { + null + } + } + + private fun wifiName(context: Context, capabilities: NetworkCapabilities): String { + val standard = try { + val info = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + capabilities.transportInfo as? WifiInfo + } else { + null + } ?: @Suppress("DEPRECATION") run { + (context.applicationContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager)?.connectionInfo + } + if (info != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) info.wifiStandard else 0 + } catch (_: Exception) { + 0 + } + return when (standard) { + 8 -> "Wi-Fi 7" //ScanResult.WIFI_STANDARD_11BE + 6 -> "Wi-Fi 6" //WIFI_STANDARD_11AX + 5 -> "Wi-Fi 5" //WIFI_STANDARD_11AC + 4 -> "Wi-Fi 4" //WIFI_STANDARD_11N + else -> "Wi-Fi" + } + } + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/engine/TestEngine.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/engine/TestEngine.kt new file mode 100644 index 0000000..02c0610 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/engine/TestEngine.kt @@ -0,0 +1,91 @@ +package org.librespeed.speedtest.engine + +import android.content.Context +import com.fdossena.speedtest.core.Speedtest +import com.fdossena.speedtest.core.config.SpeedtestConfig +import com.fdossena.speedtest.core.config.TelemetryConfig +import com.fdossena.speedtest.core.serverSelector.TestPoint +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.withContext +import org.json.JSONArray +import org.json.JSONObject +import java.io.IOException +import kotlin.coroutines.resume + +class TestEngine(private val context: Context) { + + private var speedtest: Speedtest? = null + + data class Discovery(val servers: List, val selected: TestPoint?) + + /** Loads the server list (remote first, bundled fallback), pings all servers and picks the best one. */ + suspend fun discover(customServers: List): Discovery = withContext(Dispatchers.IO) { + val st = newSpeedtest(telemetryEnabled = false) + customServers.forEach { runCatching { st.addTestPoint(it) } } + var loaded = false + val data = readAsset("ServerList.json")?.trim() + if (data != null) { + loaded = if (data.startsWith("\"") || data.startsWith("'")) { + st.loadServerList(data.substring(1, data.length - 1)) + } else { + runCatching { st.addTestPoints(JSONArray(data)); true }.getOrDefault(false) + } + } + if (!loaded) { + readAsset("ServerListFallback.json")?.let { + runCatching { st.addTestPoints(JSONArray(it)); loaded = true } + } + } + if (!loaded && customServers.isEmpty()) throw IOException("Failed to load the server list") + val selected = suspendCancellableCoroutine { continuation -> + st.selectServer(object : Speedtest.ServerSelectedHandler() { + override fun onServerSelected(server: TestPoint?) { + continuation.resume(server) + } + }) + continuation.invokeOnCancellation { runCatching { st.abort() } } + } + Discovery(st.testPoints.toList(), selected) + } + + /** Prepares a fresh test run against an already known server, without re-pinging everything. */ + fun prepare(servers: List, selected: TestPoint, telemetryEnabled: Boolean, singleConnection: Boolean = false) { + val st = newSpeedtest(telemetryEnabled, singleConnection) + st.addTestPoints(servers.toTypedArray()) + st.setSelectedServer(selected) + speedtest = st + } + + fun start(handler: Speedtest.SpeedtestHandler) { + speedtest?.start(handler) + } + + fun abort() { + runCatching { speedtest?.abort() } + } + + private fun newSpeedtest(telemetryEnabled: Boolean, singleConnection: Boolean = false): Speedtest { + val st = Speedtest() + val configJson = runCatching { JSONObject(readAsset("SpeedtestConfig.json") ?: "{}") }.getOrDefault(JSONObject()) + if (singleConnection) { + configJson.put("dl_parallelStreams", 1) + configJson.put("ul_parallelStreams", 1) + } + runCatching { st.setSpeedtestConfig(SpeedtestConfig(configJson)) } + val telemetryJson = if (telemetryEnabled) { + JSONObject().put("telemetryLevel", TelemetryConfig.LEVEL_FULL) + } else { + readAsset("TelemetryConfig.json")?.let { runCatching { JSONObject(it) }.getOrNull() } ?: JSONObject() + } + runCatching { st.setTelemetryConfig(TelemetryConfig(telemetryJson)) } + return st + } + + private fun readAsset(name: String): String? = try { + context.assets.open(name).bufferedReader().use { it.readText() } + } catch (_: Exception) { + null + } + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/share/ShareImage.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/share/ShareImage.kt new file mode 100644 index 0000000..a03fc0d --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/share/ShareImage.kt @@ -0,0 +1,184 @@ +package org.librespeed.speedtest.share + +import android.content.Context +import android.content.Intent +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.LinearGradient +import android.graphics.Paint +import android.graphics.Path +import android.graphics.RadialGradient +import android.graphics.Shader +import android.graphics.Typeface +import androidx.core.content.FileProvider +import org.librespeed.speedtest.R +import org.librespeed.speedtest.data.GeoDistance +import org.librespeed.speedtest.data.HistoryEntry +import org.librespeed.speedtest.ui.history.formatDate +import java.io.File +import java.util.Locale + +object ShareImage { + + private const val TEAL = 0xFF2DD4BF.toInt() + private const val PURPLE = 0xFFA78BFA.toInt() + private const val WHITE = 0xFFE4E9F2.toInt() + private const val GRAY = 0xFF9AA4B8.toInt() + private const val BACKGROUND_TOP = 0xFF0B1120.toInt() + private const val BACKGROUND_BOTTOM = 0xFF1A1440.toInt() + + private const val WIDTH = 1080 + private const val HEIGHT = 1350 + + fun share(context: Context, entry: HistoryEntry, useMBytes: Boolean) { + try { + val bitmap = render(context, entry, useMBytes) + val directory = File(context.cacheDir, "share").apply { mkdirs() } + val file = File(directory, "librespeed-result.png") + file.outputStream().use { bitmap.compress(Bitmap.CompressFormat.PNG, 100, it) } + bitmap.recycle() + val uri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file) + val intent = Intent(Intent.ACTION_SEND).apply { + type = "image/png" + putExtra(Intent.EXTRA_STREAM, uri) + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + } + context.startActivity(Intent.createChooser(intent, context.getString(R.string.share_result))) + } catch (_: Exception) { + } + } + + fun render(context: Context, entry: HistoryEntry, useMBytes: Boolean): Bitmap { + val bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + drawBackground(canvas) + + val unit = context.getString(if (useMBytes) R.string.unit_mbytes else R.string.unit_mbps) + fun speed(value: Double) = String.format(Locale.US, "%.2f", if (useMBytes) value / 8 else value) + + fun paint(color: Int, size: Float, bold: Boolean = false) = Paint(Paint.ANTI_ALIAS_FLAG).apply { + this.color = color + textSize = size + typeface = if (bold) Typeface.create(Typeface.DEFAULT, Typeface.BOLD) else Typeface.DEFAULT + textAlign = Paint.Align.CENTER + } + + val centerX = WIDTH / 2f + + //wordmark + val titlePaint = paint(TEAL, 92f, bold = true).apply { textAlign = Paint.Align.LEFT } + val libreWidth = titlePaint.measureText("Libre") + val speedWidth = titlePaint.measureText("Speed") + val titleStart = centerX - (libreWidth + speedWidth) / 2 + canvas.drawText("Libre", titleStart, 170f, titlePaint) + titlePaint.color = WHITE + canvas.drawText("Speed", titleStart + libreWidth, 170f, titlePaint) + canvas.drawText(context.getString(R.string.share_image_subtitle), centerX, 235f, paint(GRAY, 42f)) + + //download + drawCircleArrow(canvas, centerX - measureSpeedHalf(speed(entry.download)) - 70f, 425f, TEAL, down = true) + canvas.drawText(speed(entry.download), centerX, 460f, paint(TEAL, 140f, bold = true)) + canvas.drawText(unit, centerX + measureSpeedHalf(speed(entry.download)) + 85f, 455f, paint(GRAY, 46f)) + canvas.drawText(context.getString(R.string.test_download).uppercase(Locale.ROOT), centerX, 535f, paint(GRAY, 44f, bold = true)) + + //upload + drawCircleArrow(canvas, centerX - measureSpeedHalf(speed(entry.upload)) - 70f, 690f, PURPLE, down = false) + canvas.drawText(speed(entry.upload), centerX, 725f, paint(PURPLE, 140f, bold = true)) + canvas.drawText(unit, centerX + measureSpeedHalf(speed(entry.upload)) + 85f, 720f, paint(GRAY, 46f)) + canvas.drawText(context.getString(R.string.test_upload).uppercase(Locale.ROOT), centerX, 800f, paint(GRAY, 44f, bold = true)) + + //ping + jitter + val leftX = WIDTH / 3f + val rightX = 2 * WIDTH / 3f + canvas.drawText(String.format(Locale.US, "%.0f ms", entry.ping), leftX, 950f, paint(WHITE, 72f, bold = true)) + canvas.drawText(context.getString(R.string.test_ping).uppercase(Locale.ROOT), leftX, 1005f, paint(GRAY, 40f)) + canvas.drawText(String.format(Locale.US, "%.0f ms", entry.jitter), rightX, 950f, paint(WHITE, 72f, bold = true)) + canvas.drawText(context.getString(R.string.test_jitter).uppercase(Locale.ROOT), rightX, 1005f, paint(GRAY, 40f)) + + //server + date, above the waves + canvas.drawText( + listOfNotNull(GeoDistance.cleanName(entry.server), GeoDistance.sponsor(entry.server)).joinToString(" · "), + centerX, 1075f, paint(WHITE, 44f) + ) + canvas.drawText(formatDate(entry.date), centerX, 1133f, paint(GRAY, 40f)) + + //rounded border framing the whole card, like the mockup + canvas.drawRoundRect( + android.graphics.RectF(5f, 5f, WIDTH - 5f, HEIGHT - 5f), 48f, 48f, + Paint(Paint.ANTI_ALIAS_FLAG).apply { + color = 0x30FFFFFF + style = Paint.Style.STROKE + strokeWidth = 5f + } + ) + + return bitmap + } + + private fun measureSpeedHalf(text: String): Float = + Paint(Paint.ANTI_ALIAS_FLAG).apply { + textSize = 140f + typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD) + }.measureText(text) / 2 + + private fun drawBackground(canvas: Canvas) { + val width = WIDTH.toFloat() + val height = HEIGHT.toFloat() + canvas.drawRect(0f, 0f, width, height, Paint().apply { + shader = LinearGradient(0f, 0f, 0f, height, BACKGROUND_TOP, BACKGROUND_BOTTOM, Shader.TileMode.CLAMP) + }) + //soft teal glow behind the wordmark and purple glow behind the upload value + canvas.drawRect(0f, 0f, width, 500f, Paint().apply { + shader = RadialGradient(width / 2f, 60f, 620f, 0x2E2DD4BF, 0x002DD4BF, Shader.TileMode.CLAMP) + }) + canvas.drawRect(0f, 350f, width, height, Paint().apply { + shader = RadialGradient(width / 2f, 700f, 760f, 0x1E7C5CFC, 0x007C5CFC, Shader.TileMode.CLAMP) + }) + //subtle gradient waves along the very bottom, below the server line + wave(canvas, height - 210f, 70f, 0x2E2DD4BF, 0x2EA78BFA, phase = 0f) + wave(canvas, height - 145f, 60f, 0x38A78BFA, 0x382DD4BF, phase = 0.5f) + wave(canvas, height - 80f, 55f, 0x4D2DD4BF, 0x4D7C5CFC, phase = 0.25f) + } + + private fun wave(canvas: Canvas, top: Float, amplitude: Float, colorStart: Int, colorEnd: Int, phase: Float) { + val width = WIDTH.toFloat() + val height = HEIGHT.toFloat() + val path = Path().apply { + moveTo(0f, top + amplitude * phase) + cubicTo( + width * 0.25f, top - amplitude, + width * 0.45f, top + amplitude * 1.4f, + width * 0.7f, top + amplitude * 0.2f + ) + cubicTo( + width * 0.85f, top - amplitude * 0.5f, + width * 0.95f, top + amplitude * 0.6f, + width, top - amplitude * 0.2f + ) + lineTo(width, height) + lineTo(0f, height) + close() + } + canvas.drawPath(path, Paint(Paint.ANTI_ALIAS_FLAG).apply { + shader = LinearGradient(0f, top - amplitude, width, height, colorStart, colorEnd, Shader.TileMode.CLAMP) + }) + } + + private fun drawCircleArrow(canvas: Canvas, cx: Float, cy: Float, color: Int, down: Boolean) { + val radius = 36f + val stroke = Paint(Paint.ANTI_ALIAS_FLAG).apply { + this.color = color + style = Paint.Style.STROKE + strokeWidth = 6f + strokeCap = Paint.Cap.ROUND + } + canvas.drawCircle(cx, cy, radius, stroke) + val shaft = 17f + val head = 10f + val direction = if (down) 1f else -1f + canvas.drawLine(cx, cy - shaft * direction, cx, cy + shaft * direction, stroke) + canvas.drawLine(cx, cy + shaft * direction, cx - head, cy + (shaft - head) * direction, stroke) + canvas.drawLine(cx, cy + shaft * direction, cx + head, cy + (shaft - head) * direction, stroke) + } + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/share/ShareResult.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/share/ShareResult.kt new file mode 100644 index 0000000..1b71b75 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/share/ShareResult.kt @@ -0,0 +1,89 @@ +package org.librespeed.speedtest.share + +import android.content.Context +import android.content.Intent +import org.librespeed.speedtest.R +import org.librespeed.speedtest.data.GeoDistance +import java.util.Locale + +object ShareResult { + + fun copy(context: Context, text: String) { + try { + val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as android.content.ClipboardManager + clipboard.setPrimaryClip(android.content.ClipData.newPlainText("LibreSpeed", text)) + } catch (_: Exception) { + } + } + + fun shareLink(context: Context, url: String) { + val intent = Intent(Intent.ACTION_SEND).apply { + type = "text/plain" + putExtra(Intent.EXTRA_TEXT, url) + } + try { + context.startActivity(Intent.createChooser(intent, context.getString(R.string.share_result))) + } catch (_: Exception) { + } + } + + fun buildText( + context: Context, + server: String, + download: Double, + upload: Double, + ping: Double, + jitter: Double, + loss: Double, + useMBytes: Boolean, + shareUrl: String?, + networkType: String? = null, + ipVersion: Int = 0 + ): String { + val unit = context.getString(if (useMBytes) R.string.unit_mbytes else R.string.unit_mbps) + fun speed(value: Double) = + String.format(Locale.US, "%.2f %s", if (useMBytes) value / 8 else value, unit) + + return buildString { + appendLine("LibreSpeed Speed Test") + appendLine("${context.getString(R.string.test_download)}: ${speed(download)}") + appendLine("${context.getString(R.string.test_upload)}: ${speed(upload)}") + appendLine("${context.getString(R.string.test_ping)}: ${String.format(Locale.US, "%.1f", ping)} ms") + appendLine("${context.getString(R.string.test_jitter)}: ${String.format(Locale.US, "%.1f", jitter)} ms") + if (loss >= 0) { + appendLine("${context.getString(R.string.test_loss)}: ${String.format(Locale.US, "%.1f", loss)} %") + } + appendLine("${context.getString(R.string.detail_server)}: ${GeoDistance.cleanName(server)}") + networkType?.let { appendLine("${context.getString(R.string.detail_network)}: $it") } + if (ipVersion != 0) { + appendLine("${context.getString(R.string.detail_protocol)}: IPv$ipVersion") + } + shareUrl?.let { appendLine(it) } + }.trimEnd() + } + + fun share( + context: Context, + server: String, + download: Double, + upload: Double, + ping: Double, + jitter: Double, + loss: Double, + useMBytes: Boolean, + shareUrl: String?, + networkType: String? = null, + ipVersion: Int = 0 + ) { + val text = buildText(context, server, download, upload, ping, jitter, loss, useMBytes, shareUrl, networkType, ipVersion) + val intent = Intent(Intent.ACTION_SEND).apply { + type = "text/plain" + putExtra(Intent.EXTRA_TEXT, text) + } + try { + context.startActivity(Intent.createChooser(intent, context.getString(R.string.share_result))) + } catch (_: Exception) { + } + } + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/App.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/App.kt new file mode 100644 index 0000000..9f08f05 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/App.kt @@ -0,0 +1,162 @@ +package org.librespeed.speedtest.ui + +import androidx.annotation.StringRes +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.History +import androidx.compose.material.icons.filled.Public +import androidx.compose.material.icons.filled.Settings +import androidx.compose.material.icons.filled.Speed +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.NavigationRail +import androidx.compose.material3.NavigationRailItem +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.stringResource +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavGraph.Companion.findStartDestination +import androidx.navigation.NavHostController +import androidx.navigation.NavType +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import androidx.navigation.navArgument +import org.librespeed.speedtest.R +import org.librespeed.speedtest.ui.history.HistoryScreen +import org.librespeed.speedtest.ui.result.ResultScreen +import org.librespeed.speedtest.ui.servers.ServersScreen +import org.librespeed.speedtest.ui.settings.SettingsScreen +import org.librespeed.speedtest.ui.speedtest.SpeedtestScreen +import org.librespeed.speedtest.ui.speedtest.SpeedtestViewModel + +enum class Destination(val route: String, @StringRes val label: Int, val icon: ImageVector) { + SPEEDTEST("speedtest", R.string.nav_speedtest, Icons.Filled.Speed), + HISTORY("history", R.string.nav_history, Icons.Filled.History), + SERVERS("servers", R.string.nav_servers, Icons.Filled.Public), + SETTINGS("settings", R.string.nav_settings, Icons.Filled.Settings) +} + +@androidx.compose.material3.ExperimentalMaterial3Api +@Composable +fun App(windowWidth: WindowWidthSizeClass = WindowWidthSizeClass.Compact) { + val navController = rememberNavController() + val backStackEntry by navController.currentBackStackEntryAsState() + val currentRoute = backStackEntry?.destination?.route + val speedtestViewModel: SpeedtestViewModel = viewModel() + val useRail = windowWidth != WindowWidthSizeClass.Compact + val onResultScreen = currentRoute?.startsWith("result/") == true || + currentRoute?.startsWith("testdetails/") == true || + currentRoute?.startsWith("share/") == true + + Scaffold( + containerColor = MaterialTheme.colorScheme.background, + bottomBar = { + if (!useRail && !onResultScreen) { + NavigationBar { + Destination.entries.forEach { destination -> + NavigationBarItem( + selected = currentRoute == destination.route, + onClick = { navController.navigateTo(destination) }, + icon = { Icon(destination.icon, contentDescription = null) }, + label = { Text(stringResource(destination.label)) } + ) + } + } + } + } + ) { padding -> + Row(Modifier.fillMaxSize().padding(padding)) { + if (useRail && !onResultScreen) { + NavigationRail { + Destination.entries.forEach { destination -> + NavigationRailItem( + selected = currentRoute == destination.route, + onClick = { navController.navigateTo(destination) }, + icon = { Icon(destination.icon, contentDescription = null) }, + label = { Text(stringResource(destination.label)) } + ) + } + } + } + NavHost( + navController = navController, + startDestination = Destination.SPEEDTEST.route, + modifier = Modifier.fillMaxSize() + ) { + composable(Destination.SPEEDTEST.route) { + SpeedtestScreen( + viewModel = speedtestViewModel, + onServersClick = { navController.navigateTo(Destination.SERVERS) }, + onSettingsClick = { navController.navigateTo(Destination.SETTINGS) }, + onResult = { id -> navController.navigate("result/$id") } + ) + } + composable(Destination.HISTORY.route) { + HistoryScreen(onOpen = { id -> navController.navigate("result/$id") }) + } + composable(Destination.SERVERS.route) { ServersScreen(speedtestViewModel) } + composable(Destination.SETTINGS.route) { + val uiState by speedtestViewModel.state.collectAsStateWithLifecycle() + SettingsScreen( + serverLabel = uiState.selectedServer?.name, + serverPinned = uiState.pinnedServer, + onServersClick = { navController.navigateTo(Destination.SERVERS) } + ) + } + composable( + route = "result/{id}", + arguments = listOf(navArgument("id") { type = NavType.LongType }) + ) { entry -> + ResultScreen( + entryId = entry.arguments?.getLong("id") ?: 0L, + onBack = { navController.popBackStack() }, + onTestAgain = { serverName -> + navController.navigateTo(Destination.SPEEDTEST) + speedtestViewModel.testAgain(serverName) + }, + onTestDetails = { id -> navController.navigate("testdetails/$id") }, + onShare = { id -> navController.navigate("share/$id") } + ) + } + composable( + route = "testdetails/{id}", + arguments = listOf(navArgument("id") { type = NavType.LongType }) + ) { entry -> + org.librespeed.speedtest.ui.result.TestDetailsScreen( + entryId = entry.arguments?.getLong("id") ?: 0L, + onBack = { navController.popBackStack() } + ) + } + composable( + route = "share/{id}", + arguments = listOf(navArgument("id") { type = NavType.LongType }) + ) { entry -> + org.librespeed.speedtest.ui.result.ShareScreen( + entryId = entry.arguments?.getLong("id") ?: 0L, + onBack = { navController.popBackStack() } + ) + } + } + } + } +} + +private fun NavHostController.navigateTo(destination: Destination) { + navigate(destination.route) { + popUpTo(graph.findStartDestination().id) { saveState = true } + launchSingleTop = true + restoreState = true + } +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/components/Sparkline.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/components/Sparkline.kt new file mode 100644 index 0000000..03bb2e1 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/components/Sparkline.kt @@ -0,0 +1,51 @@ +package org.librespeed.speedtest.ui.components + +import androidx.compose.foundation.Canvas +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.graphics.drawscope.Stroke + +@Composable +fun Sparkline( + data: List, + color: Color, + modifier: Modifier = Modifier +) { + Canvas(modifier = modifier) { + if (data.size < 2) return@Canvas + val max = data.max().takeIf { it > 0 } ?: return@Canvas + val stepX = size.width / (data.size - 1) + val vPadding = size.height * 0.1f + val usable = size.height - vPadding * 2 + fun pointAt(index: Int): Offset { + val y = size.height - vPadding - (data[index] / max * usable).toFloat() + return Offset(stepX * index, y) + } + + val line = Path() + line.moveTo(pointAt(0).x, pointAt(0).y) + for (i in 1 until data.size) { + val previous = pointAt(i - 1) + val current = pointAt(i) + val midX = (previous.x + current.x) / 2 + line.cubicTo(midX, previous.y, midX, current.y, current.x, current.y) + } + drawPath(line, color = color, style = Stroke(width = 4f, cap = StrokeCap.Round)) + + val fill = Path().apply { + addPath(line) + lineTo(size.width, size.height) + lineTo(0f, size.height) + close() + } + drawPath( + fill, + brush = Brush.verticalGradient(listOf(color.copy(alpha = 0.25f), Color.Transparent)) + ) + } +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/components/SpeedGauge.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/components/SpeedGauge.kt new file mode 100644 index 0000000..deeb3f4 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/components/SpeedGauge.kt @@ -0,0 +1,116 @@ +package org.librespeed.speedtest.ui.components + +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.tween +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.drawscope.rotate +import androidx.compose.ui.graphics.nativeCanvas +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import org.librespeed.speedtest.ui.theme.Purple +import org.librespeed.speedtest.ui.theme.Teal +import kotlin.math.cos +import kotlin.math.sin + +private val SCALE_STOPS = doubleArrayOf(0.0, 1.0, 5.0, 10.0, 25.0, 50.0, 100.0, 250.0, 500.0, 1000.0) +private const val START_ANGLE = 135f +private const val SWEEP = 270f + +/** Maps a speed to a 0..1 position on the non-linear gauge scale. */ +private fun scaleFraction(speed: Double): Float { + if (speed <= 0) return 0f + if (speed >= SCALE_STOPS.last()) return 1f + for (i in 1 until SCALE_STOPS.size) { + if (speed <= SCALE_STOPS[i]) { + val segment = (speed - SCALE_STOPS[i - 1]) / (SCALE_STOPS[i] - SCALE_STOPS[i - 1]) + return ((i - 1) + segment).toFloat() / (SCALE_STOPS.size - 1) + } + } + return 1f +} + +@Composable +fun SpeedGauge( + speed: Double, + modifier: Modifier = Modifier, + content: @Composable () -> Unit +) { + val fraction by animateFloatAsState( + targetValue = scaleFraction(speed), + animationSpec = tween(durationMillis = 300), + label = "gauge" + ) + val trackColor = MaterialTheme.colorScheme.surfaceVariant + val labelColor = MaterialTheme.colorScheme.onSurfaceVariant + val labelSizePx = with(LocalDensity.current) { 11.sp.toPx() } + + Box(modifier = modifier.aspectRatio(1f), contentAlignment = Alignment.Center) { + Canvas(modifier = Modifier.matchParentSize()) { + val stroke = size.minDimension * 0.055f + val labelInset = labelSizePx * 2.2f + val diameter = size.minDimension - stroke - labelInset * 2 + val topLeft = Offset((size.width - diameter) / 2, (size.height - diameter) / 2) + val arcSize = Size(diameter, diameter) + + drawArc( + color = trackColor, + startAngle = START_ANGLE, + sweepAngle = SWEEP, + useCenter = false, + topLeft = topLeft, + size = arcSize, + style = Stroke(width = stroke, cap = StrokeCap.Round) + ) + if (fraction > 0f) { + // sweep gradient starts at 3 o'clock; rotate so it begins at the gauge start + rotate(degrees = START_ANGLE - 5f) { + drawArc( + brush = Brush.sweepGradient( + 0f to Teal, + (SWEEP + 10f) / 360f to Purple, + 1f to Teal + ), + startAngle = 5f, + sweepAngle = (SWEEP * fraction).coerceAtLeast(1f), + useCenter = false, + topLeft = topLeft, + size = arcSize, + style = Stroke(width = stroke, cap = StrokeCap.Round) + ) + } + } + // scale labels + val paint = android.graphics.Paint().apply { + color = labelColor.toArgb() + textSize = labelSizePx + textAlign = android.graphics.Paint.Align.CENTER + isAntiAlias = true + } + val labelRadius = diameter / 2 + stroke / 2 + labelSizePx * 1.1f + val center = Offset(size.width / 2, size.height / 2) + SCALE_STOPS.forEachIndexed { index, stop -> + val angleDeg = START_ANGLE + SWEEP * index / (SCALE_STOPS.size - 1) + val rad = Math.toRadians(angleDeg.toDouble()) + val x = center.x + labelRadius * cos(rad).toFloat() + val y = center.y + labelRadius * sin(rad).toFloat() + labelSizePx * 0.35f + val text = if (stop < 1) "0" else stop.toInt().toString() + drawContext.canvas.nativeCanvas.drawText(text, x, y, paint) + } + } + content() + } +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/history/HistoryScreen.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/history/HistoryScreen.kt new file mode 100644 index 0000000..c98cda6 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/history/HistoryScreen.kt @@ -0,0 +1,189 @@ +package org.librespeed.speedtest.ui.history + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ChevronRight +import androidx.compose.material.icons.filled.DeleteOutline +import androidx.compose.material.icons.filled.Public +import androidx.compose.material.icons.filled.SettingsEthernet +import androidx.compose.material.icons.filled.SignalCellularAlt +import androidx.compose.material.icons.filled.Wifi +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.viewmodel.compose.viewModel +import org.librespeed.speedtest.R +import org.librespeed.speedtest.data.GeoDistance +import org.librespeed.speedtest.data.HistoryEntry +import org.librespeed.speedtest.ui.theme.Purple +import org.librespeed.speedtest.ui.theme.Teal +import java.text.DateFormat +import java.util.Date +import java.util.Locale + +@Composable +fun HistoryScreen( + onOpen: (Long) -> Unit, + viewModel: HistoryViewModel = viewModel() +) { + val entries by viewModel.entries.collectAsStateWithLifecycle() + var confirmClear by remember { mutableStateOf(false) } + + LaunchedEffect(Unit) { viewModel.load() } + + Column(Modifier.fillMaxSize()) { + Row( + modifier = Modifier.fillMaxWidth().padding(start = 20.dp, end = 8.dp, top = 8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = stringResource(R.string.nav_history), + style = MaterialTheme.typography.headlineSmall, + color = MaterialTheme.colorScheme.onBackground, + modifier = Modifier.weight(1f) + ) + IconButton(onClick = { confirmClear = true }, enabled = entries.isNotEmpty()) { + Icon(Icons.Filled.DeleteOutline, contentDescription = stringResource(R.string.history_clear)) + } + } + if (entries.isEmpty()) { + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + Text( + text = stringResource(R.string.history_empty), + color = MaterialTheme.colorScheme.onSurfaceVariant, + style = MaterialTheme.typography.bodyMedium + ) + } + } else { + LazyColumn(Modifier.fillMaxSize(), contentPadding = PaddingValues(16.dp)) { + items(entries, key = { it.id }) { entry -> + HistoryRow(entry = entry, onClick = { onOpen(entry.id) }) + Spacer(Modifier.height(8.dp)) + } + } + } + } + + if (confirmClear) { + AlertDialog( + onDismissRequest = { confirmClear = false }, + title = { Text(stringResource(R.string.history_clear)) }, + text = { Text(stringResource(R.string.history_clear_confirm)) }, + confirmButton = { + TextButton(onClick = { + confirmClear = false + viewModel.clear() + }) { Text(stringResource(R.string.history_clear)) } + }, + dismissButton = { + TextButton(onClick = { confirmClear = false }) { Text(stringResource(R.string.dialog_cancel)) } + } + ) + } +} + +fun formatDate(timestamp: Long): String = + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT).format(Date(timestamp)) + +@Composable +private fun HistoryRow(entry: HistoryEntry, onClick: () -> Unit) { + Card( + onClick = onClick, + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), + modifier = Modifier.fillMaxWidth() + ) { + Row( + modifier = Modifier.padding(horizontal = 14.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + imageVector = when { + entry.networkType == null -> Icons.Filled.Public + entry.networkType.startsWith("Wi-Fi") -> Icons.Filled.Wifi + entry.networkType == "Ethernet" -> Icons.Filled.SettingsEthernet + else -> Icons.Filled.SignalCellularAlt + }, + contentDescription = entry.networkType, + tint = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.size(20.dp) + ) + Spacer(Modifier.width(12.dp)) + Column(Modifier.weight(1f)) { + Text( + text = listOfNotNull(formatDate(entry.date), entry.networkType).joinToString(" • "), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + Text( + text = GeoDistance.cleanName(entry.server), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + Column(horizontalAlignment = Alignment.End) { + Text( + text = String.format(Locale.US, "%.0f", entry.download), + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.SemiBold, + color = Teal + ) + Text( + text = stringResource(R.string.unit_mbps), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + Spacer(Modifier.width(14.dp)) + Column(horizontalAlignment = Alignment.End) { + Text( + text = String.format(Locale.US, "%.0f", entry.upload), + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.SemiBold, + color = Purple + ) + Text( + text = stringResource(R.string.unit_mbps), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + Icon( + Icons.Filled.ChevronRight, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/history/HistoryViewModel.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/history/HistoryViewModel.kt new file mode 100644 index 0000000..fe2050c --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/history/HistoryViewModel.kt @@ -0,0 +1,40 @@ +package org.librespeed.speedtest.ui.history + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.librespeed.speedtest.data.HistoryDatabase +import org.librespeed.speedtest.data.HistoryEntry + +class HistoryViewModel(application: Application) : AndroidViewModel(application) { + + private val database = HistoryDatabase(application) + private val _entries = MutableStateFlow>(emptyList()) + val entries: StateFlow> = _entries + + fun load() { + viewModelScope.launch { + _entries.value = withContext(Dispatchers.IO) { database.readAll() } + } + } + + fun delete(entry: HistoryEntry) { + viewModelScope.launch { + withContext(Dispatchers.IO) { database.delete(entry.id) } + load() + } + } + + fun clear() { + viewModelScope.launch { + withContext(Dispatchers.IO) { database.clear() } + load() + } + } + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/ResultScreen.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/ResultScreen.kt new file mode 100644 index 0000000..e866cb7 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/ResultScreen.kt @@ -0,0 +1,410 @@ +package org.librespeed.speedtest.ui.result + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.ChevronRight +import androidx.compose.material.icons.filled.DataUsage +import androidx.compose.material.icons.filled.Lan +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.icons.filled.MyLocation +import androidx.compose.material.icons.filled.NetworkPing +import androidx.compose.material.icons.filled.PhoneAndroid +import androidx.compose.material.icons.filled.Public +import androidx.compose.material.icons.filled.Refresh +import androidx.compose.material.icons.filled.Schedule +import androidx.compose.material.icons.filled.Share +import androidx.compose.material.icons.filled.SsidChart +import androidx.compose.material.icons.filled.Tag +import androidx.compose.material.icons.outlined.ArrowCircleDown +import androidx.compose.material.icons.outlined.ArrowCircleUp +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.librespeed.speedtest.R +import org.librespeed.speedtest.data.AppPreferences +import org.librespeed.speedtest.data.GeoDistance +import org.librespeed.speedtest.data.HistoryDatabase +import org.librespeed.speedtest.data.HistoryEntry +import org.librespeed.speedtest.share.ShareResult +import org.librespeed.speedtest.ui.components.Sparkline +import org.librespeed.speedtest.ui.history.formatDate +import org.librespeed.speedtest.ui.theme.Purple +import org.librespeed.speedtest.ui.theme.Teal +import java.util.Locale + +@Composable +fun ResultScreen( + entryId: Long, + onBack: () -> Unit, + onTestAgain: (String) -> Unit, + onTestDetails: (Long) -> Unit, + onShare: (Long) -> Unit +) { + val context = LocalContext.current + val prefs = remember { AppPreferences(context.applicationContext) } + val useMBytes by prefs.useMBytes.collectAsStateWithLifecycle(initialValue = false) + var entry by remember { mutableStateOf(null) } + var missing by remember { mutableStateOf(false) } + var menuOpen by remember { mutableStateOf(false) } + + LaunchedEffect(entryId) { + val loaded = withContext(Dispatchers.IO) { HistoryDatabase(context.applicationContext).read(entryId) } + if (loaded == null) missing = true else entry = loaded + } + LaunchedEffect(missing) { if (missing) onBack() } + + val result = entry ?: return + val unitLabel = stringResource(if (useMBytes) R.string.unit_mbytes else R.string.unit_mbps) + fun display(value: Double): Double = if (useMBytes) value / 8 else value + + fun copyText() { + ShareResult.copy( + context, + ShareResult.buildText( + context, result.server, result.download, result.upload, result.ping, + result.jitter, result.loss, useMBytes, result.shareUrl, + result.networkType, result.ipVersion + ) + ) + } + + Column( + modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + modifier = Modifier.fillMaxWidth().padding(start = 4.dp, end = 4.dp, top = 4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + IconButton(onClick = onBack) { + Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.dialog_close)) + } + Text( + text = stringResource(R.string.result_title), + style = MaterialTheme.typography.titleLarge, + color = MaterialTheme.colorScheme.onBackground, + textAlign = TextAlign.Center, + modifier = Modifier.weight(1f) + ) + IconButton(onClick = { onShare(result.id) }) { + Icon(Icons.Filled.Share, contentDescription = stringResource(R.string.share_result), tint = MaterialTheme.colorScheme.onSurfaceVariant) + } + Box { + IconButton(onClick = { menuOpen = true }) { + Icon(Icons.Filled.MoreVert, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant) + } + DropdownMenu(expanded = menuOpen, onDismissRequest = { menuOpen = false }) { + DropdownMenuItem( + text = { Text(stringResource(R.string.test_details_title)) }, + onClick = { + menuOpen = false + onTestDetails(result.id) + } + ) + DropdownMenuItem( + text = { Text(stringResource(R.string.share_copy)) }, + onClick = { + menuOpen = false + copyText() + } + ) + val deleteScope = rememberCoroutineScope() + DropdownMenuItem( + text = { Text(stringResource(R.string.history_delete), color = MaterialTheme.colorScheme.error) }, + onClick = { + menuOpen = false + deleteScope.launch(Dispatchers.IO) { + HistoryDatabase(context.applicationContext).delete(result.id) + } + onBack() + } + ) + } + } + } + + Column(Modifier.widthIn(max = 560.dp).fillMaxWidth().padding(horizontal = 24.dp)) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth().padding(top = 4.dp, bottom = 12.dp) + ) { + Icon( + Icons.Filled.Public, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(18.dp) + ) + Spacer(Modifier.width(10.dp)) + Column { + Text( + text = formatDate(result.date), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface + ) + Text( + text = listOfNotNull( + GeoDistance.cleanName(result.server), + GeoDistance.sponsor(result.server) + ).joinToString(" · "), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + + Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { + SpeedCard( + modifier = Modifier.weight(1f), + icon = Icons.Outlined.ArrowCircleDown, + label = stringResource(R.string.test_download), + value = display(result.download), + unit = unitLabel, + accent = Teal, + samples = result.downloadSamples + ) + SpeedCard( + modifier = Modifier.weight(1f), + icon = Icons.Outlined.ArrowCircleUp, + label = stringResource(R.string.test_upload), + value = display(result.upload), + unit = unitLabel, + accent = Purple, + samples = result.uploadSamples + ) + } + + Spacer(Modifier.height(12.dp)) + Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { + MetricBox(Modifier.weight(1f), Icons.Filled.NetworkPing, stringResource(R.string.test_ping), result.ping, stringResource(R.string.unit_ms)) + MetricBox(Modifier.weight(1f), Icons.Filled.SsidChart, stringResource(R.string.test_jitter), result.jitter, stringResource(R.string.unit_ms)) + } + + Spacer(Modifier.height(16.dp)) + Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)) { + Column(Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 4.dp)) { + if (result.ipVersion != 0) { + DetailRow(stringResource(R.string.detail_protocol), "IPv${result.ipVersion}", Icons.Filled.Lan) + RowDivider() + } + result.ipInfo?.takeIf { it.isNotBlank() }?.let { info -> + DetailRow(stringResource(R.string.detail_ip), info.substringBefore(" - ").trim(), Icons.Filled.MyLocation) + RowDivider() + } + DetailRow(stringResource(R.string.detail_client), "Android ${android.os.Build.VERSION.RELEASE}", Icons.Filled.PhoneAndroid) + RowDivider() + DetailRow(stringResource(R.string.detail_server), GeoDistance.cleanName(result.server), Icons.Filled.Public) + result.shareUrl?.let { + RowDivider() + DetailRow(stringResource(R.string.detail_result_id), it.substringAfterLast("=", it), Icons.Filled.Tag) + } + if (result.durationMs > 0) { + RowDivider() + DetailRow(stringResource(R.string.detail_duration), String.format(Locale.US, "%.1f s", result.durationMs / 1000.0), Icons.Filled.Schedule) + } + val totalMb = (result.downloadSamples.sum() + result.uploadSamples.sum()) * 0.1 / 8 + if (totalMb > 0) { + RowDivider() + DetailRow(stringResource(R.string.detail_data), String.format(Locale.US, "~ %.0f MB", totalMb), Icons.Filled.DataUsage) + } + } + } + + Spacer(Modifier.height(16.dp)) + Button( + onClick = { onShare(result.id) }, + modifier = Modifier.fillMaxWidth().height(52.dp) + ) { + Icon(Icons.Filled.Share, contentDescription = null, modifier = Modifier.size(18.dp)) + Spacer(Modifier.width(8.dp)) + Text(stringResource(R.string.share_result), style = MaterialTheme.typography.titleMedium) + } + Spacer(Modifier.height(8.dp)) + OutlinedButton( + onClick = { onTestAgain(result.server) }, + border = BorderStroke(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.6f)), + colors = ButtonDefaults.outlinedButtonColors(contentColor = MaterialTheme.colorScheme.primary), + modifier = Modifier.fillMaxWidth().height(52.dp) + ) { + Icon(Icons.Filled.Refresh, contentDescription = null, modifier = Modifier.size(18.dp)) + Spacer(Modifier.width(8.dp)) + Text(stringResource(R.string.result_test_again), style = MaterialTheme.typography.titleMedium) + } + + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { onTestDetails(result.id) } + .padding(vertical = 14.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = stringResource(R.string.more_details), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier.weight(1f) + ) + Icon( + Icons.Filled.ChevronRight, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary + ) + } + Spacer(Modifier.height(12.dp)) + } + } +} + +@Composable +private fun SpeedCard( + modifier: Modifier, + icon: ImageVector, + label: String, + value: Double, + unit: String, + accent: Color, + samples: List +) { + Card(modifier = modifier, colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)) { + Column(Modifier.padding(12.dp)) { + Row(verticalAlignment = Alignment.CenterVertically) { + Icon(icon, contentDescription = null, tint = accent, modifier = Modifier.size(16.dp)) + Spacer(Modifier.width(6.dp)) + Text( + text = label.uppercase(Locale.ROOT), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + Spacer(Modifier.height(4.dp)) + Text( + text = String.format(Locale.US, "%.2f", value), + style = MaterialTheme.typography.headlineSmall, + fontWeight = FontWeight.Bold, + color = accent + ) + Text( + text = unit, + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + if (samples.size > 1) { + Sparkline( + data = samples, + color = accent, + modifier = Modifier.fillMaxWidth().height(30.dp).padding(top = 4.dp) + ) + } + } + } +} + +@Composable +private fun MetricBox(modifier: Modifier, icon: ImageVector, title: String, value: Double, unit: String) { + Card(modifier = modifier, colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)) { + Column(Modifier.padding(vertical = 14.dp).fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { + Row(verticalAlignment = Alignment.CenterVertically) { + Icon(icon, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.size(13.dp)) + Spacer(Modifier.width(4.dp)) + Text( + text = title.uppercase(Locale.ROOT), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + Spacer(Modifier.height(4.dp)) + Row(verticalAlignment = Alignment.Bottom) { + Text( + text = if (value < 0) "—" else String.format(Locale.US, "%.1f", value), + style = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.Bold, + color = MaterialTheme.colorScheme.primary + ) + Spacer(Modifier.width(4.dp)) + Text( + text = unit, + modifier = Modifier.padding(bottom = 3.dp), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + } +} + +@Composable +internal fun DetailRow(title: String, value: String, icon: ImageVector? = null) { + Row(Modifier.fillMaxWidth().padding(vertical = 9.dp), verticalAlignment = Alignment.CenterVertically) { + icon?.let { + Icon( + it, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.size(16.dp) + ) + Spacer(Modifier.width(10.dp)) + } + Text( + text = title, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + Spacer(Modifier.width(16.dp)) + Text( + text = value, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurface, + textAlign = TextAlign.End, + modifier = Modifier.weight(1f) + ) + } +} + +@Composable +internal fun RowDivider() { + HorizontalDivider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f)) +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/ShareScreen.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/ShareScreen.kt new file mode 100644 index 0000000..03a50e8 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/ShareScreen.kt @@ -0,0 +1,167 @@ +package org.librespeed.speedtest.ui.result + +import android.graphics.Bitmap +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.ContentCopy +import androidx.compose.material.icons.filled.Link +import androidx.compose.material.icons.filled.Photo +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.librespeed.speedtest.R +import org.librespeed.speedtest.data.AppPreferences +import org.librespeed.speedtest.data.HistoryDatabase +import org.librespeed.speedtest.data.HistoryEntry +import org.librespeed.speedtest.share.ShareImage +import org.librespeed.speedtest.share.ShareResult + +@Composable +fun ShareScreen(entryId: Long, onBack: () -> Unit) { + val context = LocalContext.current + val prefs = remember { AppPreferences(context.applicationContext) } + val useMBytes by prefs.useMBytes.collectAsStateWithLifecycle(initialValue = false) + var entry by remember { mutableStateOf(null) } + var missing by remember { mutableStateOf(false) } + var preview by remember { mutableStateOf(null) } + + LaunchedEffect(entryId) { + val loaded = withContext(Dispatchers.IO) { HistoryDatabase(context.applicationContext).read(entryId) } + if (loaded == null) missing = true else entry = loaded + } + LaunchedEffect(missing) { if (missing) onBack() } + LaunchedEffect(entry, useMBytes) { + entry?.let { loaded -> + preview = withContext(Dispatchers.Default) { ShareImage.render(context, loaded, useMBytes) } + } + } + + val result = entry ?: return + + fun copyText() { + ShareResult.copy( + context, + ShareResult.buildText( + context, result.server, result.download, result.upload, result.ping, + result.jitter, result.loss, useMBytes, result.shareUrl, + result.networkType, result.ipVersion + ) + ) + } + + Column( + modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + modifier = Modifier.fillMaxWidth().padding(start = 4.dp, end = 48.dp, top = 4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + IconButton(onClick = onBack) { + Icon(Icons.Filled.Close, contentDescription = stringResource(R.string.dialog_close)) + } + Text( + text = stringResource(R.string.share_result), + style = MaterialTheme.typography.titleLarge, + color = MaterialTheme.colorScheme.onBackground, + textAlign = TextAlign.Center, + modifier = Modifier.weight(1f) + ) + } + + Column(Modifier.widthIn(max = 560.dp).fillMaxWidth().padding(horizontal = 24.dp)) { + preview?.let { bitmap -> + Image( + bitmap = bitmap.asImageBitmap(), + contentDescription = null, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp) + .clip(RoundedCornerShape(20.dp)) + ) + } + + Spacer(Modifier.padding(top = 16.dp)) + Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)) { + Column(Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 4.dp)) { + ShareOption( + icon = Icons.Filled.Photo, + title = stringResource(R.string.share_image), + subtitle = stringResource(R.string.share_image_hint) + ) { ShareImage.share(context, result, useMBytes) } + result.shareUrl?.let { url -> + OptionDivider() + ShareOption( + icon = Icons.Filled.Link, + title = stringResource(R.string.share_link), + subtitle = stringResource(R.string.share_link_hint) + ) { ShareResult.shareLink(context, url) } + } + OptionDivider() + ShareOption( + icon = Icons.Filled.ContentCopy, + title = stringResource(R.string.share_copy), + subtitle = stringResource(R.string.share_copy_hint) + ) { copyText() } + } + } + Spacer(Modifier.padding(bottom = 20.dp)) + } + } +} + +@Composable +private fun OptionDivider() { + HorizontalDivider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f)) +} + +@Composable +private fun ShareOption(icon: ImageVector, title: String, subtitle: String, onClick: () -> Unit) { + Row( + modifier = Modifier.fillMaxWidth().clickable(onClick = onClick).padding(vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon(icon, contentDescription = null, tint = MaterialTheme.colorScheme.primary, modifier = Modifier.size(24.dp)) + Spacer(Modifier.width(14.dp)) + Column { + Text(title, style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onSurface) + Text(subtitle, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant) + } + } +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/TestDetailsScreen.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/TestDetailsScreen.kt new file mode 100644 index 0000000..0443f3d --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/result/TestDetailsScreen.kt @@ -0,0 +1,184 @@ +package org.librespeed.speedtest.ui.result + +import android.os.Build +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Android +import androidx.compose.material.icons.filled.Apps +import androidx.compose.material.icons.filled.ArrowDownward +import androidx.compose.material.icons.filled.ArrowUpward +import androidx.compose.material.icons.filled.Business +import androidx.compose.material.icons.filled.CloudUpload +import androidx.compose.material.icons.filled.DataUsage +import androidx.compose.material.icons.filled.Event +import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.filled.Lan +import androidx.compose.material.icons.filled.MyLocation +import androidx.compose.material.icons.filled.NetworkPing +import androidx.compose.material.icons.filled.Public +import androidx.compose.material.icons.filled.Schedule +import androidx.compose.material.icons.filled.Smartphone +import androidx.compose.material.icons.filled.Tag +import androidx.compose.material.icons.filled.Wifi +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.librespeed.speedtest.BuildConfig +import org.librespeed.speedtest.R +import org.librespeed.speedtest.data.GeoDistance +import org.librespeed.speedtest.data.HistoryDatabase +import org.librespeed.speedtest.data.HistoryEntry +import org.librespeed.speedtest.ui.history.formatDate +import java.util.Locale + +@Composable +fun TestDetailsScreen(entryId: Long, onBack: () -> Unit) { + val context = LocalContext.current + var entry by remember { mutableStateOf(null) } + var missing by remember { mutableStateOf(false) } + + LaunchedEffect(entryId) { + val loaded = withContext(Dispatchers.IO) { HistoryDatabase(context.applicationContext).read(entryId) } + if (loaded == null) missing = true else entry = loaded + } + LaunchedEffect(missing) { if (missing) onBack() } + + val result = entry ?: return + + Column( + modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + modifier = Modifier.fillMaxWidth().padding(start = 4.dp, end = 16.dp, top = 4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + IconButton(onClick = onBack) { + Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.dialog_close)) + } + Text( + text = stringResource(R.string.test_details_title), + style = MaterialTheme.typography.titleLarge, + color = MaterialTheme.colorScheme.onBackground + ) + } + + Column(Modifier.widthIn(max = 560.dp).fillMaxWidth().padding(horizontal = 20.dp)) { + Section(stringResource(R.string.section_test)) { + result.shareUrl?.let { + DetailRow(stringResource(R.string.detail_result_id), it.substringAfterLast("=", it), Icons.Filled.Tag) + RowDivider() + } + DetailRow(stringResource(R.string.section_date), formatDate(result.date), Icons.Filled.Event) + if (result.durationMs > 0) { + RowDivider() + DetailRow(stringResource(R.string.detail_duration), String.format(Locale.US, "%.1f s", result.durationMs / 1000.0), Icons.Filled.Schedule) + } + } + + Section(stringResource(R.string.section_server)) { + DetailRow(stringResource(R.string.servers_add_name), GeoDistance.cleanName(result.server), Icons.Filled.Public) + GeoDistance.sponsor(result.server)?.let { + RowDivider() + DetailRow(stringResource(R.string.detail_isp), it, Icons.Filled.Business) + } + if (result.ping >= 0) { + RowDivider() + DetailRow(stringResource(R.string.info_latency), String.format(Locale.US, "%.1f %s", result.ping, stringResource(R.string.unit_ms)), Icons.Filled.NetworkPing) + } + } + + Section(stringResource(R.string.section_network)) { + if (result.ipVersion != 0) { + DetailRow(stringResource(R.string.detail_protocol), "IPv${result.ipVersion}", Icons.Filled.Lan) + RowDivider() + } + result.networkType?.let { + DetailRow(stringResource(R.string.detail_network), it, Icons.Filled.Wifi) + RowDivider() + } + result.ipInfo?.takeIf { it.isNotBlank() }?.let { info -> + val ip = info.substringBefore(" - ").trim() + val provider = info.substringAfter(" - ", "").trim() + DetailRow(stringResource(R.string.detail_ip), ip, Icons.Filled.MyLocation) + if (provider.isNotEmpty()) { + RowDivider() + DetailRow(stringResource(R.string.detail_isp), provider, Icons.Filled.Business) + } + } + } + + Section(stringResource(R.string.section_data)) { + val downloadMb = result.downloadSamples.sum() * 0.1 / 8 + val uploadMb = result.uploadSamples.sum() * 0.1 / 8 + if (downloadMb > 0) { + DetailRow(stringResource(R.string.detail_dl_data), String.format(Locale.US, "~ %.0f MB", downloadMb), Icons.Filled.ArrowDownward) + RowDivider() + } + if (uploadMb > 0) { + DetailRow(stringResource(R.string.detail_ul_data), String.format(Locale.US, "~ %.0f MB", uploadMb), Icons.Filled.ArrowUpward) + RowDivider() + } + DetailRow(stringResource(R.string.detail_data), String.format(Locale.US, "~ %.0f MB", downloadMb + uploadMb), Icons.Filled.DataUsage) + } + + Section(stringResource(R.string.section_telemetry)) { + DetailRow( + stringResource(R.string.settings_section_telemetry), + stringResource(if (result.shareUrl != null) R.string.telemetry_submitted else R.string.telemetry_not_submitted), + Icons.Filled.CloudUpload + ) + } + + Section(stringResource(R.string.section_client)) { + DetailRow(stringResource(R.string.section_application), "LibreSpeed", Icons.Filled.Apps) + RowDivider() + DetailRow(stringResource(R.string.section_version), BuildConfig.VERSION_NAME, Icons.Filled.Info) + RowDivider() + DetailRow("Android", Build.VERSION.RELEASE, Icons.Filled.Android) + RowDivider() + DetailRow(stringResource(R.string.section_device), "${Build.MANUFACTURER} ${Build.MODEL}", Icons.Filled.Smartphone) + } + Spacer(Modifier.height(20.dp)) + } + } +} + +@Composable +private fun Section(title: String, content: @Composable () -> Unit) { + Text( + text = title.uppercase(), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier.fillMaxWidth().padding(top = 16.dp, bottom = 6.dp) + ) + Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)) { + Column(Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 4.dp)) { content() } + } +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/servers/ServerSheet.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/servers/ServerSheet.kt new file mode 100644 index 0000000..5611b28 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/servers/ServerSheet.kt @@ -0,0 +1,259 @@ +package org.librespeed.speedtest.ui.servers + +import android.content.Intent +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material.icons.filled.Share +import androidx.compose.material.icons.filled.Speed +import androidx.compose.material.icons.filled.Star +import androidx.compose.material.icons.outlined.StarBorder +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import com.fdossena.speedtest.core.serverSelector.TestPoint +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.librespeed.speedtest.R +import org.librespeed.speedtest.data.GeoDistance +import org.librespeed.speedtest.data.HistoryDatabase +import org.librespeed.speedtest.data.key +import org.librespeed.speedtest.ui.history.formatDate +import java.net.Inet4Address +import java.net.Inet6Address +import java.net.InetAddress + +@androidx.compose.material3.ExperimentalMaterial3Api +@Composable +fun ServerSheet( + server: TestPoint, + favorite: Boolean, + custom: Boolean, + distanceKm: Int?, + onSelect: () -> Unit, + onToggleFavorite: () -> Unit, + onPing: () -> Unit, + onDelete: () -> Unit, + onDismiss: () -> Unit +) { + val context = LocalContext.current + val host = GeoDistance.hostLabel(server.server) + var ipv4 by remember { mutableStateOf(null) } + var ipv6 by remember { mutableStateOf(null) } + var lastTest by remember { mutableStateOf(null) } + + LaunchedEffect(server.key()) { + withContext(Dispatchers.IO) { + try { + val addresses = InetAddress.getAllByName(host.substringBefore("/").substringBefore(":")) + ipv4 = addresses.firstOrNull { it is Inet4Address }?.hostAddress + ipv6 = addresses.firstOrNull { it is Inet6Address }?.hostAddress + } catch (_: Exception) { + } + lastTest = try { + HistoryDatabase(context.applicationContext).readAll() + .firstOrNull { it.server == server.name }?.date + } catch (_: Exception) { + null + } + } + } + + ModalBottomSheet(onDismissRequest = onDismiss) { + Column( + modifier = Modifier + .fillMaxWidth() + .verticalScroll(rememberScrollState()) + .padding(start = 20.dp, end = 20.dp, bottom = 24.dp) + ) { + Row(verticalAlignment = Alignment.CenterVertically) { + Column(Modifier.weight(1f)) { + Text( + text = GeoDistance.cleanName(server.name), + style = MaterialTheme.typography.titleMedium, + color = MaterialTheme.colorScheme.onSurface, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + Text( + text = host, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + if (server.ping >= 0) { + Text( + text = "${server.ping.toInt()} ${stringResource(R.string.unit_ms)}", + style = MaterialTheme.typography.titleSmall, + color = MaterialTheme.colorScheme.primary + ) + } + IconButton(onClick = onToggleFavorite) { + Icon( + imageVector = if (favorite) Icons.Filled.Star else Icons.Outlined.StarBorder, + contentDescription = stringResource(R.string.servers_favorite), + tint = if (favorite) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + HorizontalDivider(Modifier.padding(vertical = 10.dp), color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f)) + + SheetAction( + icon = Icons.Filled.PlayArrow, + title = stringResource(R.string.sheet_select), + subtitle = stringResource(R.string.sheet_select_hint), + onClick = onSelect + ) + if (!favorite) { + SheetAction( + icon = Icons.Outlined.StarBorder, + title = stringResource(R.string.sheet_favorite), + subtitle = stringResource(R.string.sheet_favorite_hint), + onClick = onToggleFavorite + ) + } + SheetAction( + icon = Icons.Filled.Info, + title = stringResource(R.string.sheet_info), + subtitle = stringResource(R.string.sheet_info_hint), + onClick = null + ) + Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerHigh)) { + Column(Modifier.fillMaxWidth().padding(horizontal = 14.dp, vertical = 6.dp)) { + InfoRow(stringResource(R.string.info_location), GeoDistance.cleanName(server.name)) + GeoDistance.sponsor(server.name)?.let { InfoRow(stringResource(R.string.detail_isp), it) } + InfoRow(stringResource(R.string.detail_server), host) + distanceKm?.let { InfoRow(stringResource(R.string.info_distance), "~ $it km") } + if (server.ping >= 0) InfoRow(stringResource(R.string.info_latency), "${server.ping.toInt()} ${stringResource(R.string.unit_ms)}") + ipv4?.let { InfoRow("IPv4", it) } + ipv6?.let { InfoRow("IPv6", it) } + lastTest?.let { InfoRow(stringResource(R.string.info_last_test), formatDate(it)) } + } + } + SheetAction( + icon = Icons.Filled.Speed, + title = stringResource(R.string.sheet_ping), + subtitle = stringResource(R.string.sheet_ping_hint), + onClick = onPing + ) + val shareTitle = stringResource(R.string.sheet_share) + val shareText = stringResource(R.string.share_server_text, GeoDistance.cleanName(server.name), server.server) + SheetAction( + icon = Icons.Filled.Share, + title = shareTitle, + subtitle = stringResource(R.string.sheet_share_hint), + onClick = { + val intent = Intent(Intent.ACTION_SEND).apply { + type = "text/plain" + putExtra(Intent.EXTRA_TEXT, shareText) + } + try { + context.startActivity(Intent.createChooser(intent, shareTitle)) + } catch (_: Exception) { + } + } + ) + if (favorite) { + SheetAction( + icon = Icons.Filled.Delete, + title = stringResource(R.string.sheet_unfavorite), + subtitle = stringResource(R.string.sheet_unfavorite_hint), + tint = FavoriteRed, + onClick = onToggleFavorite + ) + } + if (custom) { + SheetAction( + icon = Icons.Filled.Delete, + title = stringResource(R.string.servers_delete), + subtitle = stringResource(R.string.sheet_delete_hint), + tint = FavoriteRed, + onClick = onDelete + ) + } + } + } +} + +private val FavoriteRed = Color(0xFFEF4444) + +@Composable +private fun SheetAction( + icon: ImageVector, + title: String, + subtitle: String, + tint: Color = MaterialTheme.colorScheme.primary, + onClick: (() -> Unit)? +) { + val rowModifier = if (onClick != null) { + Modifier.fillMaxWidth().clickable(onClick = onClick).padding(vertical = 10.dp) + } else { + Modifier.fillMaxWidth().padding(vertical = 10.dp) + } + Row(rowModifier, verticalAlignment = Alignment.CenterVertically) { + Icon(icon, contentDescription = null, tint = tint, modifier = Modifier.size(24.dp)) + Spacer(Modifier.width(14.dp)) + Column { + Text( + text = title, + style = MaterialTheme.typography.bodyLarge, + color = if (tint == FavoriteRed) tint else MaterialTheme.colorScheme.onSurface + ) + Text( + text = subtitle, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } +} + +@Composable +private fun InfoRow(title: String, value: String) { + Row(Modifier.fillMaxWidth().padding(vertical = 6.dp), verticalAlignment = Alignment.CenterVertically) { + Text( + text = title, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.width(130.dp) + ) + Text( + text = value, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface + ) + } +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/servers/ServersScreen.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/servers/ServersScreen.kt new file mode 100644 index 0000000..6e304c6 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/servers/ServersScreen.kt @@ -0,0 +1,357 @@ +package org.librespeed.speedtest.ui.servers + +import android.Manifest +import android.content.pm.PackageManager +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.icons.filled.Public +import androidx.compose.material.icons.filled.Refresh +import androidx.compose.material.icons.filled.Star +import androidx.compose.material.icons.outlined.StarBorder +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Tab +import androidx.compose.material3.TabRow +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.core.content.ContextCompat +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.fdossena.speedtest.core.serverSelector.TestPoint +import org.librespeed.speedtest.R +import org.librespeed.speedtest.data.GeoDistance +import org.librespeed.speedtest.data.key +import org.librespeed.speedtest.ui.speedtest.SpeedtestViewModel +import org.librespeed.speedtest.ui.theme.DangerRed +import org.librespeed.speedtest.ui.theme.Teal + +private val Amber = Color(0xFFF7941D) + +@androidx.compose.material3.ExperimentalMaterial3Api +@Composable +fun ServersScreen(viewModel: SpeedtestViewModel) { + val state by viewModel.state.collectAsStateWithLifecycle() + val context = LocalContext.current + //start on All servers when there are no favorites yet + var tabOverride by remember { mutableIntStateOf(-1) } + val tab = if (tabOverride != -1) tabOverride else if (state.favorites.isEmpty()) 1 else 0 + var showAddDialog by remember { mutableStateOf(false) } + var sheetServer by remember { mutableStateOf(null) } + var hasLocation by remember { + mutableStateOf( + ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == + PackageManager.PERMISSION_GRANTED + ) + } + val locationLauncher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> + hasLocation = granted + if (granted) viewModel.computeDistances() + } + + val sorted = remember(state.servers, state.customKeys) { + state.servers + .filter { it.ping >= 0 || it.key() in state.customKeys } + .sortedBy { if (it.ping < 0) Float.MAX_VALUE else it.ping } + } + val visible = if (tab == 0) sorted.filter { it.key() in state.favorites } else sorted + + Column(Modifier.fillMaxSize()) { + Row( + modifier = Modifier.fillMaxWidth().padding(start = 20.dp, end = 8.dp, top = 8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = stringResource(R.string.nav_servers), + style = MaterialTheme.typography.headlineSmall, + color = MaterialTheme.colorScheme.onBackground, + modifier = Modifier.weight(1f) + ) + IconButton(onClick = { showAddDialog = true }) { + Icon(Icons.Filled.Add, contentDescription = stringResource(R.string.servers_add)) + } + IconButton(onClick = { viewModel.refreshServers() }, enabled = !state.selectingServers) { + if (state.selectingServers) { + CircularProgressIndicator(modifier = Modifier.size(20.dp), strokeWidth = 2.dp) + } else { + Icon(Icons.Filled.Refresh, contentDescription = stringResource(R.string.servers_refresh)) + } + } + } + Card( + onClick = { viewModel.useAutoSelect() }, + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), + border = if (!state.pinnedServer) BorderStroke(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.7f)) else null, + modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp) + ) { + Row( + modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + Icons.Filled.Public, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(20.dp) + ) + Spacer(Modifier.width(12.dp)) + Column(Modifier.weight(1f)) { + Text( + text = stringResource(R.string.server_auto_select), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface + ) + if (!state.pinnedServer && state.selectedServer != null) { + Text( + text = GeoDistance.cleanName(state.selectedServer!!.name), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + } + if (!state.pinnedServer) { + Icon( + Icons.Filled.Check, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary + ) + } + } + } + if (!hasLocation) { + TextButton( + onClick = { locationLauncher.launch(Manifest.permission.ACCESS_COARSE_LOCATION) }, + modifier = Modifier.padding(horizontal = 8.dp) + ) { + Text(stringResource(R.string.servers_show_distances)) + } + } + TabRow(selectedTabIndex = tab, containerColor = MaterialTheme.colorScheme.background) { + Tab(selected = tab == 0, onClick = { tabOverride = 0 }, text = { Text(stringResource(R.string.servers_favorites)) }) + Tab(selected = tab == 1, onClick = { tabOverride = 1 }, text = { Text(stringResource(R.string.servers_all)) }) + } + if (visible.isEmpty()) { + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + Text( + text = stringResource(if (tab == 0) R.string.servers_no_favorites else R.string.servers_none), + color = MaterialTheme.colorScheme.onSurfaceVariant, + style = MaterialTheme.typography.bodyMedium + ) + } + } else { + LazyColumn(Modifier.fillMaxSize(), contentPadding = PaddingValues(16.dp)) { + items(visible, key = { it.key() }) { server -> + ServerRow( + server = server, + selected = state.pinnedServer && state.selectedServer?.key() == server.key(), + favorite = server.key() in state.favorites, + distanceKm = state.distances[server.key()], + onClick = { viewModel.selectServer(server) }, + onToggleFavorite = { viewModel.toggleFavorite(server) }, + onMore = { sheetServer = server } + ) + Spacer(Modifier.height(8.dp)) + } + } + } + } + + sheetServer?.let { server -> + ServerSheet( + server = server, + favorite = server.key() in state.favorites, + custom = server.key() in state.customKeys, + distanceKm = state.distances[server.key()], + onSelect = { + viewModel.selectServer(server) + sheetServer = null + }, + onToggleFavorite = { viewModel.toggleFavorite(server) }, + onPing = { viewModel.pingServer(server) }, + onDelete = { + viewModel.removeCustomServer(server) + sheetServer = null + }, + onDismiss = { sheetServer = null } + ) + } + + if (showAddDialog) { + AddServerDialog( + onDismiss = { showAddDialog = false }, + onAdd = { name, url -> + if (viewModel.addCustomServer(name, url)) { + showAddDialog = false + true + } else false + } + ) + } +} + +private fun latencyColor(ping: Float): Color = when { + ping < 50 -> Teal + ping < 150 -> Amber + else -> DangerRed +} + +@Composable +private fun ServerRow( + server: TestPoint, + selected: Boolean, + favorite: Boolean, + distanceKm: Int?, + onClick: () -> Unit, + onToggleFavorite: () -> Unit, + onMore: () -> Unit +) { + Card( + onClick = onClick, + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), + border = if (selected) BorderStroke(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.7f)) else null, + modifier = Modifier.fillMaxWidth() + ) { + Row( + modifier = Modifier.padding(start = 16.dp, end = 4.dp, top = 8.dp, bottom = 8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Column(Modifier.weight(1f)) { + Text( + text = GeoDistance.cleanName(server.name), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + Text( + text = GeoDistance.hostLabel(server.server), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + Column(horizontalAlignment = Alignment.End) { + if (server.ping >= 0) { + Text( + text = "${server.ping.toInt()} ${stringResource(R.string.unit_ms)}", + style = MaterialTheme.typography.labelMedium, + color = latencyColor(server.ping) + ) + } else { + Text( + text = stringResource(R.string.servers_unreachable), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.error + ) + } + distanceKm?.let { + Text( + text = "$it km", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + IconButton(onClick = onToggleFavorite) { + Icon( + imageVector = if (favorite) Icons.Filled.Star else Icons.Outlined.StarBorder, + contentDescription = stringResource(R.string.servers_favorite), + tint = if (favorite) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant + ) + } + IconButton(onClick = onMore) { + Icon( + Icons.Filled.MoreVert, + contentDescription = stringResource(R.string.servers_details), + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + } +} + +@Composable +private fun AddServerDialog(onDismiss: () -> Unit, onAdd: (String, String) -> Boolean) { + var name by remember { mutableStateOf("") } + var url by remember { mutableStateOf("") } + var failed by remember { mutableStateOf(false) } + + AlertDialog( + onDismissRequest = onDismiss, + title = { Text(stringResource(R.string.servers_add)) }, + text = { + Column { + OutlinedTextField( + value = name, + onValueChange = { name = it }, + singleLine = true, + label = { Text(stringResource(R.string.servers_add_name)) } + ) + Spacer(Modifier.height(10.dp)) + OutlinedTextField( + value = url, + onValueChange = { url = it }, + singleLine = true, + label = { Text(stringResource(R.string.servers_add_url)) }, + placeholder = { Text("https://speedtest.example.com/backend") }, + isError = failed + ) + Spacer(Modifier.height(6.dp)) + Text( + text = stringResource(if (failed) R.string.servers_add_invalid else R.string.servers_add_hint), + style = MaterialTheme.typography.bodySmall, + color = if (failed) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onSurfaceVariant + ) + } + }, + confirmButton = { + TextButton( + enabled = name.isNotBlank() && url.isNotBlank(), + onClick = { failed = !onAdd(name, url) } + ) { Text(stringResource(R.string.servers_add_confirm)) } + }, + dismissButton = { + TextButton(onClick = onDismiss) { Text(stringResource(R.string.dialog_cancel)) } + } + ) +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/settings/SettingsScreen.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/settings/SettingsScreen.kt new file mode 100644 index 0000000..389d35e --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/settings/SettingsScreen.kt @@ -0,0 +1,335 @@ +package org.librespeed.speedtest.ui.settings + +import android.content.Intent +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ChevronRight +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.RadioButton +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.unit.dp +import androidx.core.net.toUri +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import kotlinx.coroutines.launch +import org.librespeed.speedtest.R +import org.librespeed.speedtest.data.AppPreferences +import org.librespeed.speedtest.data.ClientInfo + +private const val PROJECT_URL = "https://github.com/librespeed/speedtest-android" +private const val WEBSITE_URL = "https://librespeed.org" + +@Composable +fun SettingsScreen( + serverLabel: String?, + serverPinned: Boolean, + onServersClick: () -> Unit +) { + val context = LocalContext.current + val prefs = remember { AppPreferences(context.applicationContext) } + val scope = rememberCoroutineScope() + + val themeMode by prefs.themeMode.collectAsStateWithLifecycle(initialValue = "system") + val useMBytes by prefs.useMBytes.collectAsStateWithLifecycle(initialValue = false) + val telemetry by prefs.telemetryEnabled.collectAsStateWithLifecycle(initialValue = false) + val singleConnection by prefs.singleConnection.collectAsStateWithLifecycle(initialValue = false) + + var unitsDialog by remember { mutableStateOf(false) } + var themeDialog by remember { mutableStateOf(false) } + var testModeDialog by remember { mutableStateOf(false) } + var whatIsSentDialog by remember { mutableStateOf(false) } + + Column( + modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 20.dp) + ) { + Spacer(Modifier.height(8.dp)) + Text( + text = stringResource(R.string.nav_settings), + style = MaterialTheme.typography.headlineSmall, + color = MaterialTheme.colorScheme.onBackground + ) + SectionTitle(stringResource(R.string.settings_section_general)) + SettingsCard { + ValueRow( + title = stringResource(R.string.settings_server), + value = when { + serverPinned && serverLabel != null -> serverLabel + else -> stringResource(R.string.server_auto_select) + }, + onClick = onServersClick + ) + RowDivider() + ValueRow( + title = stringResource(R.string.settings_units), + value = stringResource(if (useMBytes) R.string.unit_mbytes else R.string.unit_mbps), + onClick = { unitsDialog = true } + ) + RowDivider() + ValueRow( + title = stringResource(R.string.settings_theme), + value = stringResource( + when (themeMode) { + "light" -> R.string.theme_light + "dark" -> R.string.theme_dark + else -> R.string.theme_system + } + ), + onClick = { themeDialog = true } + ) + RowDivider() + ValueRow( + title = stringResource(R.string.settings_test_mode), + value = stringResource(if (singleConnection) R.string.test_mode_single else R.string.test_mode_standard), + onClick = { testModeDialog = true } + ) + } + SectionTitle(stringResource(R.string.settings_section_telemetry)) + SettingsCard { + Row(verticalAlignment = Alignment.CenterVertically) { + Column(Modifier.weight(1f)) { + Text( + text = stringResource(R.string.settings_telemetry), + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurface + ) + Text( + text = stringResource(R.string.settings_telemetry_summary), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + Switch( + checked = telemetry, + onCheckedChange = { checked -> scope.launch { prefs.setTelemetryEnabled(checked) } } + ) + } + Text( + text = stringResource(R.string.settings_whats_sent), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier + .clickable(onClick = { whatIsSentDialog = true }, role = Role.Button) + .padding(top = 10.dp, bottom = 2.dp) + ) + } + SectionTitle(stringResource(R.string.settings_section_about)) + SettingsCard { + Column(Modifier.padding(vertical = 10.dp)) { + Text( + text = ClientInfo.client, + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurface + ) + Text( + text = stringResource(R.string.settings_license), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + RowDivider() + NavRow(stringResource(R.string.settings_licenses)) { context.openUrl("$PROJECT_URL/blob/master/LICENSE") } + RowDivider() + NavRow(stringResource(R.string.settings_source)) { context.openUrl(PROJECT_URL) } + RowDivider() + NavRow(stringResource(R.string.settings_website)) { context.openUrl(WEBSITE_URL) } + RowDivider() + NavRow(stringResource(R.string.settings_privacy)) { context.openUrl("$PROJECT_URL/blob/master/PRIVACY.md") } + } + Spacer(Modifier.height(16.dp)) + } + + if (unitsDialog) { + RadioDialog( + title = stringResource(R.string.settings_units), + options = listOf( + stringResource(R.string.unit_mbps_long) to !useMBytes, + stringResource(R.string.unit_mbytes_long) to useMBytes + ), + hint = stringResource(R.string.settings_units_hint), + onSelect = { index -> scope.launch { prefs.setUseMBytes(index == 1) } }, + onDismiss = { unitsDialog = false } + ) + } + if (themeDialog) { + RadioDialog( + title = stringResource(R.string.settings_theme), + options = listOf( + stringResource(R.string.theme_system) to (themeMode == "system"), + stringResource(R.string.theme_light) to (themeMode == "light"), + stringResource(R.string.theme_dark) to (themeMode == "dark") + ), + hint = null, + onSelect = { index -> + scope.launch { prefs.setThemeMode(listOf("system", "light", "dark")[index]) } + }, + onDismiss = { themeDialog = false } + ) + } + if (testModeDialog) { + RadioDialog( + title = stringResource(R.string.settings_test_mode), + options = listOf( + stringResource(R.string.test_mode_standard) to !singleConnection, + stringResource(R.string.test_mode_single) to singleConnection + ), + hint = stringResource(R.string.test_mode_hint), + onSelect = { index -> scope.launch { prefs.setSingleConnection(index == 1) } }, + onDismiss = { testModeDialog = false } + ) + } + if (whatIsSentDialog) { + AlertDialog( + onDismissRequest = { whatIsSentDialog = false }, + title = { Text(stringResource(R.string.settings_whats_sent)) }, + text = { Text(stringResource(R.string.settings_telemetry_detail)) }, + confirmButton = { + TextButton(onClick = { whatIsSentDialog = false }) { Text(stringResource(R.string.dialog_close)) } + } + ) + } +} + +private fun android.content.Context.openUrl(url: String) { + try { + startActivity(Intent(Intent.ACTION_VIEW, url.toUri())) + } catch (_: Exception) { + } +} + +@Composable +private fun SectionTitle(text: String) { + Text( + text = text.uppercase(), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(top = 20.dp, bottom = 8.dp) + ) +} + +@Composable +private fun SettingsCard(content: @Composable () -> Unit) { + Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)) { + Column(Modifier.fillMaxWidth().padding(16.dp)) { content() } + } +} + +@Composable +private fun ValueRow(title: String, value: String, onClick: () -> Unit) { + Row( + modifier = Modifier.fillMaxWidth().clickable(onClick = onClick, role = Role.Button).padding(vertical = 10.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Column(Modifier.weight(1f)) { + Text( + text = title, + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurface + ) + Text( + text = value, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + Icon( + Icons.Filled.ChevronRight, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + } +} + +@Composable +private fun RowDivider() { + HorizontalDivider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f)) +} + +@Composable +private fun NavRow(label: String, onClick: () -> Unit) { + Row( + modifier = Modifier.fillMaxWidth().clickable(onClick = onClick, role = Role.Button).padding(vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = label, + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurface, + modifier = Modifier.weight(1f) + ) + Icon( + Icons.Filled.ChevronRight, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + } +} + +@Composable +private fun RadioDialog( + title: String, + options: List>, + hint: String?, + onSelect: (Int) -> Unit, + onDismiss: () -> Unit +) { + AlertDialog( + onDismissRequest = onDismiss, + title = { Text(title) }, + text = { + Column { + options.forEachIndexed { index, (label, selected) -> + Row( + modifier = Modifier.fillMaxWidth().clickable { + onSelect(index) + onDismiss() + }, + verticalAlignment = Alignment.CenterVertically + ) { + RadioButton(selected = selected, onClick = { + onSelect(index) + onDismiss() + }) + Text(label, style = MaterialTheme.typography.bodyMedium) + } + } + hint?.let { + Text( + text = it, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(top = 8.dp) + ) + } + } + }, + confirmButton = { + TextButton(onClick = onDismiss) { Text(stringResource(R.string.dialog_close)) } + } + ) +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/speedtest/SpeedtestScreen.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/speedtest/SpeedtestScreen.kt new file mode 100644 index 0000000..50bcf40 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/speedtest/SpeedtestScreen.kt @@ -0,0 +1,390 @@ +package org.librespeed.speedtest.ui.speedtest + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.widthIn +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowDownward +import androidx.compose.material.icons.filled.ArrowUpward +import androidx.compose.material.icons.filled.ChevronRight +import androidx.compose.material.icons.filled.NetworkPing +import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material.icons.filled.Public +import androidx.compose.material.icons.filled.Refresh +import androidx.compose.material.icons.filled.Settings +import androidx.compose.material.icons.filled.Stop +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import org.librespeed.speedtest.R +import org.librespeed.speedtest.ui.components.SpeedGauge +import org.librespeed.speedtest.ui.components.Sparkline +import org.librespeed.speedtest.ui.theme.Purple +import org.librespeed.speedtest.ui.theme.Teal +import java.util.Locale + +@Composable +fun SpeedtestScreen( + viewModel: SpeedtestViewModel, + onServersClick: () -> Unit, + onSettingsClick: () -> Unit, + onResult: (Long) -> Unit +) { + val state by viewModel.state.collectAsStateWithLifecycle() + val resultId by viewModel.lastResultId.collectAsStateWithLifecycle() + val unitLabel = stringResource(if (state.useMBytes) R.string.unit_mbytes else R.string.unit_mbps) + fun display(value: Double): Double = if (state.useMBytes) value / 8 else value + + LaunchedEffect(resultId) { + resultId?.let { + viewModel.consumeResult() + onResult(it) + } + } + + Column( + modifier = Modifier.fillMaxSize().padding(horizontal = 20.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Box(modifier = Modifier.widthIn(max = 500.dp).fillMaxWidth()) { + Row( + modifier = Modifier.align(Alignment.Center), + verticalAlignment = Alignment.CenterVertically + ) { + Image( + painter = painterResource(R.drawable.ic_logo), + contentDescription = null, + modifier = Modifier.size(28.dp) + ) + Spacer(Modifier.width(8.dp)) + Text( + text = buildAnnotatedString { + withStyle(SpanStyle(color = MaterialTheme.colorScheme.primary)) { append("Libre") } + withStyle(SpanStyle(color = MaterialTheme.colorScheme.onBackground)) { append("Speed") } + }, + style = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.Bold + ) + } + IconButton( + onClick = onSettingsClick, + modifier = Modifier.align(Alignment.CenterEnd) + ) { + Icon( + Icons.Filled.Settings, + contentDescription = stringResource(R.string.nav_settings), + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + Spacer(Modifier.height(6.dp)) + ServerChip( + state = state, + onClick = { + if (state.serverListFailed) viewModel.refreshServers() else onServersClick() + } + ) + + Spacer(Modifier.weight(1f)) + SpeedGauge( + speed = state.currentSpeed, + modifier = Modifier.widthIn(max = 384.dp).fillMaxWidth() + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text( + text = if (state.phase == Phase.IDLE || state.phase == Phase.ERROR) "—" + else String.format(Locale.US, "%.2f", display(state.currentSpeed)), + style = MaterialTheme.typography.displaySmall, + fontWeight = FontWeight.Bold, + color = MaterialTheme.colorScheme.onBackground + ) + Text( + text = unitLabel, + style = MaterialTheme.typography.titleSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + Spacer(Modifier.height(4.dp)) + PhaseLabel(state) + } + } + + Spacer(Modifier.weight(1f)) + Row(modifier = Modifier.widthIn(max = 500.dp).fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) { + MetricCard( + modifier = Modifier.weight(1f), + title = stringResource(R.string.test_download), + icon = { Icon(Icons.Filled.ArrowDownward, null, tint = Teal, modifier = Modifier.size(16.dp)) }, + value = if (state.download < 0) state.download else display(state.download), + unit = unitLabel, + accent = Teal, + samples = state.downloadSamples + ) + MetricCard( + modifier = Modifier.weight(1f), + title = stringResource(R.string.test_upload), + icon = { Icon(Icons.Filled.ArrowUpward, null, tint = Purple, modifier = Modifier.size(16.dp)) }, + value = if (state.upload < 0) state.upload else display(state.upload), + unit = unitLabel, + accent = Purple, + samples = state.uploadSamples + ) + } + + Spacer(Modifier.height(10.dp)) + Row(modifier = Modifier.widthIn(max = 500.dp).fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) { + SmallMetric(Modifier.weight(1f), stringResource(R.string.test_ping), state.ping, stringResource(R.string.unit_ms)) + SmallMetric(Modifier.weight(1f), stringResource(R.string.test_jitter), state.jitter, stringResource(R.string.unit_ms)) + SmallMetric(Modifier.weight(1f), stringResource(R.string.test_loss), state.loss, "%") + } + + Spacer(Modifier.height(14.dp)) + val running = state.phase in setOf(Phase.PING, Phase.DOWNLOAD, Phase.UPLOAD) + OutlinedButton( + onClick = { viewModel.startOrStop() }, + enabled = state.selectedServer != null || state.phase != Phase.IDLE, + border = BorderStroke(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.6f)), + colors = ButtonDefaults.outlinedButtonColors(contentColor = MaterialTheme.colorScheme.primary), + modifier = Modifier.widthIn(max = 500.dp).fillMaxWidth().height(52.dp) + ) { + Icon( + imageVector = if (running) Icons.Filled.Stop else Icons.Filled.PlayArrow, + contentDescription = null, + modifier = Modifier.size(20.dp) + ) + Spacer(Modifier.width(8.dp)) + Text( + text = stringResource( + when { + running -> R.string.test_stop + state.phase == Phase.ERROR -> R.string.test_restart + else -> R.string.test_start + } + ), + style = MaterialTheme.typography.titleMedium + ) + } + + if (state.phase == Phase.ERROR) { + Spacer(Modifier.height(8.dp)) + Text( + text = state.error ?: stringResource(R.string.test_failed), + color = MaterialTheme.colorScheme.error, + style = MaterialTheme.typography.bodySmall, + textAlign = TextAlign.Center + ) + } + Spacer(Modifier.height(12.dp)) + } +} + +@Composable +private fun ServerChip(state: SpeedtestUiState, onClick: () -> Unit) { + Card( + onClick = onClick, + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), + modifier = Modifier.widthIn(max = 500.dp).fillMaxWidth() + ) { + Row( + modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + imageVector = Icons.Filled.Public, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(20.dp) + ) + Spacer(Modifier.width(12.dp)) + Column(Modifier.weight(1f)) { + when { + state.selectingServers -> Text( + text = stringResource(R.string.servers_selecting), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + state.serverListFailed -> Text( + text = stringResource(R.string.servers_load_failed), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.error + ) + state.selectedServer != null -> { + Text( + text = stringResource( + if (state.pinnedServer) R.string.server_selected else R.string.server_auto_select + ), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface + ) + Text( + text = state.selectedServer.name, + style = MaterialTheme.typography.labelSmall, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + else -> Text( + text = stringResource(R.string.servers_none), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.error + ) + } + } + if (state.selectingServers) { + CircularProgressIndicator(modifier = Modifier.size(18.dp), strokeWidth = 2.dp) + } else if (state.serverListFailed) { + Icon(Icons.Filled.Refresh, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant) + } else { + state.selectedServer?.takeIf { it.ping >= 0 }?.let { + Text( + text = "${it.ping.toInt()} ${stringResource(R.string.unit_ms)}", + style = MaterialTheme.typography.labelMedium, + color = MaterialTheme.colorScheme.primary + ) + } + Spacer(Modifier.width(6.dp)) + Icon( + Icons.Filled.ChevronRight, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + } +} + +@Composable +private fun PhaseLabel(state: SpeedtestUiState) { + val text = when (state.phase) { + Phase.PING -> stringResource(R.string.phase_ping) + Phase.DOWNLOAD -> stringResource(R.string.phase_download) + Phase.UPLOAD -> stringResource(R.string.phase_upload) + else -> "" + } + if (text.isNotEmpty()) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + when (state.phase) { + Phase.DOWNLOAD -> Icon(Icons.Filled.ArrowDownward, null, tint = Teal, modifier = Modifier.size(20.dp)) + Phase.UPLOAD -> Icon(Icons.Filled.ArrowUpward, null, tint = Purple, modifier = Modifier.size(20.dp)) + else -> Icon(Icons.Filled.NetworkPing, null, tint = MaterialTheme.colorScheme.primary, modifier = Modifier.size(20.dp)) + } + Spacer(Modifier.height(4.dp)) + Text( + text = text, + style = MaterialTheme.typography.labelMedium, + color = MaterialTheme.colorScheme.primary + ) + } + } +} + +@Composable +private fun MetricCard( + modifier: Modifier, + title: String, + icon: @Composable () -> Unit, + value: Double, + unit: String, + accent: Color, + samples: List +) { + Card( + modifier = modifier, + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface) + ) { + Column(Modifier.padding(12.dp)) { + Row(verticalAlignment = Alignment.CenterVertically) { + icon() + Spacer(Modifier.width(6.dp)) + Text( + text = title.uppercase(Locale.ROOT), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + Spacer(Modifier.height(4.dp)) + Text( + text = if (value < 0) "—" else String.format(Locale.US, "%.2f", value), + style = MaterialTheme.typography.headlineSmall, + fontWeight = FontWeight.SemiBold, + color = MaterialTheme.colorScheme.onSurface + ) + Text( + text = unit, + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + Sparkline( + data = samples, + color = accent, + modifier = Modifier.fillMaxWidth().height(30.dp).padding(top = 4.dp) + ) + } + } +} + +@Composable +private fun SmallMetric(modifier: Modifier, title: String, value: Double, unit: String) { + Card( + modifier = modifier, + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface) + ) { + Column(Modifier.padding(10.dp), horizontalAlignment = Alignment.CenterHorizontally) { + Text( + text = title, + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + Spacer(Modifier.height(2.dp)) + Row(verticalAlignment = Alignment.Bottom) { + Text( + text = if (value < 0) "—" else String.format(Locale.US, "%.1f", value), + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.SemiBold, + color = MaterialTheme.colorScheme.primary + ) + Spacer(Modifier.width(4.dp)) + Text( + text = unit, + modifier = Modifier.padding(bottom = 2.dp), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + } +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/speedtest/SpeedtestViewModel.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/speedtest/SpeedtestViewModel.kt new file mode 100644 index 0000000..9843498 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/speedtest/SpeedtestViewModel.kt @@ -0,0 +1,342 @@ +package org.librespeed.speedtest.ui.speedtest + +import android.Manifest +import android.app.Application +import android.content.Context +import android.content.pm.PackageManager +import android.location.Geocoder +import android.location.Location +import android.location.LocationManager +import androidx.core.content.ContextCompat +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.viewModelScope +import com.fdossena.speedtest.core.Speedtest +import com.fdossena.speedtest.core.serverSelector.ServerSelector +import com.fdossena.speedtest.core.serverSelector.TestPoint +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.librespeed.speedtest.data.AppPreferences +import org.librespeed.speedtest.data.CustomServerFactory +import org.librespeed.speedtest.data.GeoDistance +import org.librespeed.speedtest.data.HistoryDatabase +import org.librespeed.speedtest.data.HistoryEntry +import org.librespeed.speedtest.data.NetworkInfo +import org.librespeed.speedtest.data.key +import org.librespeed.speedtest.engine.TestEngine +import kotlin.math.roundToInt + +enum class Phase { IDLE, PING, DOWNLOAD, UPLOAD, ERROR } + +data class SpeedtestUiState( + val phase: Phase = Phase.IDLE, + val selectingServers: Boolean = false, + val serverListFailed: Boolean = false, + val servers: List = emptyList(), + val selectedServer: TestPoint? = null, + val pinnedServer: Boolean = false, + val currentSpeed: Double = 0.0, + val download: Double = -1.0, + val upload: Double = -1.0, + val ping: Double = -1.0, + val jitter: Double = -1.0, + val loss: Double = -1.0, + val downloadSamples: List = emptyList(), + val uploadSamples: List = emptyList(), + val ipInfo: String? = null, + val shareUrl: String? = null, + val error: String? = null, + val favorites: Set = emptySet(), + val customKeys: Set = emptySet(), + val useMBytes: Boolean = false, + val distances: Map = emptyMap() +) + +class SpeedtestViewModel(application: Application) : AndroidViewModel(application) { + + private val engine = TestEngine(application) + private val prefs = AppPreferences(application) + private val history = HistoryDatabase(application) + private val _state = MutableStateFlow(SpeedtestUiState()) + val state: StateFlow = _state + + /** Id of the freshly saved result; the UI navigates to it and calls [consumeResult]. */ + val lastResultId = MutableStateFlow(null) + + private var telemetryEnabled = false + private var singleConnection = false + private var autoSelected: TestPoint? = null + private var aborted = false + + init { + viewModelScope.launch { + prefs.favorites.collect { favorites -> _state.update { it.copy(favorites = favorites) } } + } + viewModelScope.launch { + prefs.useMBytes.collect { useMBytes -> _state.update { it.copy(useMBytes = useMBytes) } } + } + viewModelScope.launch { prefs.telemetryEnabled.collect { telemetryEnabled = it } } + viewModelScope.launch { prefs.singleConnection.collect { singleConnection = it } } + refreshServers() + } + + fun consumeResult() { + lastResultId.value = null + } + + fun refreshServers() { + if (_state.value.selectingServers) return + _state.update { it.copy(selectingServers = true, serverListFailed = false) } + viewModelScope.launch { + try { + val custom = prefs.customServers.first() + val discovery = engine.discover(custom) + autoSelected = discovery.selected + val remembered = prefs.rememberedServer.first() + ?.let { key -> discovery.servers.find { it.key() == key && it.ping >= 0 } } + _state.update { + it.copy( + selectingServers = false, + servers = discovery.servers, + selectedServer = remembered ?: discovery.selected, + pinnedServer = remembered != null, + customKeys = custom.map { c -> c.key() }.toSet(), + serverListFailed = discovery.selected == null && discovery.servers.isEmpty() + ) + } + } catch (_: Exception) { + _state.update { it.copy(selectingServers = false, serverListFailed = true) } + } + computeDistances() + } + } + + /** Fills in distances to servers when coarse location is granted; results stay on the device. */ + fun computeDistances() { + viewModelScope.launch(Dispatchers.IO) { + val app = getApplication() + if (ContextCompat.checkSelfPermission(app, Manifest.permission.ACCESS_COARSE_LOCATION) + != PackageManager.PERMISSION_GRANTED + ) return@launch + val location = lastKnownLocation(app) ?: return@launch + if (!Geocoder.isPresent()) return@launch + val geocoder = Geocoder(app) + val cache = prefs.getGeoCache().toMutableMap() + for (server in _state.value.servers) { + val place = GeoDistance.cleanName(server.name) + val coordinates = cache[place] ?: try { + @Suppress("DEPRECATION") + geocoder.getFromLocationName(place, 1)?.firstOrNull() + ?.let { it.latitude to it.longitude } + ?.also { + cache[place] = it + prefs.putGeoCache(place, it.first, it.second) + } + } catch (_: Exception) { + null + } ?: continue + val km = GeoDistance.km(location.latitude, location.longitude, coordinates.first, coordinates.second) + _state.update { + it.copy(distances = it.distances + (server.key() to km.roundToInt())) + } + } + } + } + + //only called after computeDistances verified ACCESS_COARSE_LOCATION + @android.annotation.SuppressLint("MissingPermission") + private fun lastKnownLocation(app: Application): Location? = try { + val manager = app.getSystemService(Context.LOCATION_SERVICE) as LocationManager + manager.getProviders(true) + .mapNotNull { provider -> runCatching { manager.getLastKnownLocation(provider) }.getOrNull() } + .maxByOrNull { it.time } + } catch (_: Exception) { + null + } + + fun selectServer(testPoint: TestPoint) { + if (isRunning()) return + _state.update { it.copy(selectedServer = testPoint, pinnedServer = true) } + viewModelScope.launch { prefs.setRememberedServer(testPoint.key()) } + } + + /** Returns to automatic server selection. */ + fun useAutoSelect() { + if (isRunning()) return + _state.update { it.copy(selectedServer = autoSelected ?: it.selectedServer, pinnedServer = false) } + viewModelScope.launch { prefs.setRememberedServer(null) } + } + + fun toggleFavorite(testPoint: TestPoint) { + viewModelScope.launch { prefs.toggleFavorite(testPoint.key()) } + } + + /** Re-pings a single server and refreshes the list when done. */ + fun pingServer(testPoint: TestPoint) { + viewModelScope.launch(Dispatchers.IO) { + try { + object : ServerSelector(arrayOf(testPoint), 2000) { + override fun onServerSelected(server: TestPoint?) { + _state.update { it.copy(servers = it.servers.toList()) } + } + }.start() + } catch (_: Exception) { + } + } + } + + /** Returns false when the URL is invalid. */ + fun addCustomServer(name: String, url: String): Boolean { + val testPoint = try { + CustomServerFactory.create(name, url) + } catch (_: Exception) { + return false + } + viewModelScope.launch { + prefs.addCustomServer(testPoint) + refreshServers() + } + return true + } + + fun removeCustomServer(testPoint: TestPoint) { + viewModelScope.launch { + prefs.removeCustomServer(testPoint.key()) + refreshServers() + } + } + + fun startOrStop() { + if (isRunning()) stop() else start() + } + + private fun isRunning(): Boolean = _state.value.phase in setOf(Phase.PING, Phase.DOWNLOAD, Phase.UPLOAD) + + private fun start() { + val current = _state.value + val server = current.selectedServer ?: return + aborted = false + val networkType = NetworkInfo.describe(getApplication()) + val startedAt = System.currentTimeMillis() + _state.update { + it.copy( + phase = Phase.PING, + currentSpeed = 0.0, + download = -1.0, upload = -1.0, ping = -1.0, jitter = -1.0, loss = -1.0, + downloadSamples = emptyList(), uploadSamples = emptyList(), + ipInfo = null, shareUrl = null, error = null + ) + } + engine.prepare(current.servers, server, telemetryEnabled, singleConnection) + engine.start(object : Speedtest.SpeedtestHandler() { + override fun onDownloadUpdate(dl: Double, progress: Double) { + _state.update { + it.copy( + phase = Phase.DOWNLOAD, + currentSpeed = dl, + download = dl, + downloadSamples = if (progress > 0) it.downloadSamples + dl else it.downloadSamples + ) + } + } + + override fun onUploadUpdate(ul: Double, progress: Double) { + _state.update { + it.copy( + phase = Phase.UPLOAD, + currentSpeed = ul, + upload = ul, + uploadSamples = if (progress > 0) it.uploadSamples + ul else it.uploadSamples + ) + } + } + + override fun onPingJitterUpdate(ping: Double, jitter: Double, progress: Double) { + _state.update { it.copy(phase = Phase.PING, ping = ping, jitter = jitter) } + } + + override fun onLossUpdate(loss: Double) { + _state.update { it.copy(loss = loss) } + } + + override fun onIPInfoUpdate(ipInfo: String?) { + _state.update { it.copy(ipInfo = ipInfo) } + } + + override fun onTestIDReceived(id: String?, shareURL: String?) { + _state.update { it.copy(shareUrl = shareURL) } + } + + override fun onEnd() { + val finished = _state.value + if (aborted || finished.download < 0) { + resetToIdle() + return + } + viewModelScope.launch { + val entryId = withContext(Dispatchers.IO) { + history.insert( + HistoryEntry( + date = System.currentTimeMillis(), + server = server.name, + ping = finished.ping, + jitter = finished.jitter, + download = finished.download, + upload = finished.upload, + loss = finished.loss, + ipInfo = finished.ipInfo, + ipVersion = server.ipVersion, + shareUrl = finished.shareUrl, + networkType = networkType, + downloadSamples = finished.downloadSamples, + uploadSamples = finished.uploadSamples, + durationMs = System.currentTimeMillis() - startedAt + ) + ) + } + resetToIdle() + lastResultId.value = entryId + } + } + + override fun onCriticalFailure(err: String?) { + _state.update { it.copy(phase = Phase.ERROR, error = err, currentSpeed = 0.0) } + } + }) + } + + private fun resetToIdle() { + _state.update { + it.copy( + phase = Phase.IDLE, + currentSpeed = 0.0, + download = -1.0, upload = -1.0, ping = -1.0, jitter = -1.0, loss = -1.0, + downloadSamples = emptyList(), uploadSamples = emptyList(), + ipInfo = null, shareUrl = null, error = null + ) + } + } + + /** Selects the server with the given name (without pinning it) and starts a test. */ + fun testAgain(serverName: String) { + if (isRunning()) return + _state.value.servers.find { it.name == serverName }?.let { server -> + _state.update { it.copy(selectedServer = server) } + } + startOrStop() + } + + private fun stop() { + aborted = true + engine.abort() + } + + override fun onCleared() { + engine.abort() + } + +} diff --git a/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/theme/Theme.kt b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/theme/Theme.kt new file mode 100644 index 0000000..14c06d0 --- /dev/null +++ b/Speedtest-Android/app/src/main/java/org/librespeed/speedtest/ui/theme/Theme.kt @@ -0,0 +1,78 @@ +package org.librespeed.speedtest.ui.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +val Teal = Color(0xFF2DD4BF) +val TealDeep = Color(0xFF14B8A6) +val Purple = Color(0xFFA78BFA) +val NightBackground = Color(0xFF0C111C) +val NightSurface = Color(0xFF151C2C) +val NightSurfaceHigh = Color(0xFF1D2537) +val DayBackground = Color(0xFFF6F8FB) +val DaySurface = Color(0xFFFFFFFF) +val DangerRed = Color(0xFFEF6461) + +private val DarkColors = darkColorScheme( + primary = Teal, + onPrimary = Color(0xFF00201C), + primaryContainer = Color(0xFF0F3B36), + onPrimaryContainer = Teal, + secondary = Purple, + onSecondary = Color(0xFF1F1147), + secondaryContainer = Color(0xFF2E2258), + onSecondaryContainer = Purple, + background = NightBackground, + onBackground = Color(0xFFE4E9F2), + surface = NightSurface, + onSurface = Color(0xFFE4E9F2), + surfaceVariant = NightSurfaceHigh, + onSurfaceVariant = Color(0xFF9AA4B8), + surfaceContainer = NightSurface, + surfaceContainerHigh = NightSurfaceHigh, + error = DangerRed, + outline = Color(0xFF3A445A) +) + +private val LightColors = lightColorScheme( + primary = TealDeep, + onPrimary = Color.White, + primaryContainer = Color(0xFFC8F5EE), + onPrimaryContainer = Color(0xFF00332E), + secondary = Color(0xFF7C5CD6), + onSecondary = Color.White, + secondaryContainer = Color(0xFFE8E0FB), + onSecondaryContainer = Color(0xFF2A1A5E), + background = DayBackground, + onBackground = Color(0xFF1A1F2B), + surface = DaySurface, + onSurface = Color(0xFF1A1F2B), + surfaceVariant = Color(0xFFEDF1F7), + onSurfaceVariant = Color(0xFF5A6478), + surfaceContainer = DaySurface, + surfaceContainerHigh = Color(0xFFF0F3F8), + error = Color(0xFFC0342F), + outline = Color(0xFFC3CAD8) +) + +enum class ThemeMode { SYSTEM, LIGHT, DARK } + +@Composable +fun LibreSpeedTheme( + mode: ThemeMode = ThemeMode.SYSTEM, + content: @Composable () -> Unit +) { + val dark = when (mode) { + ThemeMode.SYSTEM -> isSystemInDarkTheme() + ThemeMode.LIGHT -> false + ThemeMode.DARK -> true + } + MaterialTheme( + colorScheme = if (dark) DarkColors else LightColors, + content = content + ) +} diff --git a/Speedtest-Android/app/src/main/res/drawable/ic_launcher.png b/Speedtest-Android/app/src/main/res/drawable/ic_launcher.png deleted file mode 100644 index 02542975f4c621329ae61fb70f52dc07f4579f61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20326 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 QXn6wN(l)w*)3OWuH$8?M + + + + + + + + + + + + + + + + + diff --git a/Speedtest-Android/app/src/main/res/drawable/ic_logo.xml b/Speedtest-Android/app/src/main/res/drawable/ic_logo.xml new file mode 100644 index 0000000..fed6d7d --- /dev/null +++ b/Speedtest-Android/app/src/main/res/drawable/ic_logo.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + diff --git a/Speedtest-Android/app/src/main/res/drawable/logo.png b/Speedtest-Android/app/src/main/res/drawable/logo.png deleted file mode 100644 index eccac8fb2c1d8c07f6fabe2c7ca9cac181fe5fb2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37296 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%0ABbam;3Y^R7zJ$cI3*4B9~Y25|6xp!$R)kR$> z(K0l=o`+Fh>N8^Cx=gtZ_Q#4Jc8ZwcVIid`JFS%qMJ|aCL%*yJnvg!qAGhfOL^#FF zM=gFRWlgW5e;&^d4~LqN=EZO1R^;Lvv$CXQ^WR@6$Hv88nRr8{TLlZjV+9D9EM{tUR{jq5#M>~z|(3#3~V#4jM|4Ty9qt11nZ(v{Y0 zYmdW0iN6VG&cZ6Is_ecWi( zvWtg9pl(36Q+j1(WnuEDX}75k2J@)1lx_(~$pwCGe$e-XII^d4u6Cc7@BG3m&%dkt zSC>v`5D=Pwiy5WnTzE4>kV&u$+kf}qfWO=}FJkSjArq%}k{J@Qc#6O~f%^(64hNJpO$V&wI zf9x-l1eR7XWkuB%R+m0^yZtpZdhF^|eW!m@XnsP2z4cYi$PmKF9SnV`^-mqCz)Q-N+@t!1uydM7=YtyN;$9 zP%VwY6EP(C=3KkyTce-d-$M|%2=EVzW<$+06r}+VU&sXrI_;)LZcVp~;f9=Ogatb5 z367HnI4{)fp14YORfeLoJ;+b74`{Uf^S$}Z&q*1RII)=Ja{&fO!hbUs)h&lXLC&&` zA_=$EWeRW77dTG^APawRoqu`NK*KF7H%KWJ)cmXR2A3@BJ={^urQ4s#Gu zBTRi88dm5M+BaG9N59FJb9n%n?_&u0hL)9ir;*F8S7z8p^71r`dJCe?W`|Ela}`zJmU`x7hG`Y1X^6 zs`P`tUo(zRTyjXVr`wPt7FpAkF;<- z{im1|7|2FyzqU!Au>#ZO^Qsj$6r8sQrc5+Sy=cqIB->m4y7WNR#r;3TksnP^?`#^T3%kRYo=3z)zojgidI&h z1`IqatE*x1^*1lk1h=PSWSh~5&Fokfh^v|E2}CUz3@B9l^+`n;2Aunc;fy=p zMAd3ZZ%OF|Cfovb+3U+tgRQbbU2CiT%F3&}oSdQ_Un612(6F;>CZCuMejEPgjiu~^ z_an5lIu(msAI%Rkn^j)x5 z?%Y!#NW;&h5Ox#2gJeGQdXRo~hTEK&b~DocaPAleV&epO*aaiP2KsNZHOIg>U#*~y zGDj2_!6u@jIdKtdBG6f9?cK@whk>$(rwk97^cyhT3?$8sZI6tIf8+~^Ch#u2h_g(f zbp+l=swfkMC4l6QOp`e`+l-8Ix6uvG3Zlkabq<26V#Y-B(vX69mre?jWng5k< z9LK-w9zm^~&IfH{#|voRu}XfkIsBAuhXV@8K4rri_MOyz_v? zUm>iWJTbh(1G)$cK~nCEsu;AO%^XXD>7e zXS#x1S0LB0iGApz?Bu95TIhn#lj)ZrGx(xd%{8D6 z6{n)KS;mNc%=H-7AiudHgyH)pvP;4IC=?l!BzsTNT#B+25`;~_?qzbbgXrdNBsSjS zH1UU+K{~&qFl_AVUDKl|oRcPt=4I<~r&0Ehv g@5K!yV&MjyF4&w|^g|;9sAfXemUf48E!-pj4`Q85RsaA1 diff --git a/Speedtest-Android/app/src/main/res/drawable/logo_inapp.png b/Speedtest-Android/app/src/main/res/drawable/logo_inapp.png deleted file mode 100644 index 14ea78c635c88c1635d27c9f66cf9e72aec9c8ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37343 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 diff --git a/Speedtest-Android/app/src/main/res/drawable/testbackground.png b/Speedtest-Android/app/src/main/res/drawable/testbackground.png deleted file mode 100644 index f19c990e6eea15b86e3c690fdc3d5f4fb8b7e0e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 278762 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%0Am7^*4gV@#ClDh}cARui^0)E9GgdR*1oZxJnf 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 diff --git a/Speedtest-Android/app/src/main/res/layout/activity_main.xml b/Speedtest-Android/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index ad35b91..0000000 --- a/Speedtest-Android/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,536 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -