diff --git a/evershelf-kiosk/app/build.gradle.kts b/evershelf-kiosk/app/build.gradle.kts index ea19834..0f0f747 100644 --- a/evershelf-kiosk/app/build.gradle.kts +++ b/evershelf-kiosk/app/build.gradle.kts @@ -11,8 +11,8 @@ android { applicationId = "it.dadaloop.evershelf.kiosk" minSdk = 24 targetSdk = 34 - versionCode = 8 - versionName = "1.5.2" + versionCode = 9 + versionName = "1.5.3" } signingConfigs { diff --git a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/KioskActivity.kt b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/KioskActivity.kt index 079a7a6..057d167 100644 --- a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/KioskActivity.kt +++ b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/KioskActivity.kt @@ -312,6 +312,10 @@ class KioskActivity : AppCompatActivity() { @SuppressLint("SetJavaScriptEnabled") private fun launchWebView() { + // Start gateway BEFORE entering kiosk lock — in lock task mode Android blocks + // startActivity() for other packages, so the gateway would never launch. + launchGatewayInBackground() + // Ensure kiosk lock and permissions are active enableKioskLock() requestAllPermissions() @@ -432,9 +436,9 @@ class KioskActivity : AppCompatActivity() { }, "_kioskBridge") val url = prefs.getString(KEY_URL, "http://evershelf.local") ?: "http://evershelf.local" + webView.clearCache(true) webView.loadUrl(url) - launchGatewayInBackground() applyScreensaverFlag() } @@ -513,6 +517,19 @@ class KioskActivity : AppCompatActivity() { val norm = { v: String -> v.trimStart('v') } val isSemver = latestTag.trimStart('v').matches(Regex("\\d+\\.\\d+.*")) + // Compare semver: returns true if `remote` is strictly greater than `local` + fun semverNewer(remote: String, local: String): Boolean { + val r = remote.split(".").map { it.filter(Char::isDigit).toIntOrNull() ?: 0 } + val l = local.split(".").map { it.filter(Char::isDigit).toIntOrNull() ?: 0 } + val len = maxOf(r.size, l.size) + for (i in 0 until len) { + val rv = r.getOrElse(i) { 0 } + val lv = l.getOrElse(i) { 0 } + if (rv != lv) return rv > lv + } + return false + } + val assets = json.optJSONArray("assets") var kioskApkUrl = "" var gatewayApkUrl = "" @@ -527,9 +544,9 @@ class KioskActivity : AppCompatActivity() { } val kioskNeedsUpdate = kioskApkUrl.isNotEmpty() && currentKiosk.isNotEmpty() && - (!isSemver || norm(latestTag) != norm(currentKiosk)) + (!isSemver || semverNewer(norm(latestTag), norm(currentKiosk))) val gatewayNeedsUpdate = currentGateway != null && gatewayApkUrl.isNotEmpty() && - (!isSemver || norm(latestTag) != norm(currentGateway)) + (!isSemver || semverNewer(norm(latestTag), norm(currentGateway))) if (!kioskNeedsUpdate && !gatewayNeedsUpdate) return@Thread @@ -555,7 +572,9 @@ class KioskActivity : AppCompatActivity() { pendingApkDownloadUrl = apkDownloadUrl tvUpdateMessage.text = "⬆️ Aggiornamento disponibile: $message" updateBanner.visibility = View.VISIBLE - updateBanner.postDelayed({ updateBanner.visibility = View.GONE }, 30_000) + // Auto-start download immediately — no timer hide, stays until done or dismissed + activeInstallBtn = btnInstallUpdate + triggerApkDownload(apkDownloadUrl) } // ── APK Download + Install ───────────────────────────────────────────── diff --git a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SettingsActivity.kt b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SettingsActivity.kt index a53e5ff..4d539a6 100644 --- a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SettingsActivity.kt +++ b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SettingsActivity.kt @@ -77,6 +77,25 @@ class SettingsActivity : AppCompatActivity() { val intent = packageManager.getLaunchIntentForPackage(GATEWAY_PACKAGE) if (intent != null) startActivity(intent) } + // Probe WebSocket port in background to show live status + Thread { + val running = try { + java.net.Socket().use { s -> + s.connect(java.net.InetSocketAddress("127.0.0.1", 8765), 1200); true + } + } catch (_: Exception) { false } + runOnUiThread { + if (running) { + statusView.text = "Attivo ✅" + statusView.setTextColor(0xFF34d399.toInt()) + deviceView.text = "Gateway in ascolto su ws://127.0.0.1:8765" + } else { + statusView.text = "Installato, non avviato ⚠️" + statusView.setTextColor(0xFFfbbf24.toInt()) + deviceView.text = "Premi \"Apri Gateway\" per avviarlo e configurarlo" + } + } + }.start() } else { btnConfigureGateway.visibility = android.view.View.GONE } diff --git a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SetupActivity.kt b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SetupActivity.kt index 02f07ef..8e0825a 100644 --- a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SetupActivity.kt +++ b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SetupActivity.kt @@ -189,6 +189,14 @@ class SetupActivity : AppCompatActivity() { super.onDestroy() } + override fun onResume() { + super.onResume() + // When returning from the gateway app (after pressing "Configura"), refresh status + if (currentStep == 4 && gatewayInstallCard.visibility == View.VISIBLE) { + checkGatewayStatus() + } + } + // ── Binding ──────────────────────────────────────────────────────────── private fun bindViews() { @@ -701,12 +709,34 @@ class SetupActivity : AppCompatActivity() { if (isGatewayInstalled()) { gatewayStatusIcon.text = "✅" gatewayStatusText.text = getString(R.string.wizard_gateway_installed) - gatewayStatusDetail.text = getString(R.string.wizard_gateway_installed_detail) - gatewayStatusDetail.setTextColor(0xFF34d399.toInt()) + gatewayStatusDetail.text = "⏳ Verifica connessione in corso..." + gatewayStatusDetail.setTextColor(0xFF94a3b8.toInt()) btnInstallGateway.visibility = View.GONE btnConfigureGateway.visibility = View.VISIBLE gatewayProgressBar.visibility = View.GONE gatewayProgressText.visibility = View.GONE + // Probe WebSocket port to tell user if gateway is actually running + Thread { + val running = try { + java.net.Socket().use { s -> + s.connect(java.net.InetSocketAddress("127.0.0.1", 8765), 1200) + true + } + } catch (_: Exception) { false } + runOnUiThread { + if (running) { + gatewayStatusDetail.text = "✅ Gateway attivo su ws://127.0.0.1:8765" + gatewayStatusDetail.setTextColor(0xFF34d399.toInt()) + btnConfigureGateway.text = "⚙️ Riapri Gateway per configurarlo" + } else { + gatewayStatusDetail.text = + "⚠️ Gateway installato ma non ancora avviato.\n" + + "Premi il pulsante qui sotto per aprirlo e configurarlo, poi torna a questa schermata." + gatewayStatusDetail.setTextColor(0xFFfbbf24.toInt()) + btnConfigureGateway.text = "▶️ Apri e configura Gateway" + } + } + }.start() } else { gatewayStatusIcon.text = "📲" gatewayStatusText.text = getString(R.string.wizard_gateway_not_installed)