Loading screen

This commit is contained in:
koalasat
2025-07-16 13:19:19 +02:00
parent bdd1a9b624
commit e3e339c788
2 changed files with 87 additions and 49 deletions

View File

@ -5,9 +5,12 @@ import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View
import android.webkit.* import android.webkit.*
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import com.robosats.R import com.robosats.R
import com.robosats.tor.TorKmp import com.robosats.tor.TorKmp
import com.robosats.tor.TorKmpManager import com.robosats.tor.TorKmpManager
@ -20,6 +23,8 @@ import java.net.URL
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private lateinit var webView: WebView private lateinit var webView: WebView
private lateinit var torKmp: TorKmp private lateinit var torKmp: TorKmp
private lateinit var loadingContainer: ConstraintLayout
private lateinit var statusTextView: TextView
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -27,8 +32,13 @@ class MainActivity : AppCompatActivity() {
// We don't need edge-to-edge since we're using fitsSystemWindows // We don't need edge-to-edge since we're using fitsSystemWindows
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
// Set up the WebView reference // Set up the UI references
webView = findViewById(R.id.webView) webView = findViewById(R.id.webView)
loadingContainer = findViewById(R.id.loadingContainer)
statusTextView = findViewById(R.id.statusTextView)
// Set initial status message
updateStatus("Initializing Tor connection...")
// Initialize Tor and setup WebView only after Tor is properly connected // Initialize Tor and setup WebView only after Tor is properly connected
initializeTor() initializeTor()
@ -54,17 +64,20 @@ class MainActivity : AppCompatActivity() {
// Log the error and show a critical error message // Log the error and show a critical error message
Log.e("TorInitialization", "Failed to initialize Tor: ${e.message}", e) Log.e("TorInitialization", "Failed to initialize Tor: ${e.message}", e)
// Show a toast notification about the critical error // Show error message on the loading screen
runOnUiThread { runOnUiThread {
Toast.makeText( updateStatus("Critical error: Tor initialization failed. App cannot proceed securely.")
this,
"Critical error: Tor initialization failed. App cannot proceed securely.",
Toast.LENGTH_LONG
).show()
} }
} }
} }
/**
* Updates the status message on the loading screen
*/
private fun updateStatus(message: String) {
statusTextView.text = message
}
private fun waitForTorConnection() { private fun waitForTorConnection() {
var retries = 0 var retries = 0
val maxRetries = 15 val maxRetries = 15
@ -72,11 +85,7 @@ class MainActivity : AppCompatActivity() {
try { try {
// Display connecting message // Display connecting message
runOnUiThread { runOnUiThread {
Toast.makeText( updateStatus("Connecting to Tor network...")
this,
"Connecting to Tor network...",
Toast.LENGTH_SHORT
).show()
} }
// Wait for Tor to connect with retry mechanism // Wait for Tor to connect with retry mechanism
@ -90,11 +99,7 @@ class MainActivity : AppCompatActivity() {
// Update status on UI thread every few retries // Update status on UI thread every few retries
if (retries % 3 == 0) { if (retries % 3 == 0) {
runOnUiThread { runOnUiThread {
Toast.makeText( updateStatus("Still connecting to Tor (attempt $retries/$maxRetries)...")
this,
"Still connecting to Tor (attempt $retries/$maxRetries)...",
Toast.LENGTH_SHORT
).show()
} }
} }
} }
@ -103,13 +108,9 @@ class MainActivity : AppCompatActivity() {
if (torKmp.isConnected()) { if (torKmp.isConnected()) {
Log.d("TorInitialization", "Tor connected successfully after $retries retries") Log.d("TorInitialization", "Tor connected successfully after $retries retries")
// Show success message // Show success message and proceed
runOnUiThread { runOnUiThread {
Toast.makeText( updateStatus("Tor connected successfully. Setting up secure browser...")
this,
"Tor connected successfully",
Toast.LENGTH_SHORT
).show()
// Now that Tor is connected, set up the WebView // Now that Tor is connected, set up the WebView
setupWebView() setupWebView()
@ -119,22 +120,14 @@ class MainActivity : AppCompatActivity() {
Log.e("TorInitialization", "Failed to connect to Tor after $maxRetries retries") Log.e("TorInitialization", "Failed to connect to Tor after $maxRetries retries")
runOnUiThread { runOnUiThread {
Toast.makeText( updateStatus("Failed to connect to Tor after multiple attempts. App cannot proceed securely.")
this,
"Failed to connect to Tor after multiple attempts. App cannot proceed securely.",
Toast.LENGTH_LONG
).show()
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("TorInitialization", "Error during Tor connection: ${e.message}", e) Log.e("TorInitialization", "Error during Tor connection: ${e.message}", e)
runOnUiThread { runOnUiThread {
Toast.makeText( updateStatus("Error connecting to Tor: ${e.message}")
this,
"Error connecting to Tor: ${e.message}",
Toast.LENGTH_LONG
).show()
} }
} }
} }
@ -196,11 +189,7 @@ class MainActivity : AppCompatActivity() {
// Show message that we're setting up secure browsing // Show message that we're setting up secure browsing
runOnUiThread { runOnUiThread {
Toast.makeText( updateStatus("Setting up secure Tor browsing...")
this,
"Setting up secure Tor browsing...",
Toast.LENGTH_SHORT
).show()
} }
// Configure proxy for WebView in a background thread to avoid NetworkOnMainThreadException // Configure proxy for WebView in a background thread to avoid NetworkOnMainThreadException
@ -231,11 +220,7 @@ class MainActivity : AppCompatActivity() {
// Success - now configure WebViewClient and load URL on UI thread // Success - now configure WebViewClient and load URL on UI thread
runOnUiThread { runOnUiThread {
Toast.makeText( updateStatus("Secure connection established. Loading app...")
this,
"Secure connection established",
Toast.LENGTH_SHORT
).show()
// Create a custom WebViewClient that forces all traffic through Tor // Create a custom WebViewClient that forces all traffic through Tor
webView.webViewClient = object : WebViewClient() { webView.webViewClient = object : WebViewClient() {
@ -406,6 +391,10 @@ class MainActivity : AppCompatActivity() {
// Add the JavaScript interface // Add the JavaScript interface
webView.addJavascriptInterface(WebAppInterface(this, webView), "AndroidAppRobosats") webView.addJavascriptInterface(WebAppInterface(this, webView), "AndroidAppRobosats")
// Show WebView and hide loading screen
loadingContainer.visibility = View.GONE
webView.visibility = View.VISIBLE
// Now it's safe to load the local HTML file // Now it's safe to load the local HTML file
webView.loadUrl("file:///android_asset/index.html") webView.loadUrl("file:///android_asset/index.html")
} }
@ -414,12 +403,8 @@ class MainActivity : AppCompatActivity() {
// Show error and exit - DO NOT LOAD WEBVIEW // Show error and exit - DO NOT LOAD WEBVIEW
runOnUiThread { runOnUiThread {
// Show toast with error // Show error on loading screen
Toast.makeText( updateStatus("SECURITY ERROR: Cannot set up secure browsing: ${e.message}")
this,
"SECURITY ERROR: Cannot set up secure browsing: ${e.message}",
Toast.LENGTH_LONG
).show()
} }
} }
}.start() }.start()

View File

@ -13,9 +13,62 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/loadingContainer"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#000000"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/appLogo"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_marginBottom="32dp"
android:contentDescription="@string/app_name"
android:src="@mipmap/ic_launcher"
app:layout_constraintBottom_toTopOf="@+id/loadingProgressBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<ProgressBar
android:id="@+id/loadingProgressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
app:layout_constraintBottom_toTopOf="@+id/statusTextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appLogo" />
<TextView
android:id="@+id/statusTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:gravity="center"
android:text="Initializing..."
android:textColor="#FFFFFF"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loadingProgressBar" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>