feat: Wire up analytics hooks in MainActivity and AdminActivity
CI / build (push) Has been cancelled
CI / lint (push) Has been cancelled

- Log session_start on app launch
- Log page_view on every page load
- Log idle_reset when idle timer fires
- Log session_end on app close
- Log admin_access (success/fail) on PIN verification
This commit is contained in:
2026-02-03 20:55:11 +00:00
parent 768c0d6e44
commit 76531d33b0
2 changed files with 22 additions and 0 deletions
@@ -6,6 +6,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey
import farm.hobbs.kioskbrowser.analytics.AnalyticsManager
import farm.hobbs.kioskbrowser.databinding.ActivityAdminBinding import farm.hobbs.kioskbrowser.databinding.ActivityAdminBinding
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@@ -15,11 +16,14 @@ import android.widget.EditText
class AdminActivity : AppCompatActivity() { class AdminActivity : AppCompatActivity() {
private lateinit var binding: ActivityAdminBinding private lateinit var binding: ActivityAdminBinding
private lateinit var analytics: AnalyticsManager
private val adminPin = "1234" // Default PIN - should be configurable private val adminPin = "1234" // Default PIN - should be configurable
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
analytics = AnalyticsManager.getInstance(this)
// Require PIN before showing settings // Require PIN before showing settings
showPinDialog() showPinDialog()
} }
@@ -36,8 +40,10 @@ class AdminActivity : AppCompatActivity() {
.setView(input) .setView(input)
.setPositiveButton("OK") { _, _ -> .setPositiveButton("OK") { _, _ ->
if (verifyPin(input.text.toString())) { if (verifyPin(input.text.toString())) {
analytics.logAdminAccess(success = true)
setupUI() setupUI()
} else { } else {
analytics.logAdminAccess(success = false)
Toast.makeText(this, "Invalid PIN", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Invalid PIN", Toast.LENGTH_SHORT).show()
finish() finish()
} }
@@ -23,6 +23,7 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore import androidx.datastore.preferences.preferencesDataStore
import farm.hobbs.kioskbrowser.analytics.AnalyticsManager
import farm.hobbs.kioskbrowser.databinding.ActivityMainBinding import farm.hobbs.kioskbrowser.databinding.ActivityMainBinding
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@@ -33,13 +34,16 @@ class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
private lateinit var webView: WebView private lateinit var webView: WebView
private lateinit var analytics: AnalyticsManager
private val idleHandler = Handler(Looper.getMainLooper()) private val idleHandler = Handler(Looper.getMainLooper())
private var idleTimeoutMs = 300_000L // 5 minutes default private var idleTimeoutMs = 300_000L // 5 minutes default
private var homepage = "https://hobbs.farm" private var homepage = "https://hobbs.farm"
private var whitelist = listOf("hobbs.farm") private var whitelist = listOf("hobbs.farm")
private var sessionStartTime = 0L
private val idleRunnable = Runnable { private val idleRunnable = Runnable {
analytics.logIdleReset()
loadHomepage() loadHomepage()
clearSession() clearSession()
} }
@@ -50,6 +54,11 @@ class MainActivity : AppCompatActivity() {
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
// Initialize analytics
analytics = AnalyticsManager.getInstance(this)
sessionStartTime = System.currentTimeMillis()
analytics.logSessionStart()
setupFullscreen() setupFullscreen()
loadSettings() loadSettings()
setupWebView() setupWebView()
@@ -121,6 +130,7 @@ class MainActivity : AppCompatActivity() {
override fun onPageFinished(view: WebView?, url: String?) { override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url) super.onPageFinished(view, url)
resetIdleTimer() resetIdleTimer()
url?.let { analytics.logPageView(it) }
} }
} }
@@ -183,6 +193,12 @@ class MainActivity : AppCompatActivity() {
idleHandler.removeCallbacks(idleRunnable) idleHandler.removeCallbacks(idleRunnable)
} }
override fun onDestroy() {
super.onDestroy()
val durationMs = System.currentTimeMillis() - sessionStartTime
analytics.logSessionEnd("app_close", durationMs)
}
// Secret admin gesture: triple-tap top-left corner to open settings // Secret admin gesture: triple-tap top-left corner to open settings
private var tapCount = 0 private var tapCount = 0
private val tapHandler = Handler(Looper.getMainLooper()) private val tapHandler = Handler(Looper.getMainLooper())